123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242 |
- //===-- BitcodeWriter.h - ClangDoc Bitcode Writer --------------*- C++ -*-===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- //
- // This file implements a writer for serializing the clang-doc internal
- // representation to LLVM bitcode. The writer takes in a stream and emits the
- // generated bitcode to that stream.
- //
- //===----------------------------------------------------------------------===//
- #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_DOC_BITCODEWRITER_H
- #define LLVM_CLANG_TOOLS_EXTRA_CLANG_DOC_BITCODEWRITER_H
- #include "Representation.h"
- #include "clang/AST/AST.h"
- #include "llvm/ADT/DenseMap.h"
- #include "llvm/ADT/SmallVector.h"
- #include "llvm/ADT/StringRef.h"
- #include "llvm/Bitstream/BitstreamWriter.h"
- #include <initializer_list>
- #include <vector>
- namespace clang {
- namespace doc {
- // Current version number of clang-doc bitcode.
- // Should be bumped when removing or changing BlockIds, RecordIds, or
- // BitCodeConstants, though they can be added without breaking it.
- static const unsigned VersionNumber = 3;
- struct BitCodeConstants {
- static constexpr unsigned RecordSize = 32U;
- static constexpr unsigned SignatureBitSize = 8U;
- static constexpr unsigned SubblockIDSize = 4U;
- static constexpr unsigned BoolSize = 1U;
- static constexpr unsigned IntSize = 16U;
- static constexpr unsigned StringLengthSize = 16U;
- static constexpr unsigned FilenameLengthSize = 16U;
- static constexpr unsigned LineNumberSize = 32U;
- static constexpr unsigned ReferenceTypeSize = 8U;
- static constexpr unsigned USRLengthSize = 6U;
- static constexpr unsigned USRBitLengthSize = 8U;
- static constexpr unsigned char Signature[4] = {'D', 'O', 'C', 'S'};
- static constexpr int USRHashSize = 20;
- };
- // New Ids need to be added to both the enum here and the relevant IdNameMap in
- // the implementation file.
- enum BlockId {
- BI_VERSION_BLOCK_ID = llvm::bitc::FIRST_APPLICATION_BLOCKID,
- BI_NAMESPACE_BLOCK_ID,
- BI_ENUM_BLOCK_ID,
- BI_ENUM_VALUE_BLOCK_ID,
- BI_TYPE_BLOCK_ID,
- BI_FIELD_TYPE_BLOCK_ID,
- BI_MEMBER_TYPE_BLOCK_ID,
- BI_RECORD_BLOCK_ID,
- BI_BASE_RECORD_BLOCK_ID,
- BI_FUNCTION_BLOCK_ID,
- BI_COMMENT_BLOCK_ID,
- BI_REFERENCE_BLOCK_ID,
- BI_TEMPLATE_BLOCK_ID,
- BI_TEMPLATE_SPECIALIZATION_BLOCK_ID,
- BI_TEMPLATE_PARAM_BLOCK_ID,
- BI_TYPEDEF_BLOCK_ID,
- BI_LAST,
- BI_FIRST = BI_VERSION_BLOCK_ID
- };
- // New Ids need to be added to the enum here, and to the relevant IdNameMap and
- // initialization list in the implementation file.
- enum RecordId {
- VERSION = 1,
- FUNCTION_USR,
- FUNCTION_NAME,
- FUNCTION_DEFLOCATION,
- FUNCTION_LOCATION,
- FUNCTION_ACCESS,
- FUNCTION_IS_METHOD,
- COMMENT_KIND,
- COMMENT_TEXT,
- COMMENT_NAME,
- COMMENT_DIRECTION,
- COMMENT_PARAMNAME,
- COMMENT_CLOSENAME,
- COMMENT_SELFCLOSING,
- COMMENT_EXPLICIT,
- COMMENT_ATTRKEY,
- COMMENT_ATTRVAL,
- COMMENT_ARG,
- FIELD_TYPE_NAME,
- FIELD_DEFAULT_VALUE,
- MEMBER_TYPE_NAME,
- MEMBER_TYPE_ACCESS,
- NAMESPACE_USR,
- NAMESPACE_NAME,
- NAMESPACE_PATH,
- ENUM_USR,
- ENUM_NAME,
- ENUM_DEFLOCATION,
- ENUM_LOCATION,
- ENUM_SCOPED,
- ENUM_VALUE_NAME,
- ENUM_VALUE_VALUE,
- ENUM_VALUE_EXPR,
- RECORD_USR,
- RECORD_NAME,
- RECORD_PATH,
- RECORD_DEFLOCATION,
- RECORD_LOCATION,
- RECORD_TAG_TYPE,
- RECORD_IS_TYPE_DEF,
- BASE_RECORD_USR,
- BASE_RECORD_NAME,
- BASE_RECORD_PATH,
- BASE_RECORD_TAG_TYPE,
- BASE_RECORD_IS_VIRTUAL,
- BASE_RECORD_ACCESS,
- BASE_RECORD_IS_PARENT,
- REFERENCE_USR,
- REFERENCE_NAME,
- REFERENCE_QUAL_NAME,
- REFERENCE_TYPE,
- REFERENCE_PATH,
- REFERENCE_FIELD,
- TEMPLATE_PARAM_CONTENTS,
- TEMPLATE_SPECIALIZATION_OF,
- TYPEDEF_USR,
- TYPEDEF_NAME,
- TYPEDEF_DEFLOCATION,
- TYPEDEF_IS_USING,
- RI_LAST,
- RI_FIRST = VERSION
- };
- static constexpr unsigned BlockIdCount = BI_LAST - BI_FIRST;
- static constexpr unsigned RecordIdCount = RI_LAST - RI_FIRST;
- // Identifiers for differentiating between subblocks
- enum class FieldId {
- F_default,
- F_namespace,
- F_parent,
- F_vparent,
- F_type,
- F_child_namespace,
- F_child_record
- };
- class ClangDocBitcodeWriter {
- public:
- ClangDocBitcodeWriter(llvm::BitstreamWriter &Stream) : Stream(Stream) {
- emitHeader();
- emitBlockInfoBlock();
- emitVersionBlock();
- }
- // Write a specific info to a bitcode stream.
- bool dispatchInfoForWrite(Info *I);
- // Block emission of different info types.
- void emitBlock(const NamespaceInfo &I);
- void emitBlock(const RecordInfo &I);
- void emitBlock(const BaseRecordInfo &I);
- void emitBlock(const FunctionInfo &I);
- void emitBlock(const EnumInfo &I);
- void emitBlock(const EnumValueInfo &I);
- void emitBlock(const TypeInfo &B);
- void emitBlock(const TypedefInfo &B);
- void emitBlock(const FieldTypeInfo &B);
- void emitBlock(const MemberTypeInfo &T);
- void emitBlock(const CommentInfo &B);
- void emitBlock(const TemplateInfo &T);
- void emitBlock(const TemplateSpecializationInfo &T);
- void emitBlock(const TemplateParamInfo &T);
- void emitBlock(const Reference &B, FieldId F);
- private:
- class AbbreviationMap {
- llvm::DenseMap<unsigned, unsigned> Abbrevs;
- public:
- AbbreviationMap() : Abbrevs(RecordIdCount) {}
- void add(RecordId RID, unsigned AbbrevID);
- unsigned get(RecordId RID) const;
- };
- class StreamSubBlockGuard {
- llvm::BitstreamWriter &Stream;
- public:
- StreamSubBlockGuard(llvm::BitstreamWriter &Stream_, BlockId ID)
- : Stream(Stream_) {
- // NOTE: SubBlockIDSize could theoretically be calculated on the fly,
- // based on the initialization list of records in each block.
- Stream.EnterSubblock(ID, BitCodeConstants::SubblockIDSize);
- }
- StreamSubBlockGuard(const StreamSubBlockGuard &) = delete;
- StreamSubBlockGuard &operator=(const StreamSubBlockGuard &) = delete;
- ~StreamSubBlockGuard() { Stream.ExitBlock(); }
- };
- // Emission of validation and overview blocks.
- void emitHeader();
- void emitVersionBlock();
- void emitRecordID(RecordId ID);
- void emitBlockID(BlockId ID);
- void emitBlockInfoBlock();
- void emitBlockInfo(BlockId BID, const std::vector<RecordId> &RIDs);
- // Emission of individual record types.
- void emitRecord(StringRef Str, RecordId ID);
- void emitRecord(const SymbolID &Str, RecordId ID);
- void emitRecord(const Location &Loc, RecordId ID);
- void emitRecord(const Reference &Ref, RecordId ID);
- void emitRecord(bool Value, RecordId ID);
- void emitRecord(int Value, RecordId ID);
- void emitRecord(unsigned Value, RecordId ID);
- void emitRecord(const TemplateInfo &Templ);
- bool prepRecordData(RecordId ID, bool ShouldEmit = true);
- // Emission of appropriate abbreviation type.
- void emitAbbrev(RecordId ID, BlockId Block);
- // Static size is the maximum length of the block/record names we're pushing
- // to this + 1. Longest is currently `MemberTypeBlock` at 15 chars.
- SmallVector<uint32_t, BitCodeConstants::RecordSize> Record;
- llvm::BitstreamWriter &Stream;
- AbbreviationMap Abbrevs;
- };
- } // namespace doc
- } // namespace clang
- #endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_DOC_BITCODEWRITER_H
|