brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.6 KiB · 9c1b6ab Raw
269 lines · c
1//===--  BitcodeWriter.h - ClangDoc Bitcode Writer --------------*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file implements a writer for serializing the clang-doc internal10// representation to LLVM bitcode. The writer takes in a stream and emits the11// generated bitcode to that stream.12//13//===----------------------------------------------------------------------===//14 15#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_DOC_BITCODEWRITER_H16#define LLVM_CLANG_TOOLS_EXTRA_CLANG_DOC_BITCODEWRITER_H17 18#include "Representation.h"19#include "llvm/ADT/DenseMap.h"20#include "llvm/Bitstream/BitstreamWriter.h"21#include <vector>22 23namespace clang {24namespace doc {25 26// Current version number of clang-doc bitcode.27// Should be bumped when removing or changing BlockIds, RecordIds, or28// BitCodeConstants, though they can be added without breaking it.29static const unsigned VersionNumber = 3;30 31struct BitCodeConstants {32  static constexpr unsigned RecordSize = 32U;33  static constexpr unsigned SignatureBitSize = 8U;34  static constexpr unsigned SubblockIDSize = 4U;35  static constexpr unsigned BoolSize = 1U;36  static constexpr unsigned IntSize = 16U;37  static constexpr unsigned StringLengthSize = 16U;38  static constexpr unsigned FilenameLengthSize = 16U;39  static constexpr unsigned LineNumberSize = 32U;40  static constexpr unsigned ReferenceTypeSize = 8U;41  static constexpr unsigned USRLengthSize = 6U;42  static constexpr unsigned USRBitLengthSize = 8U;43  static constexpr unsigned char Signature[4] = {'D', 'O', 'C', 'S'};44  static constexpr int USRHashSize = 20;45};46 47// New Ids need to be added to both the enum here and the relevant IdNameMap in48// the implementation file.49enum BlockId {50  BI_VERSION_BLOCK_ID = llvm::bitc::FIRST_APPLICATION_BLOCKID,51  BI_NAMESPACE_BLOCK_ID,52  BI_ENUM_BLOCK_ID,53  BI_ENUM_VALUE_BLOCK_ID,54  BI_TYPE_BLOCK_ID,55  BI_FIELD_TYPE_BLOCK_ID,56  BI_MEMBER_TYPE_BLOCK_ID,57  BI_RECORD_BLOCK_ID,58  BI_BASE_RECORD_BLOCK_ID,59  BI_FUNCTION_BLOCK_ID,60  BI_COMMENT_BLOCK_ID,61  BI_REFERENCE_BLOCK_ID,62  BI_TEMPLATE_BLOCK_ID,63  BI_TEMPLATE_SPECIALIZATION_BLOCK_ID,64  BI_TEMPLATE_PARAM_BLOCK_ID,65  BI_CONSTRAINT_BLOCK_ID,66  BI_TYPEDEF_BLOCK_ID,67  BI_CONCEPT_BLOCK_ID,68  BI_VAR_BLOCK_ID,69  BI_FRIEND_BLOCK_ID,70  BI_LAST,71  BI_FIRST = BI_VERSION_BLOCK_ID72};73 74// New Ids need to be added to the enum here, and to the relevant IdNameMap and75// initialization list in the implementation file.76enum RecordId {77  VERSION = 1,78  FUNCTION_USR,79  FUNCTION_NAME,80  FUNCTION_DEFLOCATION,81  FUNCTION_LOCATION,82  FUNCTION_ACCESS,83  FUNCTION_IS_METHOD,84  FUNCTION_IS_STATIC,85  COMMENT_KIND,86  COMMENT_TEXT,87  COMMENT_NAME,88  COMMENT_DIRECTION,89  COMMENT_PARAMNAME,90  COMMENT_CLOSENAME,91  COMMENT_SELFCLOSING,92  COMMENT_EXPLICIT,93  COMMENT_ATTRKEY,94  COMMENT_ATTRVAL,95  COMMENT_ARG,96  TYPE_IS_BUILTIN,97  TYPE_IS_TEMPLATE,98  FIELD_TYPE_NAME,99  FIELD_DEFAULT_VALUE,100  FIELD_TYPE_IS_BUILTIN,101  FIELD_TYPE_IS_TEMPLATE,102  MEMBER_TYPE_NAME,103  MEMBER_TYPE_ACCESS,104  MEMBER_TYPE_IS_STATIC,105  MEMBER_TYPE_IS_BUILTIN,106  MEMBER_TYPE_IS_TEMPLATE,107  NAMESPACE_USR,108  NAMESPACE_NAME,109  NAMESPACE_PATH,110  ENUM_USR,111  ENUM_NAME,112  ENUM_DEFLOCATION,113  ENUM_LOCATION,114  ENUM_SCOPED,115  ENUM_VALUE_NAME,116  ENUM_VALUE_VALUE,117  ENUM_VALUE_EXPR,118  RECORD_USR,119  RECORD_NAME,120  RECORD_PATH,121  RECORD_DEFLOCATION,122  RECORD_LOCATION,123  RECORD_TAG_TYPE,124  RECORD_IS_TYPE_DEF,125  RECORD_MANGLED_NAME,126  BASE_RECORD_USR,127  BASE_RECORD_NAME,128  BASE_RECORD_PATH,129  BASE_RECORD_TAG_TYPE,130  BASE_RECORD_IS_VIRTUAL,131  BASE_RECORD_ACCESS,132  BASE_RECORD_IS_PARENT,133  REFERENCE_USR,134  REFERENCE_NAME,135  REFERENCE_QUAL_NAME,136  REFERENCE_TYPE,137  REFERENCE_PATH,138  REFERENCE_FIELD,139  REFERENCE_FILE,140  TEMPLATE_PARAM_CONTENTS,141  TEMPLATE_SPECIALIZATION_OF,142  TYPEDEF_USR,143  TYPEDEF_NAME,144  TYPEDEF_DEFLOCATION,145  TYPEDEF_IS_USING,146  CONCEPT_USR,147  CONCEPT_NAME,148  CONCEPT_IS_TYPE,149  CONCEPT_CONSTRAINT_EXPRESSION,150  CONSTRAINT_EXPRESSION,151  VAR_USR,152  VAR_NAME,153  VAR_DEFLOCATION,154  VAR_IS_STATIC,155  FRIEND_IS_CLASS,156  RI_LAST,157  RI_FIRST = VERSION158};159 160static constexpr unsigned BlockIdCount = BI_LAST - BI_FIRST;161static constexpr unsigned RecordIdCount = RI_LAST - RI_FIRST;162 163// Identifiers for differentiating between subblocks164enum class FieldId {165  F_default,166  F_namespace,167  F_parent,168  F_vparent,169  F_type,170  F_child_namespace,171  F_child_record,172  F_concept,173  F_friend174};175 176class ClangDocBitcodeWriter {177public:178  ClangDocBitcodeWriter(llvm::BitstreamWriter &Stream) : Stream(Stream) {179    emitHeader();180    emitBlockInfoBlock();181    emitVersionBlock();182  }183 184  // Write a specific info to a bitcode stream.185  bool dispatchInfoForWrite(Info *I);186 187  // Block emission of different info types.188  void emitBlock(const NamespaceInfo &I);189  void emitBlock(const RecordInfo &I);190  void emitBlock(const BaseRecordInfo &I);191  void emitBlock(const FunctionInfo &I);192  void emitBlock(const EnumInfo &I);193  void emitBlock(const EnumValueInfo &I);194  void emitBlock(const TypeInfo &B);195  void emitBlock(const TypedefInfo &B);196  void emitBlock(const FieldTypeInfo &B);197  void emitBlock(const MemberTypeInfo &T);198  void emitBlock(const CommentInfo &B);199  void emitBlock(const TemplateInfo &T);200  void emitBlock(const TemplateSpecializationInfo &T);201  void emitBlock(const TemplateParamInfo &T);202  void emitBlock(const ConceptInfo &T);203  void emitBlock(const ConstraintInfo &T);204  void emitBlock(const Reference &B, FieldId F);205  void emitBlock(const FriendInfo &R);206  void emitBlock(const VarInfo &B);207 208private:209  class AbbreviationMap {210    llvm::DenseMap<unsigned, unsigned> Abbrevs;211 212  public:213    AbbreviationMap() : Abbrevs(RecordIdCount) {}214 215    void add(RecordId RID, unsigned AbbrevID);216    unsigned get(RecordId RID) const;217  };218 219  class StreamSubBlockGuard {220    llvm::BitstreamWriter &Stream;221 222  public:223    StreamSubBlockGuard(llvm::BitstreamWriter &Stream_, BlockId ID)224        : Stream(Stream_) {225      // NOTE: SubBlockIDSize could theoretically be calculated on the fly,226      // based on the initialization list of records in each block.227      Stream.EnterSubblock(ID, BitCodeConstants::SubblockIDSize);228    }229 230    StreamSubBlockGuard(const StreamSubBlockGuard &) = delete;231    StreamSubBlockGuard &operator=(const StreamSubBlockGuard &) = delete;232 233    ~StreamSubBlockGuard() { Stream.ExitBlock(); }234  };235 236  // Emission of validation and overview blocks.237  void emitHeader();238  void emitVersionBlock();239  void emitRecordID(RecordId ID);240  void emitBlockID(BlockId ID);241  void emitBlockInfoBlock();242  void emitBlockInfo(BlockId BID, const std::vector<RecordId> &RIDs);243 244  // Emission of individual record types.245  void emitRecord(StringRef Str, RecordId ID);246  void emitRecord(const SymbolID &Str, RecordId ID);247  void emitRecord(const Location &Loc, RecordId ID);248  void emitRecord(const Reference &Ref, RecordId ID);249  void emitRecord(bool Value, RecordId ID);250  void emitRecord(int Value, RecordId ID);251  void emitRecord(unsigned Value, RecordId ID);252  void emitRecord(const TemplateInfo &Templ);253  bool prepRecordData(RecordId ID, bool ShouldEmit = true);254 255  // Emission of appropriate abbreviation type.256  void emitAbbrev(RecordId ID, BlockId Block);257 258  // Static size is the maximum length of the block/record names we're pushing259  // to this + 1. Longest is currently `MemberTypeBlock` at 15 chars.260  SmallVector<uint32_t, BitCodeConstants::RecordSize> Record;261  llvm::BitstreamWriter &Stream;262  AbbreviationMap Abbrevs;263};264 265} // namespace doc266} // namespace clang267 268#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_DOC_BITCODEWRITER_H269