summaryrefslogtreecommitdiffstats
path: root/clang-tools-extra/clang-doc/BitcodeWriter.h
diff options
context:
space:
mode:
Diffstat (limited to 'clang-tools-extra/clang-doc/BitcodeWriter.h')
-rw-r--r--clang-tools-extra/clang-doc/BitcodeWriter.h201
1 files changed, 201 insertions, 0 deletions
diff --git a/clang-tools-extra/clang-doc/BitcodeWriter.h b/clang-tools-extra/clang-doc/BitcodeWriter.h
new file mode 100644
index 00000000000..092bfc6338a
--- /dev/null
+++ b/clang-tools-extra/clang-doc/BitcodeWriter.h
@@ -0,0 +1,201 @@
+//===-- BitcodeWriter.h - ClangDoc Bitcode Writer --------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// 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/Bitcode/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 = 1;
+
+struct BitCodeConstants {
+ static constexpr unsigned RecordSize = 16U;
+ 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 = 16U;
+ static constexpr unsigned ReferenceTypeSize = 8U;
+ static constexpr unsigned USRLengthSize = 6U;
+ static constexpr unsigned USRBitLengthSize = 8U;
+};
+
+// 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_TYPE_BLOCK_ID,
+ BI_FIELD_TYPE_BLOCK_ID,
+ BI_MEMBER_TYPE_BLOCK_ID,
+ BI_RECORD_BLOCK_ID,
+ BI_FUNCTION_BLOCK_ID,
+ BI_COMMENT_BLOCK_ID,
+ BI_FIRST = BI_VERSION_BLOCK_ID,
+ BI_LAST = BI_COMMENT_BLOCK_ID
+};
+
+// New Ids need to be added to the enum here, and to the relevant IdNameMap and
+// initialization list in the implementation file.
+#define INFORECORDS(X) X##_USR, X##_NAME, X##_NAMESPACE
+
+enum RecordId {
+ VERSION = 1,
+ INFORECORDS(FUNCTION),
+ FUNCTION_DEFLOCATION,
+ FUNCTION_LOCATION,
+ FUNCTION_PARENT,
+ 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,
+ TYPE_REF,
+ FIELD_TYPE_REF,
+ FIELD_TYPE_NAME,
+ MEMBER_TYPE_REF,
+ MEMBER_TYPE_NAME,
+ MEMBER_TYPE_ACCESS,
+ INFORECORDS(NAMESPACE),
+ INFORECORDS(ENUM),
+ ENUM_DEFLOCATION,
+ ENUM_LOCATION,
+ ENUM_MEMBER,
+ ENUM_SCOPED,
+ INFORECORDS(RECORD),
+ RECORD_DEFLOCATION,
+ RECORD_LOCATION,
+ RECORD_TAG_TYPE,
+ RECORD_PARENT,
+ RECORD_VPARENT,
+ RI_FIRST = VERSION,
+ RI_LAST = RECORD_VPARENT
+};
+
+static constexpr unsigned BlockIdCount = BI_LAST - BI_FIRST + 1;
+static constexpr unsigned RecordIdCount = RI_LAST - RI_FIRST + 1;
+
+#undef INFORECORDS
+
+class ClangDocBitcodeWriter {
+public:
+ ClangDocBitcodeWriter(llvm::BitstreamWriter &Stream) : Stream(Stream) {
+ emitHeader();
+ emitBlockInfoBlock();
+ emitVersionBlock();
+ }
+
+#ifndef NDEBUG // Don't want explicit dtor unless needed.
+ ~ClangDocBitcodeWriter() {
+ // Check that the static size is large-enough.
+ assert(Record.capacity() > BitCodeConstants::RecordSize);
+ }
+#endif
+
+ // Block emission of different info types.
+ void emitBlock(const NamespaceInfo &I);
+ void emitBlock(const RecordInfo &I);
+ void emitBlock(const FunctionInfo &I);
+ void emitBlock(const EnumInfo &I);
+ void emitBlock(const TypeInfo &B);
+ void emitBlock(const FieldTypeInfo &B);
+ void emitBlock(const MemberTypeInfo &B);
+ void emitBlock(const CommentInfo &B);
+
+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() = default;
+ 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::initializer_list<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);
+ 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
OpenPOWER on IntegriCloud