Index: clang-doc/BitcodeWriter.h =================================================================== --- clang-doc/BitcodeWriter.h +++ clang-doc/BitcodeWriter.h @@ -31,7 +31,7 @@ // 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; +static const unsigned VersionNumber = 2; struct BitCodeConstants { static constexpr unsigned RecordSize = 16U; @@ -59,20 +59,20 @@ BI_RECORD_BLOCK_ID, BI_FUNCTION_BLOCK_ID, BI_COMMENT_BLOCK_ID, - BI_FIRST = BI_VERSION_BLOCK_ID, - BI_LAST = BI_COMMENT_BLOCK_ID + BI_REFERENCE_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. -#define INFORECORDS(X) X##_USR, X##_NAME, X##_NAMESPACE +#define INFORECORDS(X) X##_USR, X##_NAME enum RecordId { VERSION = 1, INFORECORDS(FUNCTION), FUNCTION_DEFLOCATION, FUNCTION_LOCATION, - FUNCTION_PARENT, FUNCTION_ACCESS, FUNCTION_IS_METHOD, COMMENT_KIND, @@ -86,10 +86,7 @@ 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), @@ -102,17 +99,22 @@ RECORD_DEFLOCATION, RECORD_LOCATION, RECORD_TAG_TYPE, - RECORD_PARENT, - RECORD_VPARENT, - RI_FIRST = VERSION, - RI_LAST = RECORD_VPARENT + REFERENCE_USR, + REFERENCE_NAME, + REFERENCE_TYPE, + REFERENCE_FIELD, + RI_LAST, + RI_FIRST = VERSION }; -static constexpr unsigned BlockIdCount = BI_LAST - BI_FIRST + 1; -static constexpr unsigned RecordIdCount = RI_LAST - RI_FIRST + 1; +static constexpr unsigned BlockIdCount = BI_LAST - BI_FIRST; +static constexpr unsigned RecordIdCount = RI_LAST - RI_FIRST; #undef INFORECORDS +// Identifiers for differentiating between subblocks +enum class FieldId { F_namespace = 1, F_parent, F_vparent, F_type }; + class ClangDocBitcodeWriter { public: ClangDocBitcodeWriter(llvm::BitstreamWriter &Stream) : Stream(Stream) { @@ -137,6 +139,7 @@ void emitBlock(const FieldTypeInfo &B); void emitBlock(const MemberTypeInfo &B); void emitBlock(const CommentInfo &B); + void emitBlock(const Reference &B, FieldId F); private: class AbbreviationMap { Index: clang-doc/BitcodeWriter.cpp =================================================================== --- clang-doc/BitcodeWriter.cpp +++ clang-doc/BitcodeWriter.cpp @@ -14,6 +14,9 @@ namespace clang { namespace doc { +// Empty SymbolID for comparison, so we don't have to construct one every time. +static const SymbolID EmptySID = SymbolID(); + // Since id enums are not zero-indexed, we need to transform the given id into // its associated index. struct BlockIdToIndexFunctor { @@ -82,18 +85,6 @@ llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob)}); } -static void ReferenceAbbrev(std::shared_ptr &Abbrev) { - AbbrevGen(Abbrev, - {// 0. Fixed-size integer (ref type) - llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Fixed, - BitCodeConstants::ReferenceTypeSize), - // 1. Fixed-size integer (length of the USR or UnresolvedName) - llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Fixed, - BitCodeConstants::StringLengthSize), - // 2. The string blob - llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob)}); -} - struct RecordIdDsc { llvm::StringRef Name; AbbrevDsc Abbrev = nullptr; @@ -124,7 +115,8 @@ {BI_MEMBER_TYPE_BLOCK_ID, "MemberTypeBlock"}, {BI_RECORD_BLOCK_ID, "RecordBlock"}, {BI_FUNCTION_BLOCK_ID, "FunctionBlock"}, - {BI_COMMENT_BLOCK_ID, "CommentBlock"}}; + {BI_COMMENT_BLOCK_ID, "CommentBlock"}, + {BI_REFERENCE_BLOCK_ID, "ReferenceBlock"}}; assert(Inits.size() == BlockIdCount); for (const auto &Init : Inits) BlockIdNameMap[Init.first] = Init.second; @@ -152,38 +144,32 @@ {COMMENT_ATTRKEY, {"AttrKey", &StringAbbrev}}, {COMMENT_ATTRVAL, {"AttrVal", &StringAbbrev}}, {COMMENT_ARG, {"Arg", &StringAbbrev}}, - {TYPE_REF, {"Type", &ReferenceAbbrev}}, - {FIELD_TYPE_REF, {"Type", &ReferenceAbbrev}}, {FIELD_TYPE_NAME, {"Name", &StringAbbrev}}, - {MEMBER_TYPE_REF, {"Type", &ReferenceAbbrev}}, {MEMBER_TYPE_NAME, {"Name", &StringAbbrev}}, {MEMBER_TYPE_ACCESS, {"Access", &IntAbbrev}}, {NAMESPACE_USR, {"USR", &SymbolIDAbbrev}}, {NAMESPACE_NAME, {"Name", &StringAbbrev}}, - {NAMESPACE_NAMESPACE, {"Namespace", &ReferenceAbbrev}}, {ENUM_USR, {"USR", &SymbolIDAbbrev}}, {ENUM_NAME, {"Name", &StringAbbrev}}, - {ENUM_NAMESPACE, {"Namespace", &ReferenceAbbrev}}, {ENUM_DEFLOCATION, {"DefLocation", &LocationAbbrev}}, {ENUM_LOCATION, {"Location", &LocationAbbrev}}, {ENUM_MEMBER, {"Member", &StringAbbrev}}, {ENUM_SCOPED, {"Scoped", &BoolAbbrev}}, {RECORD_USR, {"USR", &SymbolIDAbbrev}}, {RECORD_NAME, {"Name", &StringAbbrev}}, - {RECORD_NAMESPACE, {"Namespace", &ReferenceAbbrev}}, {RECORD_DEFLOCATION, {"DefLocation", &LocationAbbrev}}, {RECORD_LOCATION, {"Location", &LocationAbbrev}}, {RECORD_TAG_TYPE, {"TagType", &IntAbbrev}}, - {RECORD_PARENT, {"Parent", &ReferenceAbbrev}}, - {RECORD_VPARENT, {"VParent", &ReferenceAbbrev}}, {FUNCTION_USR, {"USR", &SymbolIDAbbrev}}, {FUNCTION_NAME, {"Name", &StringAbbrev}}, - {FUNCTION_NAMESPACE, {"Namespace", &ReferenceAbbrev}}, {FUNCTION_DEFLOCATION, {"DefLocation", &LocationAbbrev}}, {FUNCTION_LOCATION, {"Location", &LocationAbbrev}}, - {FUNCTION_PARENT, {"Parent", &ReferenceAbbrev}}, {FUNCTION_ACCESS, {"Access", &IntAbbrev}}, - {FUNCTION_IS_METHOD, {"IsMethod", &BoolAbbrev}}}; + {FUNCTION_IS_METHOD, {"IsMethod", &BoolAbbrev}}, + {REFERENCE_USR, {"USR", &SymbolIDAbbrev}}, + {REFERENCE_NAME, {"Name", &StringAbbrev}}, + {REFERENCE_TYPE, {"RefType", &IntAbbrev}}, + {REFERENCE_FIELD, {"Field", &IntAbbrev}}}; assert(Inits.size() == RecordIdCount); for (const auto &Init : Inits) { RecordIdNameMap[Init.first] = Init.second; @@ -203,28 +189,28 @@ COMMENT_PARAMNAME, COMMENT_CLOSENAME, COMMENT_SELFCLOSING, COMMENT_EXPLICIT, COMMENT_ATTRKEY, COMMENT_ATTRVAL, COMMENT_ARG}}, // Type Block - {BI_TYPE_BLOCK_ID, {TYPE_REF}}, + {BI_TYPE_BLOCK_ID, {}}, // FieldType Block - {BI_FIELD_TYPE_BLOCK_ID, {FIELD_TYPE_REF, FIELD_TYPE_NAME}}, + {BI_FIELD_TYPE_BLOCK_ID, {FIELD_TYPE_NAME}}, // MemberType Block - {BI_MEMBER_TYPE_BLOCK_ID, - {MEMBER_TYPE_REF, MEMBER_TYPE_NAME, MEMBER_TYPE_ACCESS}}, + {BI_MEMBER_TYPE_BLOCK_ID, {MEMBER_TYPE_NAME, MEMBER_TYPE_ACCESS}}, // Enum Block {BI_ENUM_BLOCK_ID, - {ENUM_USR, ENUM_NAME, ENUM_NAMESPACE, ENUM_DEFLOCATION, ENUM_LOCATION, - ENUM_MEMBER, ENUM_SCOPED}}, + {ENUM_USR, ENUM_NAME, ENUM_DEFLOCATION, ENUM_LOCATION, ENUM_MEMBER, + ENUM_SCOPED}}, // Namespace Block - {BI_NAMESPACE_BLOCK_ID, - {NAMESPACE_USR, NAMESPACE_NAME, NAMESPACE_NAMESPACE}}, + {BI_NAMESPACE_BLOCK_ID, {NAMESPACE_USR, NAMESPACE_NAME}}, // Record Block {BI_RECORD_BLOCK_ID, - {RECORD_USR, RECORD_NAME, RECORD_NAMESPACE, RECORD_DEFLOCATION, - RECORD_LOCATION, RECORD_TAG_TYPE, RECORD_PARENT, RECORD_VPARENT}}, + {RECORD_USR, RECORD_NAME, RECORD_DEFLOCATION, RECORD_LOCATION, + RECORD_TAG_TYPE}}, // Function Block {BI_FUNCTION_BLOCK_ID, - {FUNCTION_USR, FUNCTION_NAME, FUNCTION_NAMESPACE, FUNCTION_DEFLOCATION, - FUNCTION_LOCATION, FUNCTION_PARENT, FUNCTION_ACCESS, - FUNCTION_IS_METHOD}}}; + {FUNCTION_USR, FUNCTION_NAME, FUNCTION_DEFLOCATION, FUNCTION_LOCATION, + FUNCTION_ACCESS, FUNCTION_IS_METHOD}}, + // Reference Block + {BI_REFERENCE_BLOCK_ID, + {REFERENCE_USR, REFERENCE_NAME, REFERENCE_TYPE, REFERENCE_FIELD}}}; // AbbreviationMap @@ -293,7 +279,7 @@ assert(RecordIdNameMap[ID] && "Unknown RecordId."); assert(RecordIdNameMap[ID].Abbrev == &SymbolIDAbbrev && "Abbrev type mismatch."); - if (!prepRecordData(ID, !Sym.empty())) + if (!prepRecordData(ID, Sym != EmptySID)) return; assert(Sym.size() == 20); Record.push_back(Sym.size()); @@ -327,26 +313,6 @@ Stream.EmitRecordWithBlob(Abbrevs.get(ID), Record, "test"); } -void ClangDocBitcodeWriter::emitRecord(const Reference &Ref, RecordId ID) { - assert(RecordIdNameMap[ID] && "Unknown RecordId."); - assert(RecordIdNameMap[ID].Abbrev == &ReferenceAbbrev && - "Abbrev type mismatch."); - SmallString<40> StringUSR; - StringRef OutString; - if (Ref.RefType == InfoType::IT_default) - OutString = Ref.UnresolvedName; - else { - StringUSR = llvm::toHex(llvm::toStringRef(Ref.USR)); - OutString = StringUSR; - } - if (!prepRecordData(ID, !OutString.empty())) - return; - assert(OutString.size() < (1U << BitCodeConstants::StringLengthSize)); - Record.push_back((int)Ref.RefType); - Record.push_back(OutString.size()); - Stream.EmitRecordWithBlob(Abbrevs.get(ID), Record, OutString); -} - void ClangDocBitcodeWriter::emitRecord(bool Val, RecordId ID) { assert(RecordIdNameMap[ID] && "Unknown RecordId."); assert(RecordIdNameMap[ID].Abbrev == &BoolAbbrev && "Abbrev type mismatch."); @@ -408,28 +374,37 @@ // Block emission +void ClangDocBitcodeWriter::emitBlock(const Reference &R, FieldId Field) { + if (R.USR == EmptySID && R.Name.empty()) + return; + StreamSubBlockGuard Block(Stream, BI_REFERENCE_BLOCK_ID); + emitRecord(R.USR, REFERENCE_USR); + emitRecord(R.Name, REFERENCE_NAME); + emitRecord((unsigned)R.RefType, REFERENCE_TYPE); + emitRecord((unsigned)Field, REFERENCE_FIELD); +} + void ClangDocBitcodeWriter::emitBlock(const TypeInfo &T) { StreamSubBlockGuard Block(Stream, BI_TYPE_BLOCK_ID); - emitRecord(T.Type, TYPE_REF); + emitBlock(T.Type, FieldId::F_type); } void ClangDocBitcodeWriter::emitBlock(const FieldTypeInfo &T) { StreamSubBlockGuard Block(Stream, BI_FIELD_TYPE_BLOCK_ID); - emitRecord(T.Type, FIELD_TYPE_REF); + emitBlock(T.Type, FieldId::F_type); emitRecord(T.Name, FIELD_TYPE_NAME); } void ClangDocBitcodeWriter::emitBlock(const MemberTypeInfo &T) { StreamSubBlockGuard Block(Stream, BI_MEMBER_TYPE_BLOCK_ID); - emitRecord(T.Type, MEMBER_TYPE_REF); + emitBlock(T.Type, FieldId::F_type); emitRecord(T.Name, MEMBER_TYPE_NAME); emitRecord(T.Access, MEMBER_TYPE_ACCESS); } void ClangDocBitcodeWriter::emitBlock(const CommentInfo &I) { StreamSubBlockGuard Block(Stream, BI_COMMENT_BLOCK_ID); - for (const auto &L : - std::vector>{ + for (const auto &L : std::vector>{ {I.Kind, COMMENT_KIND}, {I.Text, COMMENT_TEXT}, {I.Name, COMMENT_NAME}, @@ -453,7 +428,7 @@ emitRecord(I.USR, X##_USR); \ emitRecord(I.Name, X##_NAME); \ for (const auto &N : I.Namespace) \ - emitRecord(N, X##_NAMESPACE); \ + emitBlock(N, FieldId::F_namespace); \ for (const auto &CI : I.Description) \ emitBlock(CI); @@ -485,9 +460,9 @@ for (const auto &N : I.Members) emitBlock(N); for (const auto &P : I.Parents) - emitRecord(P, RECORD_PARENT); + emitBlock(P, FieldId::F_parent); for (const auto &P : I.VirtualParents) - emitRecord(P, RECORD_VPARENT); + emitBlock(P, FieldId::F_vparent); } void ClangDocBitcodeWriter::emitBlock(const FunctionInfo &I) { @@ -498,7 +473,7 @@ emitRecord(I.DefLoc.getValue(), FUNCTION_DEFLOCATION); for (const auto &L : I.Loc) emitRecord(L, FUNCTION_LOCATION); - emitRecord(I.Parent, FUNCTION_PARENT); + emitBlock(I.Parent, FieldId::F_parent); emitBlock(I.ReturnType); for (const auto &N : I.Params) emitBlock(N); Index: clang-doc/Representation.h =================================================================== --- clang-doc/Representation.h +++ clang-doc/Representation.h @@ -30,11 +30,11 @@ struct Info; enum class InfoType { + IT_default, IT_namespace, IT_record, IT_function, - IT_enum, - IT_default + IT_enum }; // A representation of a parsed comment. @@ -42,13 +42,13 @@ CommentInfo() = default; CommentInfo(CommentInfo &&Other) : Children(std::move(Other.Children)) {} - SmallString<16> - Kind; // Kind of comment (TextComment, InlineCommandComment, - // HTMLStartTagComment, HTMLEndTagComment, BlockCommandComment, - // ParamCommandComment, TParamCommandComment, VerbatimBlockComment, - // VerbatimBlockLineComment, VerbatimLineComment). - SmallString<64> Text; // Text of the comment. - SmallString<16> Name; // Name of the comment (for Verbatim and HTML). + SmallString<16> Kind; // Kind of comment (TextComment, InlineCommandComment, + // HTMLStartTagComment, HTMLEndTagComment, + // BlockCommandComment, ParamCommandComment, + // TParamCommandComment, VerbatimBlockComment, + // VerbatimBlockLineComment, VerbatimLineComment). + SmallString<64> Text; // Text of the comment. + SmallString<16> Name; // Name of the comment (for Verbatim and HTML). SmallString<8> Direction; // Parameter direction (for (T)ParamCommand). SmallString<16> ParamName; // Parameter name (for (T)ParamCommand). SmallString<16> CloseName; // Closing tag name (for VerbatimBlock). @@ -67,20 +67,22 @@ struct Reference { Reference() = default; - Reference(llvm::StringRef Name) : UnresolvedName(Name) {} - Reference(SymbolID USR, InfoType IT) : USR(USR), RefType(IT) {} - - SymbolID USR; // Unique identifer for referenced decl - SmallString<16> UnresolvedName; // Name of unresolved type. - InfoType RefType = - InfoType::IT_default; // Indicates the type of this Reference (namespace, - // record, function, enum, default). + Reference(llvm::StringRef Name) : Name(Name) {} + Reference(SymbolID USR, StringRef Name, InfoType IT) + : USR(USR), Name(Name), RefType(IT) {} + + SymbolID USR = SymbolID(); // Unique identifer for referenced decl + SmallString<16> Name; // Name of type (possibly unresolved). + InfoType RefType = InfoType::IT_default; // Indicates the type of this + // Reference (namespace, record, + // function, enum, default). }; // A base struct for TypeInfos struct TypeInfo { TypeInfo() = default; - TypeInfo(SymbolID &Type, InfoType IT) : Type(Type, IT) {} + TypeInfo(SymbolID Type, StringRef Field, InfoType IT) + : Type(Type, Field, IT) {} TypeInfo(llvm::StringRef RefName) : Type(RefName) {} Reference Type; // Referenced type in this info. @@ -89,8 +91,9 @@ // Info for field types. struct FieldTypeInfo : public TypeInfo { FieldTypeInfo() = default; - FieldTypeInfo(SymbolID &Type, InfoType IT, llvm::StringRef Name) - : TypeInfo(Type, IT), Name(Name) {} + FieldTypeInfo(SymbolID Type, StringRef Field, InfoType IT, + llvm::StringRef Name) + : TypeInfo(Type, Field, IT), Name(Name) {} FieldTypeInfo(llvm::StringRef RefName, llvm::StringRef Name) : TypeInfo(RefName), Name(Name) {} @@ -100,15 +103,17 @@ // Info for member types. struct MemberTypeInfo : public FieldTypeInfo { MemberTypeInfo() = default; - MemberTypeInfo(SymbolID &Type, InfoType IT, llvm::StringRef Name) - : FieldTypeInfo(Type, IT, Name) {} - MemberTypeInfo(llvm::StringRef RefName, llvm::StringRef Name) - : FieldTypeInfo(RefName, Name) {} - - AccessSpecifier Access = - clang::AccessSpecifier::AS_none; // Access level associated with this - // info (public, protected, private, - // none). + MemberTypeInfo(SymbolID Type, StringRef Field, InfoType IT, + llvm::StringRef Name, AccessSpecifier Access) + : FieldTypeInfo(Type, Field, IT, Name), Access(Access) {} + MemberTypeInfo(llvm::StringRef RefName, llvm::StringRef Name, + AccessSpecifier Access) + : FieldTypeInfo(RefName, Name), Access(Access) {} + + AccessSpecifier Access = AccessSpecifier::AS_none; // Access level associated + // with this info (public, + // protected, private, + // none). }; struct Location { @@ -148,10 +153,10 @@ bool IsMethod = false; // Indicates whether this function is a class method. Reference Parent; // Reference to the parent class decl for this method. TypeInfo ReturnType; // Info about the return type of this function. - llvm::SmallVector Params; // List of parameters. - AccessSpecifier Access = - AccessSpecifier::AS_none; // Access level for this method (public, - // private, protected, none). + llvm::SmallVector Params; // List of parameters. + AccessSpecifier Access = AccessSpecifier::AS_none; // Access level for this + // method (public, private, + // protected, none). }; // TODO: Expand to allow for documenting templating, inheritance access, Index: clang-doc/Serialize.cpp =================================================================== --- clang-doc/Serialize.cpp +++ clang-doc/Serialize.cpp @@ -173,21 +173,23 @@ static void parseFields(RecordInfo &I, const RecordDecl *D) { for (const FieldDecl *F : D->fields()) { - // FIXME: Set Access to the appropriate value. - SymbolID Type; - std::string Name; - InfoType RefType; if (const auto *T = getDeclForType(F->getTypeSourceInfo()->getType())) { - Type = getUSRForDecl(T); - if (dyn_cast(T)) - RefType = InfoType::IT_enum; - else if (dyn_cast(T)) - RefType = InfoType::IT_record; - I.Members.emplace_back(Type, RefType, F->getQualifiedNameAsString()); - } else { - Name = F->getTypeSourceInfo()->getType().getAsString(); - I.Members.emplace_back(Name, F->getQualifiedNameAsString()); + // Use getAccessUnsafe so that we just get the default AS_none if it's not + // valid, as opposed to an assert. + if (const auto *N = dyn_cast(T)) { + I.Members.emplace_back(getUSRForDecl(T), N->getNameAsString(), + InfoType::IT_enum, F->getNameAsString(), + N->getAccessUnsafe()); + continue; + } else if (const auto *N = dyn_cast(T)) { + I.Members.emplace_back(getUSRForDecl(T), N->getNameAsString(), + InfoType::IT_record, F->getNameAsString(), + N->getAccessUnsafe()); + continue; + } } + I.Members.emplace_back(F->getTypeSourceInfo()->getType().getAsString(), + F->getNameAsString(), F->getAccessUnsafe()); } } @@ -198,20 +200,19 @@ static void parseParameters(FunctionInfo &I, const FunctionDecl *D) { for (const ParmVarDecl *P : D->parameters()) { - SymbolID Type; - std::string Name; - InfoType RefType; if (const auto *T = getDeclForType(P->getOriginalType())) { - Type = getUSRForDecl(T); - if (dyn_cast(T)) - RefType = InfoType::IT_enum; - else if (dyn_cast(T)) - RefType = InfoType::IT_record; - I.Params.emplace_back(Type, RefType, P->getQualifiedNameAsString()); - } else { - Name = P->getOriginalType().getAsString(); - I.Params.emplace_back(Name, P->getQualifiedNameAsString()); + if (const auto *N = dyn_cast(T)) { + I.Params.emplace_back(getUSRForDecl(N), N->getNameAsString(), + InfoType::IT_enum, P->getNameAsString()); + continue; + } else if (const auto *N = dyn_cast(T)) { + I.Params.emplace_back(getUSRForDecl(N), N->getNameAsString(), + InfoType::IT_record, P->getNameAsString()); + continue; + } } + I.Params.emplace_back(P->getOriginalType().getAsString(), + P->getNameAsString()); } } @@ -220,13 +221,15 @@ if (B.isVirtual()) continue; if (const auto *P = getDeclForType(B.getType())) - I.Parents.emplace_back(getUSRForDecl(P), InfoType::IT_record); + I.Parents.emplace_back(getUSRForDecl(P), P->getNameAsString(), + InfoType::IT_record); else I.Parents.emplace_back(B.getType().getAsString()); } for (const CXXBaseSpecifier &B : D->vbases()) { if (const auto *P = getDeclForType(B.getType())) - I.VirtualParents.emplace_back(getUSRForDecl(P), InfoType::IT_record); + I.VirtualParents.emplace_back(getUSRForDecl(P), P->getNameAsString(), + InfoType::IT_record); else I.VirtualParents.emplace_back(B.getType().getAsString()); } @@ -239,13 +242,17 @@ const auto *DC = dyn_cast(D); while ((DC = DC->getParent())) { if (const auto *N = dyn_cast(DC)) - Namespaces.emplace_back(getUSRForDecl(N), InfoType::IT_namespace); + Namespaces.emplace_back(getUSRForDecl(N), N->getNameAsString(), + InfoType::IT_namespace); else if (const auto *N = dyn_cast(DC)) - Namespaces.emplace_back(getUSRForDecl(N), InfoType::IT_record); + Namespaces.emplace_back(getUSRForDecl(N), N->getNameAsString(), + InfoType::IT_record); else if (const auto *N = dyn_cast(DC)) - Namespaces.emplace_back(getUSRForDecl(N), InfoType::IT_function); + Namespaces.emplace_back(getUSRForDecl(N), N->getNameAsString(), + InfoType::IT_function); else if (const auto *N = dyn_cast(DC)) - Namespaces.emplace_back(getUSRForDecl(N), InfoType::IT_enum); + Namespaces.emplace_back(getUSRForDecl(N), N->getNameAsString(), + InfoType::IT_enum); } } @@ -275,13 +282,14 @@ StringRef Filename) { populateSymbolInfo(I, D, FC, LineNumber, Filename); if (const auto *T = getDeclForType(D->getReturnType())) { - I.ReturnType.Type.USR = getUSRForDecl(T); if (dyn_cast(T)) - I.ReturnType.Type.RefType = InfoType::IT_enum; + I.ReturnType = + TypeInfo(getUSRForDecl(T), T->getNameAsString(), InfoType::IT_enum); else if (dyn_cast(T)) - I.ReturnType.Type.RefType = InfoType::IT_record; + I.ReturnType = + TypeInfo(getUSRForDecl(T), T->getNameAsString(), InfoType::IT_record); } else { - I.ReturnType.Type.UnresolvedName = D->getReturnType().getAsString(); + I.ReturnType = TypeInfo(D->getReturnType().getAsString()); } parseParameters(I, D); } @@ -317,7 +325,8 @@ FunctionInfo I; populateFunctionInfo(I, D, FC, LineNumber, File); I.IsMethod = true; - I.Parent = Reference(getUSRForDecl(D->getParent()), InfoType::IT_record); + I.Parent = Reference{getUSRForDecl(D->getParent()), + D->getParent()->getNameAsString(), InfoType::IT_record}; I.Access = D->getAccess(); return serialize(I); } Index: test/clang-doc/mapper-class-in-class.cpp =================================================================== --- test/clang-doc/mapper-class-in-class.cpp +++ test/clang-doc/mapper-class-in-class.cpp @@ -12,24 +12,29 @@ // CHECK-X: // CHECK-X-NEXT: - // CHECK-X-NEXT: + // CHECK-X-NEXT: // CHECK-X-NEXT: // CHECK-X-NEXT: // CHECK-X-NEXT: // CHECK-X-NEXT: blob data = 'X' - // CHECK-X-NEXT: blob data = '{{.*}}' - // CHECK-X-NEXT: + // CHECK-X-NEXT: blob data = '{{.*}}' + // CHECK-X-NEXT: // CHECK-X-NEXT: // CHECK-X-Y: // CHECK-X-Y-NEXT: - // CHECK-X-Y-NEXT: + // CHECK-X-Y-NEXT: // CHECK-X-Y-NEXT: // CHECK-X-Y-NEXT: // CHECK-X-Y-NEXT: // CHECK-X-Y-NEXT: blob data = 'Y' - // CHECK-X-Y-NEXT: blob data = 'CA7C7935730B5EACD25F080E9C83FA087CCDC75E' - // CHECK-X-Y-NEXT: blob data = '{{.*}}' - // CHECK-X-Y-NEXT: + // CHECK-X-Y-NEXT: + // CHECK-X-Y-NEXT: + // CHECK-X-Y-NEXT: blob data = 'X' + // CHECK-X-Y-NEXT: + // CHECK-X-Y-NEXT: + // CHECK-X-Y-NEXT: + // CHECK-X-Y-NEXT: blob data = '{{.*}}' + // CHECK-X-Y-NEXT: // CHECK-X-Y-NEXT: Index: test/clang-doc/mapper-class-in-function.cpp =================================================================== --- test/clang-doc/mapper-class-in-function.cpp +++ test/clang-doc/mapper-class-in-function.cpp @@ -15,27 +15,35 @@ // CHECK-H: // CHECK-H-NEXT: - // CHECK-H-NEXT: + // CHECK-H-NEXT: // CHECK-H-NEXT: // CHECK-H-NEXT: // CHECK-H-NEXT: // CHECK-H-NEXT: blob data = 'H' - // CHECK-H-NEXT: blob data = '{{.*}}' - // CHECK-H-NEXT: - // CHECK-H-NEXT: blob data = 'void' + // CHECK-H-NEXT: blob data = '{{.*}}' + // CHECK-H-NEXT: + // CHECK-H-NEXT: + // CHECK-H-NEXT: blob data = 'void' + // CHECK-H-NEXT: + // CHECK-H-NEXT: // CHECK-H-NEXT: // CHECK-H-NEXT: // CHECK-H-I: // CHECK-H-I-NEXT: - // CHECK-H-I-NEXT: + // CHECK-H-I-NEXT: // CHECK-H-I-NEXT: // CHECK-H-I-NEXT: // CHECK-H-I-NEXT: // CHECK-H-I-NEXT: blob data = 'I' - // CHECK-H-I-NEXT: blob data = 'B6AC4C5C9F2EA3F2B3ECE1A33D349F4EE502B24E' - // CHECK-H-I-NEXT: blob data = '{{.*}}' - // CHECK-H-I-NEXT: + // CHECK-H-I-NEXT: + // CHECK-H-I-NEXT: + // CHECK-H-I-NEXT: blob data = 'H' + // CHECK-H-I-NEXT: + // CHECK-H-I-NEXT: + // CHECK-H-I-NEXT: + // CHECK-H-I-NEXT: blob data = '{{.*}}' + // CHECK-H-I-NEXT: // CHECK-H-I-NEXT: Index: test/clang-doc/mapper-class.cpp =================================================================== --- test/clang-doc/mapper-class.cpp +++ test/clang-doc/mapper-class.cpp @@ -9,11 +9,11 @@ // CHECK: // CHECK-NEXT: - // CHECK-NEXT: + // CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: blob data = 'E' - // CHECK-NEXT: blob data = '{{.*}}' - // CHECK-NEXT: + // CHECK-NEXT: blob data = '{{.*}}' + // CHECK-NEXT: // CHECK-NEXT: Index: test/clang-doc/mapper-comments.cpp =================================================================== --- test/clang-doc/mapper-comments.cpp +++ test/clang-doc/mapper-comments.cpp @@ -25,7 +25,7 @@ // CHECK: // CHECK-NEXT: - // CHECK-NEXT: + // CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: @@ -157,16 +157,25 @@ // CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: - // CHECK-NEXT: blob data = '{{.*}}' - // CHECK-NEXT: - // CHECK-NEXT: blob data = 'int' + // CHECK-NEXT: blob data = '{{.*}}' + // CHECK-NEXT: + // CHECK-NEXT: + // CHECK-NEXT: blob data = 'int' + // CHECK-NEXT: + // CHECK-NEXT: // CHECK-NEXT: - // CHECK-NEXT: - // CHECK-NEXT: blob data = 'int' - // CHECK-NEXT: blob data = 'I' + // CHECK-NEXT: + // CHECK-NEXT: + // CHECK-NEXT: blob data = 'int' + // CHECK-NEXT: + // CHECK-NEXT: + // CHECK-NEXT: blob data = 'I' // CHECK-NEXT: - // CHECK-NEXT: - // CHECK-NEXT: blob data = 'int' - // CHECK-NEXT: blob data = 'J' + // CHECK-NEXT: + // CHECK-NEXT: + // CHECK-NEXT: blob data = 'int' + // CHECK-NEXT: + // CHECK-NEXT: + // CHECK-NEXT: blob data = 'J' // CHECK-NEXT: // CHECK-NEXT: Index: test/clang-doc/mapper-enum.cpp =================================================================== --- test/clang-doc/mapper-enum.cpp +++ test/clang-doc/mapper-enum.cpp @@ -10,27 +10,27 @@ // CHECK-B: // CHECK-B-NEXT: - // CHECK-B-NEXT: + // CHECK-B-NEXT: // CHECK-B-NEXT: // CHECK-B-NEXT: // CHECK-B-NEXT: // CHECK-B-NEXT: blob data = 'B' - // CHECK-B-NEXT: blob data = '{{.*}}' - // CHECK-B-NEXT: blob data = 'X' - // CHECK-B-NEXT: blob data = 'Y' + // CHECK-B-NEXT: blob data = '{{.*}}' + // CHECK-B-NEXT: blob data = 'X' + // CHECK-B-NEXT: blob data = 'Y' // CHECK-B-NEXT: enum class C { A, B }; // CHECK-C: // CHECK-C-NEXT: - // CHECK-C-NEXT: + // CHECK-C-NEXT: // CHECK-C-NEXT: // CHECK-C-NEXT: // CHECK-C-NEXT: // CHECK-C-NEXT: blob data = 'C' - // CHECK-C-NEXT: blob data = '{{.*}}' - // CHECK-C-NEXT: - // CHECK-C-NEXT: blob data = 'A' - // CHECK-C-NEXT: blob data = 'B' + // CHECK-C-NEXT: blob data = '{{.*}}' + // CHECK-C-NEXT: + // CHECK-C-NEXT: blob data = 'A' + // CHECK-C-NEXT: blob data = 'B' // CHECK-C-NEXT: Index: test/clang-doc/mapper-function.cpp =================================================================== --- test/clang-doc/mapper-function.cpp +++ test/clang-doc/mapper-function.cpp @@ -9,17 +9,23 @@ // CHECK: // CHECK-NEXT: - // CHECK-NEXT: + // CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: blob data = 'F' - // CHECK-NEXT: blob data = '{{.*}}' - // CHECK-NEXT: - // CHECK-NEXT: blob data = 'int' + // CHECK-NEXT: blob data = '{{.*}}' + // CHECK-NEXT: + // CHECK-NEXT: + // CHECK-NEXT: blob data = 'int' + // CHECK-NEXT: + // CHECK-NEXT: // CHECK-NEXT: - // CHECK-NEXT: - // CHECK-NEXT: blob data = 'int' - // CHECK-NEXT: blob data = 'param' + // CHECK-NEXT: + // CHECK-NEXT: + // CHECK-NEXT: blob data = 'int' + // CHECK-NEXT: + // CHECK-NEXT: + // CHECK-NEXT: blob data = 'param' // CHECK-NEXT: // CHECK-NEXT: Index: test/clang-doc/mapper-method.cpp =================================================================== --- test/clang-doc/mapper-method.cpp +++ test/clang-doc/mapper-method.cpp @@ -13,31 +13,47 @@ // CHECK-G: // CHECK-G-NEXT: - // CHECK-G-NEXT: + // CHECK-G-NEXT: // CHECK-G-NEXT: // CHECK-G-NEXT: // CHECK-G-NEXT: // CHECK-G-NEXT: blob data = 'G' - // CHECK-G-NEXT: blob data = '{{.*}}' - // CHECK-G-NEXT: + // CHECK-G-NEXT: blob data = '{{.*}}' + // CHECK-G-NEXT: // CHECK-G-NEXT: // CHECK-G-F: // CHECK-G-F-NEXT: - // CHECK-G-F-NEXT: + // CHECK-G-F-NEXT: // CHECK-G-F-NEXT: // CHECK-G-F-NEXT: // CHECK-G-F-NEXT: // CHECK-G-F-NEXT: blob data = 'Method' - // CHECK-G-F-NEXT: blob data = '4202E8BF0ECB12AE354C8499C52725B0EE30AED5' - // CHECK-G-F-NEXT: - // CHECK-G-F-NEXT: blob data = '{{.*}}' - // CHECK-G-F-NEXT: blob data = '4202E8BF0ECB12AE354C8499C52725B0EE30AED5' - // CHECK-G-F-NEXT: - // CHECK-G-F-NEXT: blob data = 'int' + // CHECK-G-F-NEXT: + // CHECK-G-F-NEXT: + // CHECK-G-F-NEXT: blob data = 'G' + // CHECK-G-F-NEXT: + // CHECK-G-F-NEXT: + // CHECK-G-F-NEXT: + // CHECK-G-F-NEXT: + // CHECK-G-F-NEXT: blob data = '{{.*}}' + // CHECK-G-F-NEXT: + // CHECK-G-F-NEXT: + // CHECK-G-F-NEXT: blob data = 'G' + // CHECK-G-F-NEXT: + // CHECK-G-F-NEXT: + // CHECK-G-F-NEXT: + // CHECK-G-F-NEXT: + // CHECK-G-F-NEXT: + // CHECK-G-F-NEXT: blob data = 'int' + // CHECK-G-F-NEXT: + // CHECK-G-F-NEXT: // CHECK-G-F-NEXT: - // CHECK-G-F-NEXT: - // CHECK-G-F-NEXT: blob data = 'int' - // CHECK-G-F-NEXT: blob data = 'param' + // CHECK-G-F-NEXT: + // CHECK-G-F-NEXT: + // CHECK-G-F-NEXT: blob data = 'int' + // CHECK-G-F-NEXT: + // CHECK-G-F-NEXT: + // CHECK-G-F-NEXT: blob data = 'param' // CHECK-G-F-NEXT: // CHECK-G-F-NEXT: Index: test/clang-doc/mapper-namespace.cpp =================================================================== --- test/clang-doc/mapper-namespace.cpp +++ test/clang-doc/mapper-namespace.cpp @@ -9,7 +9,7 @@ // CHECK: // CHECK-NEXT: - // CHECK-NEXT: + // CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: Index: test/clang-doc/mapper-struct.cpp =================================================================== --- test/clang-doc/mapper-struct.cpp +++ test/clang-doc/mapper-struct.cpp @@ -9,15 +9,17 @@ // CHECK: // CHECK-NEXT: - // CHECK-NEXT: + // CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: blob data = 'C' - // CHECK-NEXT: blob data = '{{.*}}' - // CHECK-NEXT: - // CHECK-NEXT: blob data = 'int' - // CHECK-NEXT: blob data = 'C::i' - // CHECK-NEXT: + // CHECK-NEXT: blob data = '{{.*}}' + // CHECK-NEXT: + // CHECK-NEXT: + // CHECK-NEXT: blob data = 'int' + // CHECK-NEXT: + // CHECK-NEXT: + // CHECK-NEXT: blob data = 'i' // CHECK-NEXT: // CHECK-NEXT: Index: test/clang-doc/mapper-union.cpp =================================================================== --- test/clang-doc/mapper-union.cpp +++ test/clang-doc/mapper-union.cpp @@ -9,21 +9,25 @@ // CHECK: // CHECK-NEXT: - // CHECK-NEXT: + // CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: blob data = 'D' - // CHECK-NEXT: blob data = '{{.*}}' - // CHECK-NEXT: - // CHECK-NEXT: - // CHECK-NEXT: blob data = 'int' - // CHECK-NEXT: blob data = 'D::X' - // CHECK-NEXT: + // CHECK-NEXT: blob data = '{{.*}}' + // CHECK-NEXT: + // CHECK-NEXT: + // CHECK-NEXT: + // CHECK-NEXT: blob data = 'int' + // CHECK-NEXT: + // CHECK-NEXT: + // CHECK-NEXT: blob data = 'X' // CHECK-NEXT: - // CHECK-NEXT: - // CHECK-NEXT: blob data = 'int' - // CHECK-NEXT: blob data = 'D::Y' - // CHECK-NEXT: + // CHECK-NEXT: + // CHECK-NEXT: + // CHECK-NEXT: blob data = 'int' + // CHECK-NEXT: + // CHECK-NEXT: + // CHECK-NEXT: blob data = 'Y' // CHECK-NEXT: // CHECK-NEXT: