1e975a473SJulie Hockett //===-- BitcodeWriter.cpp - ClangDoc Bitcode Writer ------------*- C++ -*-===// 2e975a473SJulie Hockett // 32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6e975a473SJulie Hockett // 7e975a473SJulie Hockett //===----------------------------------------------------------------------===// 8e975a473SJulie Hockett 9e975a473SJulie Hockett #include "BitcodeWriter.h" 10e975a473SJulie Hockett #include "llvm/ADT/IndexedMap.h" 11e975a473SJulie Hockett #include <initializer_list> 12e975a473SJulie Hockett 13e975a473SJulie Hockett namespace clang { 14e975a473SJulie Hockett namespace doc { 15e975a473SJulie Hockett 16b59cd77cSJulie Hockett // Empty SymbolID for comparison, so we don't have to construct one every time. 17b59cd77cSJulie Hockett static const SymbolID EmptySID = SymbolID(); 18b59cd77cSJulie Hockett 19e975a473SJulie Hockett // Since id enums are not zero-indexed, we need to transform the given id into 20e975a473SJulie Hockett // its associated index. 21e975a473SJulie Hockett struct BlockIdToIndexFunctor { 22e975a473SJulie Hockett using argument_type = unsigned; 23e975a473SJulie Hockett unsigned operator()(unsigned ID) const { return ID - BI_FIRST; } 24e975a473SJulie Hockett }; 25e975a473SJulie Hockett 26e975a473SJulie Hockett struct RecordIdToIndexFunctor { 27e975a473SJulie Hockett using argument_type = unsigned; 28e975a473SJulie Hockett unsigned operator()(unsigned ID) const { return ID - RI_FIRST; } 29e975a473SJulie Hockett }; 30e975a473SJulie Hockett 31e975a473SJulie Hockett using AbbrevDsc = void (*)(std::shared_ptr<llvm::BitCodeAbbrev> &Abbrev); 32e975a473SJulie Hockett 33e975a473SJulie Hockett static void AbbrevGen(std::shared_ptr<llvm::BitCodeAbbrev> &Abbrev, 34e975a473SJulie Hockett const std::initializer_list<llvm::BitCodeAbbrevOp> Ops) { 35e975a473SJulie Hockett for (const auto &Op : Ops) 36e975a473SJulie Hockett Abbrev->Add(Op); 37e975a473SJulie Hockett } 38e975a473SJulie Hockett 39e975a473SJulie Hockett static void BoolAbbrev(std::shared_ptr<llvm::BitCodeAbbrev> &Abbrev) { 40e975a473SJulie Hockett AbbrevGen(Abbrev, 41e975a473SJulie Hockett {// 0. Boolean 42e975a473SJulie Hockett llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Fixed, 43e975a473SJulie Hockett BitCodeConstants::BoolSize)}); 44e975a473SJulie Hockett } 45e975a473SJulie Hockett 46e975a473SJulie Hockett static void IntAbbrev(std::shared_ptr<llvm::BitCodeAbbrev> &Abbrev) { 47e975a473SJulie Hockett AbbrevGen(Abbrev, 48e975a473SJulie Hockett {// 0. Fixed-size integer 49e975a473SJulie Hockett llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Fixed, 50e975a473SJulie Hockett BitCodeConstants::IntSize)}); 51e975a473SJulie Hockett } 52e975a473SJulie Hockett 53e975a473SJulie Hockett static void SymbolIDAbbrev(std::shared_ptr<llvm::BitCodeAbbrev> &Abbrev) { 54e975a473SJulie Hockett AbbrevGen(Abbrev, 55e975a473SJulie Hockett {// 0. Fixed-size integer (length of the sha1'd USR) 56e975a473SJulie Hockett llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Fixed, 57e975a473SJulie Hockett BitCodeConstants::USRLengthSize), 58e975a473SJulie Hockett // 1. Fixed-size array of Char6 (USR) 59e975a473SJulie Hockett llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Array), 60e975a473SJulie Hockett llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Fixed, 61e975a473SJulie Hockett BitCodeConstants::USRBitLengthSize)}); 62e975a473SJulie Hockett } 63e975a473SJulie Hockett 64e975a473SJulie Hockett static void StringAbbrev(std::shared_ptr<llvm::BitCodeAbbrev> &Abbrev) { 65e975a473SJulie Hockett AbbrevGen(Abbrev, 66e975a473SJulie Hockett {// 0. Fixed-size integer (length of the following string) 67e975a473SJulie Hockett llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Fixed, 68e975a473SJulie Hockett BitCodeConstants::StringLengthSize), 69e975a473SJulie Hockett // 1. The string blob 70e975a473SJulie Hockett llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob)}); 71e975a473SJulie Hockett } 72e975a473SJulie Hockett 73e975a473SJulie Hockett // Assumes that the file will not have more than 65535 lines. 74e975a473SJulie Hockett static void LocationAbbrev(std::shared_ptr<llvm::BitCodeAbbrev> &Abbrev) { 75e975a473SJulie Hockett AbbrevGen( 76e975a473SJulie Hockett Abbrev, 77e975a473SJulie Hockett {// 0. Fixed-size integer (line number) 78e975a473SJulie Hockett llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Fixed, 79e975a473SJulie Hockett BitCodeConstants::LineNumberSize), 80665e9676SDiego Astiazaran // 1. Boolean (IsFileInRootDir) 81665e9676SDiego Astiazaran llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Fixed, 82665e9676SDiego Astiazaran BitCodeConstants::BoolSize), 83665e9676SDiego Astiazaran // 2. Fixed-size integer (length of the following string (filename)) 84e975a473SJulie Hockett llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Fixed, 85e975a473SJulie Hockett BitCodeConstants::StringLengthSize), 86665e9676SDiego Astiazaran // 3. The string blob 87e975a473SJulie Hockett llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob)}); 88e975a473SJulie Hockett } 89e975a473SJulie Hockett 90e975a473SJulie Hockett struct RecordIdDsc { 91e975a473SJulie Hockett llvm::StringRef Name; 92e975a473SJulie Hockett AbbrevDsc Abbrev = nullptr; 93e975a473SJulie Hockett 94e975a473SJulie Hockett RecordIdDsc() = default; 95e975a473SJulie Hockett RecordIdDsc(llvm::StringRef Name, AbbrevDsc Abbrev) 96e975a473SJulie Hockett : Name(Name), Abbrev(Abbrev) {} 97e975a473SJulie Hockett 98e975a473SJulie Hockett // Is this 'description' valid? 99e975a473SJulie Hockett operator bool() const { 100e975a473SJulie Hockett return Abbrev != nullptr && Name.data() != nullptr && !Name.empty(); 101e975a473SJulie Hockett } 102e975a473SJulie Hockett }; 103e975a473SJulie Hockett 104e975a473SJulie Hockett static const llvm::IndexedMap<llvm::StringRef, BlockIdToIndexFunctor> 105e975a473SJulie Hockett BlockIdNameMap = []() { 106e975a473SJulie Hockett llvm::IndexedMap<llvm::StringRef, BlockIdToIndexFunctor> BlockIdNameMap; 107e975a473SJulie Hockett BlockIdNameMap.resize(BlockIdCount); 108e975a473SJulie Hockett 109e975a473SJulie Hockett // There is no init-list constructor for the IndexedMap, so have to 110e975a473SJulie Hockett // improvise 111e975a473SJulie Hockett static const std::vector<std::pair<BlockId, const char *const>> Inits = { 112e975a473SJulie Hockett {BI_VERSION_BLOCK_ID, "VersionBlock"}, 113e975a473SJulie Hockett {BI_NAMESPACE_BLOCK_ID, "NamespaceBlock"}, 114e975a473SJulie Hockett {BI_ENUM_BLOCK_ID, "EnumBlock"}, 115eaa7b324SBrett Wilson {BI_ENUM_VALUE_BLOCK_ID, "EnumValueBlock"}, 11621fb70c6SBrett Wilson {BI_TYPEDEF_BLOCK_ID, "TypedefBlock"}, 117e975a473SJulie Hockett {BI_TYPE_BLOCK_ID, "TypeBlock"}, 118e975a473SJulie Hockett {BI_FIELD_TYPE_BLOCK_ID, "FieldTypeBlock"}, 119e975a473SJulie Hockett {BI_MEMBER_TYPE_BLOCK_ID, "MemberTypeBlock"}, 120e975a473SJulie Hockett {BI_RECORD_BLOCK_ID, "RecordBlock"}, 121ba3d595fSDiego Astiazaran {BI_BASE_RECORD_BLOCK_ID, "BaseRecordBlock"}, 122e975a473SJulie Hockett {BI_FUNCTION_BLOCK_ID, "FunctionBlock"}, 123b59cd77cSJulie Hockett {BI_COMMENT_BLOCK_ID, "CommentBlock"}, 1244a68babdSBrett Wilson {BI_REFERENCE_BLOCK_ID, "ReferenceBlock"}, 1254a68babdSBrett Wilson {BI_TEMPLATE_BLOCK_ID, "TemplateBlock"}, 1264a68babdSBrett Wilson {BI_TEMPLATE_SPECIALIZATION_BLOCK_ID, "TemplateSpecializationBlock"}, 1274a68babdSBrett Wilson {BI_TEMPLATE_PARAM_BLOCK_ID, "TemplateParamBlock"}}; 128e975a473SJulie Hockett assert(Inits.size() == BlockIdCount); 129e975a473SJulie Hockett for (const auto &Init : Inits) 130e975a473SJulie Hockett BlockIdNameMap[Init.first] = Init.second; 131e975a473SJulie Hockett assert(BlockIdNameMap.size() == BlockIdCount); 132e975a473SJulie Hockett return BlockIdNameMap; 133e975a473SJulie Hockett }(); 134e975a473SJulie Hockett 135e975a473SJulie Hockett static const llvm::IndexedMap<RecordIdDsc, RecordIdToIndexFunctor> 136e975a473SJulie Hockett RecordIdNameMap = []() { 137e975a473SJulie Hockett llvm::IndexedMap<RecordIdDsc, RecordIdToIndexFunctor> RecordIdNameMap; 138e975a473SJulie Hockett RecordIdNameMap.resize(RecordIdCount); 139e975a473SJulie Hockett 140e975a473SJulie Hockett // There is no init-list constructor for the IndexedMap, so have to 141e975a473SJulie Hockett // improvise 142e975a473SJulie Hockett static const std::vector<std::pair<RecordId, RecordIdDsc>> Inits = { 143e975a473SJulie Hockett {VERSION, {"Version", &IntAbbrev}}, 144e975a473SJulie Hockett {COMMENT_KIND, {"Kind", &StringAbbrev}}, 145e975a473SJulie Hockett {COMMENT_TEXT, {"Text", &StringAbbrev}}, 146e975a473SJulie Hockett {COMMENT_NAME, {"Name", &StringAbbrev}}, 147e975a473SJulie Hockett {COMMENT_DIRECTION, {"Direction", &StringAbbrev}}, 148e975a473SJulie Hockett {COMMENT_PARAMNAME, {"ParamName", &StringAbbrev}}, 149e975a473SJulie Hockett {COMMENT_CLOSENAME, {"CloseName", &StringAbbrev}}, 150e975a473SJulie Hockett {COMMENT_SELFCLOSING, {"SelfClosing", &BoolAbbrev}}, 151e975a473SJulie Hockett {COMMENT_EXPLICIT, {"Explicit", &BoolAbbrev}}, 152e975a473SJulie Hockett {COMMENT_ATTRKEY, {"AttrKey", &StringAbbrev}}, 153e975a473SJulie Hockett {COMMENT_ATTRVAL, {"AttrVal", &StringAbbrev}}, 154e975a473SJulie Hockett {COMMENT_ARG, {"Arg", &StringAbbrev}}, 155e975a473SJulie Hockett {FIELD_TYPE_NAME, {"Name", &StringAbbrev}}, 156e191086bSBrett Wilson {FIELD_DEFAULT_VALUE, {"DefaultValue", &StringAbbrev}}, 157e975a473SJulie Hockett {MEMBER_TYPE_NAME, {"Name", &StringAbbrev}}, 158e975a473SJulie Hockett {MEMBER_TYPE_ACCESS, {"Access", &IntAbbrev}}, 159e975a473SJulie Hockett {NAMESPACE_USR, {"USR", &SymbolIDAbbrev}}, 160e975a473SJulie Hockett {NAMESPACE_NAME, {"Name", &StringAbbrev}}, 1612c1c9a24SJulie Hockett {NAMESPACE_PATH, {"Path", &StringAbbrev}}, 162e975a473SJulie Hockett {ENUM_USR, {"USR", &SymbolIDAbbrev}}, 163e975a473SJulie Hockett {ENUM_NAME, {"Name", &StringAbbrev}}, 164e975a473SJulie Hockett {ENUM_DEFLOCATION, {"DefLocation", &LocationAbbrev}}, 165e975a473SJulie Hockett {ENUM_LOCATION, {"Location", &LocationAbbrev}}, 166e975a473SJulie Hockett {ENUM_SCOPED, {"Scoped", &BoolAbbrev}}, 167eaa7b324SBrett Wilson {ENUM_VALUE_NAME, {"Name", &StringAbbrev}}, 168eaa7b324SBrett Wilson {ENUM_VALUE_VALUE, {"Value", &StringAbbrev}}, 169eaa7b324SBrett Wilson {ENUM_VALUE_EXPR, {"Expr", &StringAbbrev}}, 170e975a473SJulie Hockett {RECORD_USR, {"USR", &SymbolIDAbbrev}}, 171e975a473SJulie Hockett {RECORD_NAME, {"Name", &StringAbbrev}}, 1722c1c9a24SJulie Hockett {RECORD_PATH, {"Path", &StringAbbrev}}, 173e975a473SJulie Hockett {RECORD_DEFLOCATION, {"DefLocation", &LocationAbbrev}}, 174e975a473SJulie Hockett {RECORD_LOCATION, {"Location", &LocationAbbrev}}, 175e975a473SJulie Hockett {RECORD_TAG_TYPE, {"TagType", &IntAbbrev}}, 176b1f01e27SJulie Hockett {RECORD_IS_TYPE_DEF, {"IsTypeDef", &BoolAbbrev}}, 177ba3d595fSDiego Astiazaran {BASE_RECORD_USR, {"USR", &SymbolIDAbbrev}}, 178ba3d595fSDiego Astiazaran {BASE_RECORD_NAME, {"Name", &StringAbbrev}}, 179ba3d595fSDiego Astiazaran {BASE_RECORD_PATH, {"Path", &StringAbbrev}}, 180ba3d595fSDiego Astiazaran {BASE_RECORD_TAG_TYPE, {"TagType", &IntAbbrev}}, 181ba3d595fSDiego Astiazaran {BASE_RECORD_IS_VIRTUAL, {"IsVirtual", &BoolAbbrev}}, 182ba3d595fSDiego Astiazaran {BASE_RECORD_ACCESS, {"Access", &IntAbbrev}}, 183ba3d595fSDiego Astiazaran {BASE_RECORD_IS_PARENT, {"IsParent", &BoolAbbrev}}, 184e975a473SJulie Hockett {FUNCTION_USR, {"USR", &SymbolIDAbbrev}}, 185e975a473SJulie Hockett {FUNCTION_NAME, {"Name", &StringAbbrev}}, 186e975a473SJulie Hockett {FUNCTION_DEFLOCATION, {"DefLocation", &LocationAbbrev}}, 187e975a473SJulie Hockett {FUNCTION_LOCATION, {"Location", &LocationAbbrev}}, 188e975a473SJulie Hockett {FUNCTION_ACCESS, {"Access", &IntAbbrev}}, 189b59cd77cSJulie Hockett {FUNCTION_IS_METHOD, {"IsMethod", &BoolAbbrev}}, 190b59cd77cSJulie Hockett {REFERENCE_USR, {"USR", &SymbolIDAbbrev}}, 191b59cd77cSJulie Hockett {REFERENCE_NAME, {"Name", &StringAbbrev}}, 1924a68babdSBrett Wilson {REFERENCE_QUAL_NAME, {"QualName", &StringAbbrev}}, 193b59cd77cSJulie Hockett {REFERENCE_TYPE, {"RefType", &IntAbbrev}}, 1942c1c9a24SJulie Hockett {REFERENCE_PATH, {"Path", &StringAbbrev}}, 19521fb70c6SBrett Wilson {REFERENCE_FIELD, {"Field", &IntAbbrev}}, 1964a68babdSBrett Wilson {TEMPLATE_PARAM_CONTENTS, {"Contents", &StringAbbrev}}, 1974a68babdSBrett Wilson {TEMPLATE_SPECIALIZATION_OF, {"SpecializationOf", &SymbolIDAbbrev}}, 19821fb70c6SBrett Wilson {TYPEDEF_USR, {"USR", &SymbolIDAbbrev}}, 19921fb70c6SBrett Wilson {TYPEDEF_NAME, {"Name", &StringAbbrev}}, 20021fb70c6SBrett Wilson {TYPEDEF_DEFLOCATION, {"DefLocation", &LocationAbbrev}}, 20121fb70c6SBrett Wilson {TYPEDEF_IS_USING, {"IsUsing", &BoolAbbrev}}}; 202e975a473SJulie Hockett assert(Inits.size() == RecordIdCount); 203e975a473SJulie Hockett for (const auto &Init : Inits) { 204e975a473SJulie Hockett RecordIdNameMap[Init.first] = Init.second; 205e975a473SJulie Hockett assert((Init.second.Name.size() + 1) <= BitCodeConstants::RecordSize); 206e975a473SJulie Hockett } 207e975a473SJulie Hockett assert(RecordIdNameMap.size() == RecordIdCount); 208e975a473SJulie Hockett return RecordIdNameMap; 209e975a473SJulie Hockett }(); 210e975a473SJulie Hockett 211e975a473SJulie Hockett static const std::vector<std::pair<BlockId, std::vector<RecordId>>> 212e975a473SJulie Hockett RecordsByBlock{ 213e975a473SJulie Hockett // Version Block 214e975a473SJulie Hockett {BI_VERSION_BLOCK_ID, {VERSION}}, 215e975a473SJulie Hockett // Comment Block 216e975a473SJulie Hockett {BI_COMMENT_BLOCK_ID, 217e975a473SJulie Hockett {COMMENT_KIND, COMMENT_TEXT, COMMENT_NAME, COMMENT_DIRECTION, 218e975a473SJulie Hockett COMMENT_PARAMNAME, COMMENT_CLOSENAME, COMMENT_SELFCLOSING, 219e975a473SJulie Hockett COMMENT_EXPLICIT, COMMENT_ATTRKEY, COMMENT_ATTRVAL, COMMENT_ARG}}, 220e975a473SJulie Hockett // Type Block 221b59cd77cSJulie Hockett {BI_TYPE_BLOCK_ID, {}}, 222e975a473SJulie Hockett // FieldType Block 223e191086bSBrett Wilson {BI_FIELD_TYPE_BLOCK_ID, {FIELD_TYPE_NAME, FIELD_DEFAULT_VALUE}}, 224e975a473SJulie Hockett // MemberType Block 225b59cd77cSJulie Hockett {BI_MEMBER_TYPE_BLOCK_ID, {MEMBER_TYPE_NAME, MEMBER_TYPE_ACCESS}}, 226e975a473SJulie Hockett // Enum Block 227e975a473SJulie Hockett {BI_ENUM_BLOCK_ID, 228eaa7b324SBrett Wilson {ENUM_USR, ENUM_NAME, ENUM_DEFLOCATION, ENUM_LOCATION, ENUM_SCOPED}}, 229eaa7b324SBrett Wilson // Enum Value Block 230eaa7b324SBrett Wilson {BI_ENUM_VALUE_BLOCK_ID, 231eaa7b324SBrett Wilson {ENUM_VALUE_NAME, ENUM_VALUE_VALUE, ENUM_VALUE_EXPR}}, 23221fb70c6SBrett Wilson // Typedef Block 23321fb70c6SBrett Wilson {BI_TYPEDEF_BLOCK_ID, 23421fb70c6SBrett Wilson {TYPEDEF_USR, TYPEDEF_NAME, TYPEDEF_DEFLOCATION, TYPEDEF_IS_USING}}, 235e975a473SJulie Hockett // Namespace Block 2362c1c9a24SJulie Hockett {BI_NAMESPACE_BLOCK_ID, 2372c1c9a24SJulie Hockett {NAMESPACE_USR, NAMESPACE_NAME, NAMESPACE_PATH}}, 238e975a473SJulie Hockett // Record Block 239e975a473SJulie Hockett {BI_RECORD_BLOCK_ID, 2402c1c9a24SJulie Hockett {RECORD_USR, RECORD_NAME, RECORD_PATH, RECORD_DEFLOCATION, 2412c1c9a24SJulie Hockett RECORD_LOCATION, RECORD_TAG_TYPE, RECORD_IS_TYPE_DEF}}, 242ba3d595fSDiego Astiazaran // BaseRecord Block 243ba3d595fSDiego Astiazaran {BI_BASE_RECORD_BLOCK_ID, 244ba3d595fSDiego Astiazaran {BASE_RECORD_USR, BASE_RECORD_NAME, BASE_RECORD_PATH, 245ba3d595fSDiego Astiazaran BASE_RECORD_TAG_TYPE, BASE_RECORD_IS_VIRTUAL, BASE_RECORD_ACCESS, 246ba3d595fSDiego Astiazaran BASE_RECORD_IS_PARENT}}, 247e975a473SJulie Hockett // Function Block 248e975a473SJulie Hockett {BI_FUNCTION_BLOCK_ID, 249b59cd77cSJulie Hockett {FUNCTION_USR, FUNCTION_NAME, FUNCTION_DEFLOCATION, FUNCTION_LOCATION, 250b59cd77cSJulie Hockett FUNCTION_ACCESS, FUNCTION_IS_METHOD}}, 251b59cd77cSJulie Hockett // Reference Block 252b59cd77cSJulie Hockett {BI_REFERENCE_BLOCK_ID, 2534a68babdSBrett Wilson {REFERENCE_USR, REFERENCE_NAME, REFERENCE_QUAL_NAME, REFERENCE_TYPE, 2544a68babdSBrett Wilson REFERENCE_PATH, REFERENCE_FIELD}}, 2554a68babdSBrett Wilson // Template Blocks. 2564a68babdSBrett Wilson {BI_TEMPLATE_BLOCK_ID, {}}, 2574a68babdSBrett Wilson {BI_TEMPLATE_PARAM_BLOCK_ID, {TEMPLATE_PARAM_CONTENTS}}, 2584a68babdSBrett Wilson {BI_TEMPLATE_SPECIALIZATION_BLOCK_ID, {TEMPLATE_SPECIALIZATION_OF}}}; 259e975a473SJulie Hockett 260e975a473SJulie Hockett // AbbreviationMap 261e975a473SJulie Hockett 2620e828958SJF Bastien constexpr unsigned char BitCodeConstants::Signature[]; 263d0f9a872SJulie Hockett 264e975a473SJulie Hockett void ClangDocBitcodeWriter::AbbreviationMap::add(RecordId RID, 265e975a473SJulie Hockett unsigned AbbrevID) { 266e975a473SJulie Hockett assert(RecordIdNameMap[RID] && "Unknown RecordId."); 2674e585e51SKazu Hirata assert(!Abbrevs.contains(RID) && "Abbreviation already added."); 268e975a473SJulie Hockett Abbrevs[RID] = AbbrevID; 269e975a473SJulie Hockett } 270e975a473SJulie Hockett 271e975a473SJulie Hockett unsigned ClangDocBitcodeWriter::AbbreviationMap::get(RecordId RID) const { 272e975a473SJulie Hockett assert(RecordIdNameMap[RID] && "Unknown RecordId."); 2734e585e51SKazu Hirata assert(Abbrevs.contains(RID) && "Unknown abbreviation."); 274e975a473SJulie Hockett return Abbrevs.lookup(RID); 275e975a473SJulie Hockett } 276e975a473SJulie Hockett 277e975a473SJulie Hockett // Validation and Overview Blocks 278e975a473SJulie Hockett 279282dc72cSDmitri Gribenko /// Emits the magic number header to check that its the right format, 280e975a473SJulie Hockett /// in this case, 'DOCS'. 281e975a473SJulie Hockett void ClangDocBitcodeWriter::emitHeader() { 282d0f9a872SJulie Hockett for (char C : BitCodeConstants::Signature) 283e975a473SJulie Hockett Stream.Emit((unsigned)C, BitCodeConstants::SignatureBitSize); 284e975a473SJulie Hockett } 285e975a473SJulie Hockett 286e975a473SJulie Hockett void ClangDocBitcodeWriter::emitVersionBlock() { 287e975a473SJulie Hockett StreamSubBlockGuard Block(Stream, BI_VERSION_BLOCK_ID); 288e975a473SJulie Hockett emitRecord(VersionNumber, VERSION); 289e975a473SJulie Hockett } 290e975a473SJulie Hockett 291282dc72cSDmitri Gribenko /// Emits a block ID and the block name to the BLOCKINFO block. 292e975a473SJulie Hockett void ClangDocBitcodeWriter::emitBlockID(BlockId BID) { 293e975a473SJulie Hockett const auto &BlockIdName = BlockIdNameMap[BID]; 294e975a473SJulie Hockett assert(BlockIdName.data() && BlockIdName.size() && "Unknown BlockId."); 295e975a473SJulie Hockett 296e975a473SJulie Hockett Record.clear(); 297e975a473SJulie Hockett Record.push_back(BID); 298e975a473SJulie Hockett Stream.EmitRecord(llvm::bitc::BLOCKINFO_CODE_SETBID, Record); 299e975a473SJulie Hockett Stream.EmitRecord(llvm::bitc::BLOCKINFO_CODE_BLOCKNAME, 3009345d982SJulie Hockett ArrayRef<unsigned char>(BlockIdName.bytes_begin(), 3019345d982SJulie Hockett BlockIdName.bytes_end())); 302e975a473SJulie Hockett } 303e975a473SJulie Hockett 304282dc72cSDmitri Gribenko /// Emits a record name to the BLOCKINFO block. 305e975a473SJulie Hockett void ClangDocBitcodeWriter::emitRecordID(RecordId ID) { 306e975a473SJulie Hockett assert(RecordIdNameMap[ID] && "Unknown RecordId."); 307e975a473SJulie Hockett prepRecordData(ID); 308e975a473SJulie Hockett Record.append(RecordIdNameMap[ID].Name.begin(), 309e975a473SJulie Hockett RecordIdNameMap[ID].Name.end()); 310e975a473SJulie Hockett Stream.EmitRecord(llvm::bitc::BLOCKINFO_CODE_SETRECORDNAME, Record); 311e975a473SJulie Hockett } 312e975a473SJulie Hockett 313e975a473SJulie Hockett // Abbreviations 314e975a473SJulie Hockett 315e975a473SJulie Hockett void ClangDocBitcodeWriter::emitAbbrev(RecordId ID, BlockId Block) { 316e975a473SJulie Hockett assert(RecordIdNameMap[ID] && "Unknown abbreviation."); 317e975a473SJulie Hockett auto Abbrev = std::make_shared<llvm::BitCodeAbbrev>(); 318e975a473SJulie Hockett Abbrev->Add(llvm::BitCodeAbbrevOp(ID)); 319e975a473SJulie Hockett RecordIdNameMap[ID].Abbrev(Abbrev); 320e975a473SJulie Hockett Abbrevs.add(ID, Stream.EmitBlockInfoAbbrev(Block, std::move(Abbrev))); 321e975a473SJulie Hockett } 322e975a473SJulie Hockett 323e975a473SJulie Hockett // Records 324e975a473SJulie Hockett 325e975a473SJulie Hockett void ClangDocBitcodeWriter::emitRecord(const SymbolID &Sym, RecordId ID) { 326e975a473SJulie Hockett assert(RecordIdNameMap[ID] && "Unknown RecordId."); 327e975a473SJulie Hockett assert(RecordIdNameMap[ID].Abbrev == &SymbolIDAbbrev && 328e975a473SJulie Hockett "Abbrev type mismatch."); 329b59cd77cSJulie Hockett if (!prepRecordData(ID, Sym != EmptySID)) 330e975a473SJulie Hockett return; 331e975a473SJulie Hockett assert(Sym.size() == 20); 332e975a473SJulie Hockett Record.push_back(Sym.size()); 333e975a473SJulie Hockett Record.append(Sym.begin(), Sym.end()); 334e975a473SJulie Hockett Stream.EmitRecordWithAbbrev(Abbrevs.get(ID), Record); 335e975a473SJulie Hockett } 336e975a473SJulie Hockett 337e975a473SJulie Hockett void ClangDocBitcodeWriter::emitRecord(llvm::StringRef Str, RecordId ID) { 338e975a473SJulie Hockett assert(RecordIdNameMap[ID] && "Unknown RecordId."); 339e975a473SJulie Hockett assert(RecordIdNameMap[ID].Abbrev == &StringAbbrev && 340e975a473SJulie Hockett "Abbrev type mismatch."); 341e975a473SJulie Hockett if (!prepRecordData(ID, !Str.empty())) 342e975a473SJulie Hockett return; 343e975a473SJulie Hockett assert(Str.size() < (1U << BitCodeConstants::StringLengthSize)); 344e975a473SJulie Hockett Record.push_back(Str.size()); 345e975a473SJulie Hockett Stream.EmitRecordWithBlob(Abbrevs.get(ID), Record, Str); 346e975a473SJulie Hockett } 347e975a473SJulie Hockett 348e975a473SJulie Hockett void ClangDocBitcodeWriter::emitRecord(const Location &Loc, RecordId ID) { 349e975a473SJulie Hockett assert(RecordIdNameMap[ID] && "Unknown RecordId."); 350e975a473SJulie Hockett assert(RecordIdNameMap[ID].Abbrev == &LocationAbbrev && 351e975a473SJulie Hockett "Abbrev type mismatch."); 352e975a473SJulie Hockett if (!prepRecordData(ID, true)) 353e975a473SJulie Hockett return; 354e975a473SJulie Hockett // FIXME: Assert that the line number is of the appropriate size. 355e975a473SJulie Hockett Record.push_back(Loc.LineNumber); 356e975a473SJulie Hockett assert(Loc.Filename.size() < (1U << BitCodeConstants::StringLengthSize)); 357665e9676SDiego Astiazaran Record.push_back(Loc.IsFileInRootDir); 358f276624eSJulie Hockett Record.push_back(Loc.Filename.size()); 359f276624eSJulie Hockett Stream.EmitRecordWithBlob(Abbrevs.get(ID), Record, Loc.Filename); 360e975a473SJulie Hockett } 361e975a473SJulie Hockett 362e975a473SJulie Hockett void ClangDocBitcodeWriter::emitRecord(bool Val, RecordId ID) { 363e975a473SJulie Hockett assert(RecordIdNameMap[ID] && "Unknown RecordId."); 364e975a473SJulie Hockett assert(RecordIdNameMap[ID].Abbrev == &BoolAbbrev && "Abbrev type mismatch."); 365e975a473SJulie Hockett if (!prepRecordData(ID, Val)) 366e975a473SJulie Hockett return; 367e975a473SJulie Hockett Record.push_back(Val); 368e975a473SJulie Hockett Stream.EmitRecordWithAbbrev(Abbrevs.get(ID), Record); 369e975a473SJulie Hockett } 370e975a473SJulie Hockett 371e975a473SJulie Hockett void ClangDocBitcodeWriter::emitRecord(int Val, RecordId ID) { 372e975a473SJulie Hockett assert(RecordIdNameMap[ID] && "Unknown RecordId."); 373e975a473SJulie Hockett assert(RecordIdNameMap[ID].Abbrev == &IntAbbrev && "Abbrev type mismatch."); 374e975a473SJulie Hockett if (!prepRecordData(ID, Val)) 375e975a473SJulie Hockett return; 376e975a473SJulie Hockett // FIXME: Assert that the integer is of the appropriate size. 377e975a473SJulie Hockett Record.push_back(Val); 378e975a473SJulie Hockett Stream.EmitRecordWithAbbrev(Abbrevs.get(ID), Record); 379e975a473SJulie Hockett } 380e975a473SJulie Hockett 381e975a473SJulie Hockett void ClangDocBitcodeWriter::emitRecord(unsigned Val, RecordId ID) { 382e975a473SJulie Hockett assert(RecordIdNameMap[ID] && "Unknown RecordId."); 383e975a473SJulie Hockett assert(RecordIdNameMap[ID].Abbrev == &IntAbbrev && "Abbrev type mismatch."); 384e975a473SJulie Hockett if (!prepRecordData(ID, Val)) 385e975a473SJulie Hockett return; 386e975a473SJulie Hockett assert(Val < (1U << BitCodeConstants::IntSize)); 387e975a473SJulie Hockett Record.push_back(Val); 388e975a473SJulie Hockett Stream.EmitRecordWithAbbrev(Abbrevs.get(ID), Record); 389e975a473SJulie Hockett } 390e975a473SJulie Hockett 3914a68babdSBrett Wilson void ClangDocBitcodeWriter::emitRecord(const TemplateInfo &Templ) {} 3924a68babdSBrett Wilson 393e975a473SJulie Hockett bool ClangDocBitcodeWriter::prepRecordData(RecordId ID, bool ShouldEmit) { 394e975a473SJulie Hockett assert(RecordIdNameMap[ID] && "Unknown RecordId."); 395e975a473SJulie Hockett if (!ShouldEmit) 396e975a473SJulie Hockett return false; 397e975a473SJulie Hockett Record.clear(); 398e975a473SJulie Hockett Record.push_back(ID); 399e975a473SJulie Hockett return true; 400e975a473SJulie Hockett } 401e975a473SJulie Hockett 402e975a473SJulie Hockett // BlockInfo Block 403e975a473SJulie Hockett 404e975a473SJulie Hockett void ClangDocBitcodeWriter::emitBlockInfoBlock() { 405e975a473SJulie Hockett Stream.EnterBlockInfoBlock(); 406e975a473SJulie Hockett for (const auto &Block : RecordsByBlock) { 407e975a473SJulie Hockett assert(Block.second.size() < (1U << BitCodeConstants::SubblockIDSize)); 408e975a473SJulie Hockett emitBlockInfo(Block.first, Block.second); 409e975a473SJulie Hockett } 410e975a473SJulie Hockett Stream.ExitBlock(); 411e975a473SJulie Hockett } 412e975a473SJulie Hockett 413e975a473SJulie Hockett void ClangDocBitcodeWriter::emitBlockInfo(BlockId BID, 414e975a473SJulie Hockett const std::vector<RecordId> &RIDs) { 415e975a473SJulie Hockett assert(RIDs.size() < (1U << BitCodeConstants::SubblockIDSize)); 416e975a473SJulie Hockett emitBlockID(BID); 417e975a473SJulie Hockett for (RecordId RID : RIDs) { 418e975a473SJulie Hockett emitRecordID(RID); 419e975a473SJulie Hockett emitAbbrev(RID, BID); 420e975a473SJulie Hockett } 421e975a473SJulie Hockett } 422e975a473SJulie Hockett 423e975a473SJulie Hockett // Block emission 424e975a473SJulie Hockett 425b59cd77cSJulie Hockett void ClangDocBitcodeWriter::emitBlock(const Reference &R, FieldId Field) { 426b59cd77cSJulie Hockett if (R.USR == EmptySID && R.Name.empty()) 427b59cd77cSJulie Hockett return; 428b59cd77cSJulie Hockett StreamSubBlockGuard Block(Stream, BI_REFERENCE_BLOCK_ID); 429b59cd77cSJulie Hockett emitRecord(R.USR, REFERENCE_USR); 430b59cd77cSJulie Hockett emitRecord(R.Name, REFERENCE_NAME); 4314a68babdSBrett Wilson emitRecord(R.QualName, REFERENCE_QUAL_NAME); 432b59cd77cSJulie Hockett emitRecord((unsigned)R.RefType, REFERENCE_TYPE); 4332c1c9a24SJulie Hockett emitRecord(R.Path, REFERENCE_PATH); 434b59cd77cSJulie Hockett emitRecord((unsigned)Field, REFERENCE_FIELD); 435b59cd77cSJulie Hockett } 436b59cd77cSJulie Hockett 437e975a473SJulie Hockett void ClangDocBitcodeWriter::emitBlock(const TypeInfo &T) { 438e975a473SJulie Hockett StreamSubBlockGuard Block(Stream, BI_TYPE_BLOCK_ID); 439b59cd77cSJulie Hockett emitBlock(T.Type, FieldId::F_type); 440e975a473SJulie Hockett } 441e975a473SJulie Hockett 44221fb70c6SBrett Wilson void ClangDocBitcodeWriter::emitBlock(const TypedefInfo &T) { 44321fb70c6SBrett Wilson StreamSubBlockGuard Block(Stream, BI_TYPEDEF_BLOCK_ID); 44421fb70c6SBrett Wilson emitRecord(T.USR, TYPEDEF_USR); 44521fb70c6SBrett Wilson emitRecord(T.Name, TYPEDEF_NAME); 44621fb70c6SBrett Wilson for (const auto &N : T.Namespace) 44721fb70c6SBrett Wilson emitBlock(N, FieldId::F_namespace); 4487231c996SBrett Wilson for (const auto &CI : T.Description) 4497231c996SBrett Wilson emitBlock(CI); 45021fb70c6SBrett Wilson if (T.DefLoc) 45121fb70c6SBrett Wilson emitRecord(*T.DefLoc, TYPEDEF_DEFLOCATION); 45221fb70c6SBrett Wilson emitRecord(T.IsUsing, TYPEDEF_IS_USING); 45321fb70c6SBrett Wilson emitBlock(T.Underlying); 45421fb70c6SBrett Wilson } 45521fb70c6SBrett Wilson 456e975a473SJulie Hockett void ClangDocBitcodeWriter::emitBlock(const FieldTypeInfo &T) { 457e975a473SJulie Hockett StreamSubBlockGuard Block(Stream, BI_FIELD_TYPE_BLOCK_ID); 458b59cd77cSJulie Hockett emitBlock(T.Type, FieldId::F_type); 459e975a473SJulie Hockett emitRecord(T.Name, FIELD_TYPE_NAME); 460e191086bSBrett Wilson emitRecord(T.DefaultValue, FIELD_DEFAULT_VALUE); 461e975a473SJulie Hockett } 462e975a473SJulie Hockett 463e975a473SJulie Hockett void ClangDocBitcodeWriter::emitBlock(const MemberTypeInfo &T) { 464e975a473SJulie Hockett StreamSubBlockGuard Block(Stream, BI_MEMBER_TYPE_BLOCK_ID); 465b59cd77cSJulie Hockett emitBlock(T.Type, FieldId::F_type); 466e975a473SJulie Hockett emitRecord(T.Name, MEMBER_TYPE_NAME); 467e975a473SJulie Hockett emitRecord(T.Access, MEMBER_TYPE_ACCESS); 46899baa10fSBrett Wilson for (const auto &CI : T.Description) 46999baa10fSBrett Wilson emitBlock(CI); 470e975a473SJulie Hockett } 471e975a473SJulie Hockett 472e975a473SJulie Hockett void ClangDocBitcodeWriter::emitBlock(const CommentInfo &I) { 473e975a473SJulie Hockett StreamSubBlockGuard Block(Stream, BI_COMMENT_BLOCK_ID); 474b59cd77cSJulie Hockett for (const auto &L : std::vector<std::pair<llvm::StringRef, RecordId>>{ 475e975a473SJulie Hockett {I.Kind, COMMENT_KIND}, 476e975a473SJulie Hockett {I.Text, COMMENT_TEXT}, 477e975a473SJulie Hockett {I.Name, COMMENT_NAME}, 478e975a473SJulie Hockett {I.Direction, COMMENT_DIRECTION}, 479e975a473SJulie Hockett {I.ParamName, COMMENT_PARAMNAME}, 480e975a473SJulie Hockett {I.CloseName, COMMENT_CLOSENAME}}) 481e975a473SJulie Hockett emitRecord(L.first, L.second); 482e975a473SJulie Hockett emitRecord(I.SelfClosing, COMMENT_SELFCLOSING); 483e975a473SJulie Hockett emitRecord(I.Explicit, COMMENT_EXPLICIT); 484e975a473SJulie Hockett for (const auto &A : I.AttrKeys) 485e975a473SJulie Hockett emitRecord(A, COMMENT_ATTRKEY); 486e975a473SJulie Hockett for (const auto &A : I.AttrValues) 487e975a473SJulie Hockett emitRecord(A, COMMENT_ATTRVAL); 488e975a473SJulie Hockett for (const auto &A : I.Args) 489e975a473SJulie Hockett emitRecord(A, COMMENT_ARG); 490e975a473SJulie Hockett for (const auto &C : I.Children) 491e975a473SJulie Hockett emitBlock(*C); 492e975a473SJulie Hockett } 493e975a473SJulie Hockett 494e975a473SJulie Hockett void ClangDocBitcodeWriter::emitBlock(const NamespaceInfo &I) { 495e975a473SJulie Hockett StreamSubBlockGuard Block(Stream, BI_NAMESPACE_BLOCK_ID); 496d0f9a872SJulie Hockett emitRecord(I.USR, NAMESPACE_USR); 497d0f9a872SJulie Hockett emitRecord(I.Name, NAMESPACE_NAME); 4982c1c9a24SJulie Hockett emitRecord(I.Path, NAMESPACE_PATH); 499d0f9a872SJulie Hockett for (const auto &N : I.Namespace) 500d0f9a872SJulie Hockett emitBlock(N, FieldId::F_namespace); 501d0f9a872SJulie Hockett for (const auto &CI : I.Description) 502d0f9a872SJulie Hockett emitBlock(CI); 50321fb70c6SBrett Wilson for (const auto &C : I.Children.Namespaces) 5048899c29bSJulie Hockett emitBlock(C, FieldId::F_child_namespace); 50521fb70c6SBrett Wilson for (const auto &C : I.Children.Records) 5068899c29bSJulie Hockett emitBlock(C, FieldId::F_child_record); 50721fb70c6SBrett Wilson for (const auto &C : I.Children.Functions) 5088899c29bSJulie Hockett emitBlock(C); 50921fb70c6SBrett Wilson for (const auto &C : I.Children.Enums) 51021fb70c6SBrett Wilson emitBlock(C); 51121fb70c6SBrett Wilson for (const auto &C : I.Children.Typedefs) 5128899c29bSJulie Hockett emitBlock(C); 513e975a473SJulie Hockett } 514e975a473SJulie Hockett 515e975a473SJulie Hockett void ClangDocBitcodeWriter::emitBlock(const EnumInfo &I) { 516e975a473SJulie Hockett StreamSubBlockGuard Block(Stream, BI_ENUM_BLOCK_ID); 517d0f9a872SJulie Hockett emitRecord(I.USR, ENUM_USR); 518d0f9a872SJulie Hockett emitRecord(I.Name, ENUM_NAME); 519d0f9a872SJulie Hockett for (const auto &N : I.Namespace) 520d0f9a872SJulie Hockett emitBlock(N, FieldId::F_namespace); 521d0f9a872SJulie Hockett for (const auto &CI : I.Description) 522d0f9a872SJulie Hockett emitBlock(CI); 523e975a473SJulie Hockett if (I.DefLoc) 524ed8fceaaSKazu Hirata emitRecord(*I.DefLoc, ENUM_DEFLOCATION); 525e975a473SJulie Hockett for (const auto &L : I.Loc) 526e975a473SJulie Hockett emitRecord(L, ENUM_LOCATION); 527e975a473SJulie Hockett emitRecord(I.Scoped, ENUM_SCOPED); 528eaa7b324SBrett Wilson if (I.BaseType) 529eaa7b324SBrett Wilson emitBlock(*I.BaseType); 530e975a473SJulie Hockett for (const auto &N : I.Members) 531eaa7b324SBrett Wilson emitBlock(N); 532eaa7b324SBrett Wilson } 533eaa7b324SBrett Wilson 534eaa7b324SBrett Wilson void ClangDocBitcodeWriter::emitBlock(const EnumValueInfo &I) { 535eaa7b324SBrett Wilson StreamSubBlockGuard Block(Stream, BI_ENUM_VALUE_BLOCK_ID); 536eaa7b324SBrett Wilson emitRecord(I.Name, ENUM_VALUE_NAME); 537eaa7b324SBrett Wilson emitRecord(I.Value, ENUM_VALUE_VALUE); 538eaa7b324SBrett Wilson emitRecord(I.ValueExpr, ENUM_VALUE_EXPR); 539*5ef2456aSPeterChou1 for (const auto &CI : I.Description) 540*5ef2456aSPeterChou1 emitBlock(CI); 541e975a473SJulie Hockett } 542e975a473SJulie Hockett 543e975a473SJulie Hockett void ClangDocBitcodeWriter::emitBlock(const RecordInfo &I) { 544e975a473SJulie Hockett StreamSubBlockGuard Block(Stream, BI_RECORD_BLOCK_ID); 545d0f9a872SJulie Hockett emitRecord(I.USR, RECORD_USR); 546d0f9a872SJulie Hockett emitRecord(I.Name, RECORD_NAME); 5472c1c9a24SJulie Hockett emitRecord(I.Path, RECORD_PATH); 548d0f9a872SJulie Hockett for (const auto &N : I.Namespace) 549d0f9a872SJulie Hockett emitBlock(N, FieldId::F_namespace); 550d0f9a872SJulie Hockett for (const auto &CI : I.Description) 551d0f9a872SJulie Hockett emitBlock(CI); 552e975a473SJulie Hockett if (I.DefLoc) 553ed8fceaaSKazu Hirata emitRecord(*I.DefLoc, RECORD_DEFLOCATION); 554e975a473SJulie Hockett for (const auto &L : I.Loc) 555e975a473SJulie Hockett emitRecord(L, RECORD_LOCATION); 556edd690b0SVlad Serebrennikov emitRecord(llvm::to_underlying(I.TagType), RECORD_TAG_TYPE); 557b1f01e27SJulie Hockett emitRecord(I.IsTypeDef, RECORD_IS_TYPE_DEF); 558e975a473SJulie Hockett for (const auto &N : I.Members) 559e975a473SJulie Hockett emitBlock(N); 560e975a473SJulie Hockett for (const auto &P : I.Parents) 561b59cd77cSJulie Hockett emitBlock(P, FieldId::F_parent); 562e975a473SJulie Hockett for (const auto &P : I.VirtualParents) 563b59cd77cSJulie Hockett emitBlock(P, FieldId::F_vparent); 564ba3d595fSDiego Astiazaran for (const auto &PB : I.Bases) 565ba3d595fSDiego Astiazaran emitBlock(PB); 56621fb70c6SBrett Wilson for (const auto &C : I.Children.Records) 5678899c29bSJulie Hockett emitBlock(C, FieldId::F_child_record); 56821fb70c6SBrett Wilson for (const auto &C : I.Children.Functions) 5698899c29bSJulie Hockett emitBlock(C); 57021fb70c6SBrett Wilson for (const auto &C : I.Children.Enums) 57121fb70c6SBrett Wilson emitBlock(C); 57221fb70c6SBrett Wilson for (const auto &C : I.Children.Typedefs) 5738899c29bSJulie Hockett emitBlock(C); 5744a68babdSBrett Wilson if (I.Template) 5754a68babdSBrett Wilson emitBlock(*I.Template); 576e975a473SJulie Hockett } 577e975a473SJulie Hockett 578ba3d595fSDiego Astiazaran void ClangDocBitcodeWriter::emitBlock(const BaseRecordInfo &I) { 579ba3d595fSDiego Astiazaran StreamSubBlockGuard Block(Stream, BI_BASE_RECORD_BLOCK_ID); 580ba3d595fSDiego Astiazaran emitRecord(I.USR, BASE_RECORD_USR); 581ba3d595fSDiego Astiazaran emitRecord(I.Name, BASE_RECORD_NAME); 582ba3d595fSDiego Astiazaran emitRecord(I.Path, BASE_RECORD_PATH); 583edd690b0SVlad Serebrennikov emitRecord(llvm::to_underlying(I.TagType), BASE_RECORD_TAG_TYPE); 584ba3d595fSDiego Astiazaran emitRecord(I.IsVirtual, BASE_RECORD_IS_VIRTUAL); 585ba3d595fSDiego Astiazaran emitRecord(I.Access, BASE_RECORD_ACCESS); 586ba3d595fSDiego Astiazaran emitRecord(I.IsParent, BASE_RECORD_IS_PARENT); 587ba3d595fSDiego Astiazaran for (const auto &M : I.Members) 588ba3d595fSDiego Astiazaran emitBlock(M); 58921fb70c6SBrett Wilson for (const auto &C : I.Children.Functions) 590ba3d595fSDiego Astiazaran emitBlock(C); 591ba3d595fSDiego Astiazaran } 592ba3d595fSDiego Astiazaran 593e975a473SJulie Hockett void ClangDocBitcodeWriter::emitBlock(const FunctionInfo &I) { 594e975a473SJulie Hockett StreamSubBlockGuard Block(Stream, BI_FUNCTION_BLOCK_ID); 595d0f9a872SJulie Hockett emitRecord(I.USR, FUNCTION_USR); 596d0f9a872SJulie Hockett emitRecord(I.Name, FUNCTION_NAME); 597d0f9a872SJulie Hockett for (const auto &N : I.Namespace) 598d0f9a872SJulie Hockett emitBlock(N, FieldId::F_namespace); 599d0f9a872SJulie Hockett for (const auto &CI : I.Description) 600d0f9a872SJulie Hockett emitBlock(CI); 6016a29ae4bSDiego Astiazaran emitRecord(I.Access, FUNCTION_ACCESS); 602e975a473SJulie Hockett emitRecord(I.IsMethod, FUNCTION_IS_METHOD); 603e975a473SJulie Hockett if (I.DefLoc) 604ed8fceaaSKazu Hirata emitRecord(*I.DefLoc, FUNCTION_DEFLOCATION); 605e975a473SJulie Hockett for (const auto &L : I.Loc) 606e975a473SJulie Hockett emitRecord(L, FUNCTION_LOCATION); 607b59cd77cSJulie Hockett emitBlock(I.Parent, FieldId::F_parent); 608e975a473SJulie Hockett emitBlock(I.ReturnType); 609e975a473SJulie Hockett for (const auto &N : I.Params) 610e975a473SJulie Hockett emitBlock(N); 6114a68babdSBrett Wilson if (I.Template) 6124a68babdSBrett Wilson emitBlock(*I.Template); 6134a68babdSBrett Wilson } 6144a68babdSBrett Wilson 6154a68babdSBrett Wilson void ClangDocBitcodeWriter::emitBlock(const TemplateInfo &T) { 6164a68babdSBrett Wilson StreamSubBlockGuard Block(Stream, BI_TEMPLATE_BLOCK_ID); 6174a68babdSBrett Wilson for (const auto &P : T.Params) 6184a68babdSBrett Wilson emitBlock(P); 6194a68babdSBrett Wilson if (T.Specialization) 6204a68babdSBrett Wilson emitBlock(*T.Specialization); 6214a68babdSBrett Wilson } 6224a68babdSBrett Wilson 6234a68babdSBrett Wilson void ClangDocBitcodeWriter::emitBlock(const TemplateSpecializationInfo &T) { 6244a68babdSBrett Wilson StreamSubBlockGuard Block(Stream, BI_TEMPLATE_SPECIALIZATION_BLOCK_ID); 6254a68babdSBrett Wilson emitRecord(T.SpecializationOf, TEMPLATE_SPECIALIZATION_OF); 6264a68babdSBrett Wilson for (const auto &P : T.Params) 6274a68babdSBrett Wilson emitBlock(P); 6284a68babdSBrett Wilson } 6294a68babdSBrett Wilson 6304a68babdSBrett Wilson void ClangDocBitcodeWriter::emitBlock(const TemplateParamInfo &T) { 6314a68babdSBrett Wilson StreamSubBlockGuard Block(Stream, BI_TEMPLATE_PARAM_BLOCK_ID); 6324a68babdSBrett Wilson emitRecord(T.Contents, TEMPLATE_PARAM_CONTENTS); 633e975a473SJulie Hockett } 634e975a473SJulie Hockett 635d0f9a872SJulie Hockett bool ClangDocBitcodeWriter::dispatchInfoForWrite(Info *I) { 636d0f9a872SJulie Hockett switch (I->IT) { 637d0f9a872SJulie Hockett case InfoType::IT_namespace: 638d0f9a872SJulie Hockett emitBlock(*static_cast<clang::doc::NamespaceInfo *>(I)); 639d0f9a872SJulie Hockett break; 640d0f9a872SJulie Hockett case InfoType::IT_record: 641d0f9a872SJulie Hockett emitBlock(*static_cast<clang::doc::RecordInfo *>(I)); 642d0f9a872SJulie Hockett break; 643d0f9a872SJulie Hockett case InfoType::IT_enum: 644d0f9a872SJulie Hockett emitBlock(*static_cast<clang::doc::EnumInfo *>(I)); 645d0f9a872SJulie Hockett break; 646d0f9a872SJulie Hockett case InfoType::IT_function: 647d0f9a872SJulie Hockett emitBlock(*static_cast<clang::doc::FunctionInfo *>(I)); 648d0f9a872SJulie Hockett break; 64921fb70c6SBrett Wilson case InfoType::IT_typedef: 65021fb70c6SBrett Wilson emitBlock(*static_cast<clang::doc::TypedefInfo *>(I)); 65121fb70c6SBrett Wilson break; 652d0f9a872SJulie Hockett default: 653d0f9a872SJulie Hockett llvm::errs() << "Unexpected info, unable to write.\n"; 654d0f9a872SJulie Hockett return true; 655d0f9a872SJulie Hockett } 656d0f9a872SJulie Hockett return false; 657d0f9a872SJulie Hockett } 658e975a473SJulie Hockett 659e975a473SJulie Hockett } // namespace doc 660e975a473SJulie Hockett } // namespace clang 661