Index: clang-tools-extra/clang-doc/BitcodeReader.h =================================================================== --- clang-tools-extra/clang-doc/BitcodeReader.h +++ clang-tools-extra/clang-doc/BitcodeReader.h @@ -19,6 +19,7 @@ #include "BitcodeWriter.h" #include "Representation.h" #include "clang/AST/AST.h" +#include "llvm/ADT/Optional.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Bitcode/BitstreamReader.h" @@ -31,7 +32,7 @@ ClangDocBitcodeReader(llvm::BitstreamCursor &Stream) : Stream(Stream) {} // Main entry point, calls readBlock to read each block in the given stream. - std::vector> readBitcode(); + llvm::Expected>> readBitcode(); private: enum class Cursor { BadBlock = 1, Record, BlockEnd, BlockBegin }; Index: clang-tools-extra/clang-doc/BitcodeReader.cpp =================================================================== --- clang-tools-extra/clang-doc/BitcodeReader.cpp +++ clang-tools-extra/clang-doc/BitcodeReader.cpp @@ -100,6 +100,8 @@ case FieldId::F_parent: case FieldId::F_vparent: case FieldId::F_type: + case FieldId::F_child_namespace: + case FieldId::F_child_record: case FieldId::F_default: Field = F; return true; @@ -372,6 +374,12 @@ case FieldId::F_namespace: I->Namespace.emplace_back(std::move(R)); break; + case FieldId::F_child_namespace: + I->ChildNamespaces.emplace_back(std::move(R)); + break; + case FieldId::F_child_record: + I->ChildRecords.emplace_back(std::move(R)); + break; default: llvm::errs() << "Invalid field type for info.\n"; exit(1); @@ -403,12 +411,39 @@ case FieldId::F_vparent: I->VirtualParents.emplace_back(std::move(R)); break; + case FieldId::F_child_namespace: + I->ChildNamespaces.emplace_back(std::move(R)); + break; + case FieldId::F_child_record: + I->ChildRecords.emplace_back(std::move(R)); + break; default: llvm::errs() << "Invalid field type for info.\n"; exit(1); } } +template void addChild(T I, ChildInfoType &&R) { + llvm::errs() << "Invalid child type for info.\n"; + exit(1); +} + +template <> void addChild(NamespaceInfo *I, FunctionInfo &&R) { + I->ChildFunctions.emplace_back(std::move(R)); +} + +template <> void addChild(NamespaceInfo *I, EnumInfo &&R) { + I->ChildEnums.emplace_back(std::move(R)); +} + +template <> void addChild(RecordInfo *I, FunctionInfo &&R) { + I->ChildFunctions.emplace_back(std::move(R)); +} + +template <> void addChild(RecordInfo *I, EnumInfo &&R) { + I->ChildEnums.emplace_back(std::move(R)); +} + // Read records from bitcode into a given info. template bool ClangDocBitcodeReader::readRecord(unsigned ID, T I) { Record R; @@ -455,7 +490,7 @@ template bool ClangDocBitcodeReader::readSubBlock(unsigned ID, T I) { switch (ID) { - // Blocks can only have Comment, Reference, or TypeInfo subblocks + // Blocks can only have Comment, Reference, TypeInfo, FunctionInfo, or EnumInfo subblocks case BI_COMMENT_BLOCK_ID: if (readBlock(ID, getCommentInfo(I))) return true; @@ -492,6 +527,22 @@ } return false; } + case BI_FUNCTION_BLOCK_ID: { + FunctionInfo F; + if (readBlock(ID, &F)) { + addChild(I, std::move(F)); + return true; + } + return false; + } + case BI_ENUM_BLOCK_ID: { + EnumInfo E; + if (readBlock(ID, &E)) { + addChild(I, std::move(E)); + return true; + } + return false; + } default: llvm::errs() << "Invalid subblock type.\n"; return false; @@ -573,16 +624,20 @@ } // Entry point -std::vector> ClangDocBitcodeReader::readBitcode() { +llvm::Expected>> ClangDocBitcodeReader::readBitcode() { std::vector> Infos; if (!validateStream()) - return Infos; + return llvm::make_error( + "Invalid bitcode stream.\n", + llvm::inconvertibleErrorCode());; // Read the top level blocks. while (!Stream.AtEndOfStream()) { unsigned Code = Stream.ReadCode(); if (Code != llvm::bitc::ENTER_SUBBLOCK) - return Infos; + return llvm::make_error( + "Missing subblock in bitcode.\n", + llvm::inconvertibleErrorCode());; unsigned ID = Stream.ReadSubBlockID(); switch (ID) { @@ -592,24 +647,28 @@ case BI_MEMBER_TYPE_BLOCK_ID: case BI_COMMENT_BLOCK_ID: case BI_REFERENCE_BLOCK_ID: - llvm::errs() << "Invalid top level block.\n"; - return Infos; + return llvm::make_error( + "Invalid top level block in bitcode.\n", + llvm::inconvertibleErrorCode());; case BI_NAMESPACE_BLOCK_ID: case BI_RECORD_BLOCK_ID: case BI_ENUM_BLOCK_ID: case BI_FUNCTION_BLOCK_ID: - if (std::unique_ptr I = readBlockToInfo(ID)) { + if (std::unique_ptr I = readBlockToInfo(ID)) Infos.emplace_back(std::move(I)); - } return Infos; case BI_VERSION_BLOCK_ID: if (readBlock(ID, VersionNumber)) continue; - return Infos; + return llvm::make_error( + "Invalid bitcode version in bitcode.\n", + llvm::inconvertibleErrorCode());; case llvm::bitc::BLOCKINFO_BLOCK_ID: if (readBlockInfoBlock()) continue; - return Infos; + return llvm::make_error( + "Invalid BlockInfo in bitcode.\n", + llvm::inconvertibleErrorCode());; default: if (!Stream.SkipBlock()) continue; Index: clang-tools-extra/clang-doc/BitcodeWriter.h =================================================================== --- clang-tools-extra/clang-doc/BitcodeWriter.h +++ clang-tools-extra/clang-doc/BitcodeWriter.h @@ -68,11 +68,10 @@ // 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 - enum RecordId { VERSION = 1, - INFORECORDS(FUNCTION), + FUNCTION_USR, + FUNCTION_NAME, FUNCTION_DEFLOCATION, FUNCTION_LOCATION, FUNCTION_ACCESS, @@ -91,13 +90,16 @@ FIELD_TYPE_NAME, MEMBER_TYPE_NAME, MEMBER_TYPE_ACCESS, - INFORECORDS(NAMESPACE), - INFORECORDS(ENUM), + NAMESPACE_USR, + NAMESPACE_NAME, + ENUM_USR, + ENUM_NAME, ENUM_DEFLOCATION, ENUM_LOCATION, ENUM_MEMBER, ENUM_SCOPED, - INFORECORDS(RECORD), + RECORD_USR, + RECORD_NAME, RECORD_DEFLOCATION, RECORD_LOCATION, RECORD_TAG_TYPE, @@ -112,10 +114,8 @@ 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_default, F_namespace, F_parent, F_vparent, F_type }; +enum class FieldId { F_default, F_namespace, F_parent, F_vparent, F_type, F_child_namespace, F_child_record }; class ClangDocBitcodeWriter { public: Index: clang-tools-extra/clang-doc/BitcodeWriter.cpp =================================================================== --- clang-tools-extra/clang-doc/BitcodeWriter.cpp +++ clang-tools-extra/clang-doc/BitcodeWriter.cpp @@ -434,6 +434,14 @@ emitBlock(N, FieldId::F_namespace); for (const auto &CI : I.Description) emitBlock(CI); + for (const auto &C : I.ChildNamespaces) + emitBlock(C, FieldId::F_child_namespace); + for (const auto &C : I.ChildRecords) + emitBlock(C, FieldId::F_child_record); + for (const auto &C : I.ChildFunctions) + emitBlock(C); + for (const auto &C : I.ChildEnums) + emitBlock(C); } void ClangDocBitcodeWriter::emitBlock(const EnumInfo &I) { @@ -472,6 +480,14 @@ emitBlock(P, FieldId::F_parent); for (const auto &P : I.VirtualParents) emitBlock(P, FieldId::F_vparent); + for (const auto &C : I.ChildNamespaces) + emitBlock(C, FieldId::F_child_namespace); + for (const auto &C : I.ChildRecords) + emitBlock(C, FieldId::F_child_record); + for (const auto &C : I.ChildFunctions) + emitBlock(C); + for (const auto &C : I.ChildEnums) + emitBlock(C); } void ClangDocBitcodeWriter::emitBlock(const FunctionInfo &I) { Index: clang-tools-extra/clang-doc/ClangDoc.h =================================================================== --- clang-tools-extra/clang-doc/ClangDoc.h +++ clang-tools-extra/clang-doc/ClangDoc.h @@ -17,9 +17,11 @@ #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_DOC_CLANGDOC_H #define LLVM_CLANG_TOOLS_EXTRA_CLANG_DOC_CLANGDOC_H +#include "Representation.h" #include "clang/Tooling/Execution.h" #include "clang/Tooling/StandaloneExecution.h" #include "clang/Tooling/Tooling.h" +#include "llvm/Support/Error.h" namespace clang { namespace doc { @@ -27,6 +29,9 @@ std::unique_ptr newMapperActionFactory(tooling::ExecutionContext *ECtx); +llvm::Error mapByEnclosingScope(std::unique_ptr &&I, + tooling::ToolResults &Results); + } // namespace doc } // namespace clang Index: clang-tools-extra/clang-doc/ClangDoc.cpp =================================================================== --- clang-tools-extra/clang-doc/ClangDoc.cpp +++ clang-tools-extra/clang-doc/ClangDoc.cpp @@ -15,6 +15,7 @@ #include "ClangDoc.h" #include "Mapper.h" +#include "Serialize.h" #include "clang/AST/AST.h" #include "clang/AST/ASTConsumer.h" #include "clang/AST/ASTContext.h" @@ -57,5 +58,72 @@ return llvm::make_unique(ECtx); } +llvm::Error addInfoToResults(std::unique_ptr &&I, + StringRef EnclosingScopeKey, + InfoType EnclosingScopeType, + tooling::ToolResults &Results) { + // Add this info to the enclosing scope's key. + auto Enclosing = wrapInfoInEnclosingType(EnclosingScopeType, std::move(I)); + if (!Enclosing) + return Enclosing.takeError(); + Results.addResult(EnclosingScopeKey, serialize::serialize(Enclosing.get())); + return llvm::Error::success(); +} + +template +llvm::Error +addRefToResults(std::unique_ptr &&I, StringRef EnclosingScopeKey, + InfoType EnclosingScopeType, tooling::ToolResults &Results) { + // Add a reference to this info to the enclosing scope's key. + std::unique_ptr Ref = llvm::make_unique(I->USR, I->Name); + auto Enclosing = wrapInfoInEnclosingType(EnclosingScopeType, std::move(Ref)); + if (!Enclosing) + return Enclosing.takeError(); + Results.addResult(EnclosingScopeKey, serialize::serialize(Enclosing.get())); + + // Add this info to its own key. + Results.addResult(llvm::toHex(llvm::toStringRef(I->USR)), + serialize::serialize(I)); + return llvm::Error::success(); +} + +llvm::Error mapByEnclosingScope(std::unique_ptr &&I, + tooling::ToolResults &Results) { + // Get the enclosing scope of this decl. + auto EnclosingScope = I->getEnclosingScope(); + if (!EnclosingScope) + return EnclosingScope.takeError(); + + // Pass over things declared internally to functions. + // FIXME: Do this in the initial mapping phase and return an error here. + if (EnclosingScope.get().RefType == doc::InfoType::IT_function) + return llvm::Error::success(); + + std::string EnclosingScopeKey; + // An enclosing scope has an empty USR if it's the global namespace. + if (EnclosingScope.get().USR == doc::SymbolID()) + EnclosingScopeKey = "Global"; + else + EnclosingScopeKey = + llvm::toHex(llvm::toStringRef(EnclosingScope.get().USR)); + + switch (I->IT) { + case doc::InfoType::IT_namespace: + return addRefToResults( + std::move(I), EnclosingScopeKey, EnclosingScope.get().RefType, Results); + case doc::InfoType::IT_record: + return addRefToResults(std::move(I), EnclosingScopeKey, + EnclosingScope.get().RefType, Results); + case doc::InfoType::IT_enum: + case doc::InfoType::IT_function: + return addInfoToResults(std::move(I), EnclosingScopeKey, + EnclosingScope.get().RefType, Results); + default: + return llvm::make_error( + "Unexpected type in mapping by enclosing scope.\n", + llvm::inconvertibleErrorCode()); + } +} + } // namespace doc } // namespace clang Index: clang-tools-extra/clang-doc/Representation.h =================================================================== --- clang-tools-extra/clang-doc/Representation.h +++ clang-tools-extra/clang-doc/Representation.h @@ -30,6 +30,9 @@ using SymbolID = std::array; struct Info; +struct FunctionInfo; +struct EnumInfo; + enum class InfoType { IT_default, IT_namespace, @@ -151,6 +154,8 @@ /// A base struct for Infos. struct Info { Info() = default; + Info(InfoType IT, SymbolID USR, StringRef Name) + : USR(USR), IT(IT), Name(Name) {} Info(InfoType IT) : IT(IT) {} Info(const Info &Other) = delete; Info(Info &&Other) = default; @@ -165,18 +170,30 @@ void mergeBase(Info &&I); bool mergeable(const Info &Other); + + // Returns a reference to the parent scope (that is, the immediate parent + // namespace or class in which this decl resides). + llvm::Expected getEnclosingScope(); }; // Info for namespaces. struct NamespaceInfo : public Info { NamespaceInfo() : Info(InfoType::IT_namespace) {} + NamespaceInfo(SymbolID USR, StringRef Name) + : Info(InfoType::IT_namespace, USR, Name) {} void merge(NamespaceInfo &&I); + + std::vector ChildNamespaces; + std::vector ChildRecords; + std::vector ChildFunctions; + std::vector ChildEnums; }; // Info for symbols. struct SymbolInfo : public Info { SymbolInfo(InfoType IT) : Info(IT) {} + SymbolInfo(InfoType IT, SymbolID USR, StringRef Name) : Info(IT, USR, Name) {} void merge(SymbolInfo &&I); @@ -204,6 +221,8 @@ // Info for types. struct RecordInfo : public SymbolInfo { RecordInfo() : SymbolInfo(InfoType::IT_record) {} + RecordInfo(SymbolID USR, StringRef Name) + : SymbolInfo(InfoType::IT_record, USR, Name) {} void merge(RecordInfo &&I); @@ -217,6 +236,11 @@ // parents). llvm::SmallVector VirtualParents; // List of virtual base/parent records. + + std::vector ChildNamespaces; + std::vector ChildRecords; + std::vector ChildFunctions; + std::vector ChildEnums; }; // TODO: Expand to allow for documenting templating. @@ -239,6 +263,26 @@ llvm::Expected> mergeInfos(std::vector> &Values); +// A function to wrap a reference in an Info of the appropriate +// enclosing scope. +// +// This takes a given info and the type of the decl scope in +// which it resides (that is, the immediate parent namespace or class in which +// it is declared). It returns an info of the type of the enclosing scope with +// the given info in the appropriate child list. +// +// Example: +// class Foo { +// void Bar() {}; +// } +// +// For the method Bar, the enclosing scope is class Foo. Passing the Bar +// FunctionInfo and the enclosing type 'class' to this function would return a +// RecordInfo with the Bar functionInfo in the ChildFunctions field. This allows +// for the child to be merged into the parent's info structure. +llvm::Expected> +wrapInfoInEnclosingType(InfoType EnclosingType, std::unique_ptr &&Info); + } // namespace doc } // namespace clang Index: clang-tools-extra/clang-doc/Representation.cpp =================================================================== --- clang-tools-extra/clang-doc/Representation.cpp +++ clang-tools-extra/clang-doc/Representation.cpp @@ -42,7 +42,7 @@ mergeInfos(std::vector> &Values) { if (Values.empty()) return llvm::make_error("No info values to merge.\n", - llvm::inconvertibleErrorCode()); + llvm::inconvertibleErrorCode()); switch (Values[0]->IT) { case InfoType::IT_namespace: @@ -59,6 +59,77 @@ } } +template +bool addInfoToEnclosing(T *Enclosing, std::unique_ptr &&I) { + switch (I->IT) { + case InfoType::IT_namespace: + Enclosing->ChildNamespaces.emplace_back(I->USR, I->Name, I->IT); + return true; + case InfoType::IT_record: + Enclosing->ChildRecords.emplace_back(I->USR, I->Name, I->IT); + return true; + case InfoType::IT_function: { + FunctionInfo *Info = static_cast(I.release()); + Enclosing->ChildFunctions.emplace_back(std::move(*Info)); + return true; + } + case InfoType::IT_enum: { + EnumInfo *Info = static_cast(I.release()); + Enclosing->ChildEnums.emplace_back(std::move(*Info)); + return true; + } + default: + return false; + } +} + +llvm::Expected> +wrapInfoInEnclosingType(InfoType EnclosingType, std::unique_ptr &&I) { + switch (EnclosingType) { + case InfoType::IT_namespace: { + std::unique_ptr EnclosingInfo = llvm::make_unique(); + NamespaceInfo *Enclosing = + static_cast(EnclosingInfo.get()); + if (!addInfoToEnclosing(Enclosing, std::move(I))) + return llvm::make_error( + "Unexpected reference type.\n", llvm::inconvertibleErrorCode()); + return EnclosingInfo; + } + case InfoType::IT_record: { + std::unique_ptr EnclosingInfo = llvm::make_unique(); + RecordInfo *Enclosing = static_cast(EnclosingInfo.get()); + if (!addInfoToEnclosing(Enclosing, std::move(I))) + return llvm::make_error( + "Unexpected reference type.\n", llvm::inconvertibleErrorCode()); + return EnclosingInfo; + } + default: + return llvm::make_error("Unexpected enclosing type.\n", + llvm::inconvertibleErrorCode()); + } +} + +llvm::Expected Info::getEnclosingScope() { + // If this is top level, the enclosing scope is the global namespace. + if (Namespace.empty()) { + auto R = Reference(); + R.RefType = InfoType::IT_namespace; + return R; + } + + switch (Namespace[0].RefType) { + // Enclosing scopes should only be namespaces, functions, or records. + case InfoType::IT_namespace: + case InfoType::IT_record: + case InfoType::IT_function: + return Namespace[0]; + case InfoType::IT_enum: + case InfoType::IT_default: + return llvm::make_error("Unexpected scope type.\n", + llvm::inconvertibleErrorCode()); + } +} + void Info::mergeBase(Info &&Other) { assert(mergeable(Other)); if (USR == EmptySID) @@ -67,13 +138,15 @@ Name = Other.Name; if (Namespace.empty()) Namespace = std::move(Other.Namespace); - // Unconditionally extend the description, since each decl may have a comment. + // Unconditionally extend the description, since each decl may have a + // comment. std::move(Other.Description.begin(), Other.Description.end(), std::back_inserter(Description)); } bool Info::mergeable(const Info &Other) { - return IT == Other.IT && (USR == EmptySID || USR == Other.USR); + return IT == Other.IT && + (USR == EmptySID || USR == Other.USR || Other.USR == EmptySID); } void SymbolInfo::merge(SymbolInfo &&Other) { @@ -87,6 +160,16 @@ void NamespaceInfo::merge(NamespaceInfo &&Other) { assert(mergeable(Other)); + // Unconditionally extend the children, since they're added after the + // initial reduce and therefore there can only be one. + std::move(Other.ChildNamespaces.begin(), Other.ChildNamespaces.end(), + std::back_inserter(ChildNamespaces)); + std::move(Other.ChildRecords.begin(), Other.ChildRecords.end(), + std::back_inserter(ChildRecords)); + std::move(Other.ChildFunctions.begin(), Other.ChildFunctions.end(), + std::back_inserter(ChildFunctions)); + std::move(Other.ChildEnums.begin(), Other.ChildEnums.end(), + std::back_inserter(ChildEnums)); mergeBase(std::move(Other)); } @@ -100,6 +183,16 @@ Parents = std::move(Other.Parents); if (VirtualParents.empty()) VirtualParents = std::move(Other.VirtualParents); + // Unconditionally extend the children, since they're added after the + // initial reduce and therefore there can only be one. + std::move(Other.ChildNamespaces.begin(), Other.ChildNamespaces.end(), + std::back_inserter(ChildNamespaces)); + std::move(Other.ChildRecords.begin(), Other.ChildRecords.end(), + std::back_inserter(ChildRecords)); + std::move(Other.ChildFunctions.begin(), Other.ChildFunctions.end(), + std::back_inserter(ChildFunctions)); + std::move(Other.ChildEnums.begin(), Other.ChildEnums.end(), + std::back_inserter(ChildEnums)); SymbolInfo::merge(std::move(Other)); } Index: clang-tools-extra/clang-doc/Serialize.h =================================================================== --- clang-tools-extra/clang-doc/Serialize.h +++ clang-tools-extra/clang-doc/Serialize.h @@ -46,6 +46,8 @@ // memory (vs storing USRs directly). SymbolID hashUSR(llvm::StringRef USR); +std::string serialize(std::unique_ptr &I); + } // namespace serialize } // namespace doc } // namespace clang Index: clang-tools-extra/clang-doc/Serialize.cpp =================================================================== --- clang-tools-extra/clang-doc/Serialize.cpp +++ clang-tools-extra/clang-doc/Serialize.cpp @@ -152,6 +152,21 @@ return Buffer.str().str(); } +std::string serialize(std::unique_ptr &I) { + switch (I->IT) { + case InfoType::IT_namespace: + return serialize(*static_cast(I.get())); + case InfoType::IT_record: + return serialize(*static_cast(I.get())); + case InfoType::IT_enum: + return serialize(*static_cast(I.get())); + case InfoType::IT_function: + return serialize(*static_cast(I.get())); + default: + return ""; + } +} + static void parseFullComment(const FullComment *C, CommentInfo &CI) { ClangDocCommentVisitor Visitor(CI); Visitor.parseComment(C); Index: clang-tools-extra/clang-doc/YAMLGenerator.cpp =================================================================== --- clang-tools-extra/clang-doc/YAMLGenerator.cpp +++ clang-tools-extra/clang-doc/YAMLGenerator.cpp @@ -20,6 +20,8 @@ LLVM_YAML_IS_SEQUENCE_VECTOR(Reference) LLVM_YAML_IS_SEQUENCE_VECTOR(Location) LLVM_YAML_IS_SEQUENCE_VECTOR(CommentInfo) +LLVM_YAML_IS_SEQUENCE_VECTOR(FunctionInfo) +LLVM_YAML_IS_SEQUENCE_VECTOR(EnumInfo) LLVM_YAML_IS_SEQUENCE_VECTOR(std::unique_ptr) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::SmallString<16>) @@ -175,7 +177,14 @@ }; template <> struct MappingTraits { - static void mapping(IO &IO, NamespaceInfo &I) { InfoMapping(IO, I); } + static void mapping(IO &IO, NamespaceInfo &I) { + InfoMapping(IO, I); + IO.mapOptional("ChildNamespaces", I.ChildNamespaces, + std::vector()); + IO.mapOptional("ChildRecords", I.ChildRecords, std::vector()); + IO.mapOptional("ChildFunctions", I.ChildFunctions); + IO.mapOptional("ChildEnums", I.ChildEnums); + } }; template <> struct MappingTraits { @@ -186,6 +195,11 @@ IO.mapOptional("Parents", I.Parents, llvm::SmallVector()); IO.mapOptional("VirtualParents", I.VirtualParents, llvm::SmallVector()); + IO.mapOptional("ChildNamespaces", I.ChildNamespaces, + std::vector()); + IO.mapOptional("ChildRecords", I.ChildRecords, std::vector()); + IO.mapOptional("ChildFunctions", I.ChildFunctions); + IO.mapOptional("ChildEnums", I.ChildEnums); } }; Index: clang-tools-extra/clang-doc/tool/ClangDocMain.cpp =================================================================== --- clang-tools-extra/clang-doc/tool/ClangDocMain.cpp +++ clang-tools-extra/clang-doc/tool/ClangDocMain.cpp @@ -117,6 +117,19 @@ return false; } +// A function to extract the appropriate path name for a given info's +// documentation. The path returned is a composite of the parent namespaces as +// directories plus the decl name as the filename. +// +// Example: Given the below, the yaml path for class C will be /A/B/C.yaml +// +// namespace A { +// namesapce B { +// +// class C {}; +// +// } +// } llvm::Expected> getPath(StringRef Root, StringRef Ext, StringRef Name, llvm::SmallVectorImpl &Namespaces) { @@ -130,6 +143,8 @@ return llvm::make_error("Unable to create directory.\n", llvm::inconvertibleErrorCode()); + if (Name.empty()) + Name = "GlobalNamespace"; llvm::sys::path::append(Path, Name + Ext); return Path; } @@ -142,6 +157,32 @@ llvm_unreachable("Unknown OutputFormatTy"); } +void addToInfoPassOutput( + StringRef Key, std::unique_ptr &&I, + llvm::StringMap>> &Output) { + auto R = Output.try_emplace(Key, std::vector>()); + R.first->second.emplace_back(std::move(I)); +} + +bool mapResultsInMemory( + tooling::ToolResults &Results, + llvm::StringMap>> &Output) { + bool Err = false; + Results.forEachResult([&](StringRef Key, StringRef Value) { + llvm::BitstreamCursor Stream(Value); + doc::ClangDocBitcodeReader Reader(Stream); + auto Infos = Reader.readBitcode(); + if (!Infos) { + llvm::errs() << toString(Infos.takeError()) << "\n"; + Err = true; + return; + } + for (auto &I : Infos.get()) + addToInfoPassOutput(Key, std::move(I), Output); + }); + return Err; +} + int main(int argc, const char **argv) { llvm::sys::PrintStackTraceOnErrorSignal(argv[0]); std::error_code OK; @@ -191,30 +232,22 @@ } // Collect values into output by key. - llvm::outs() << "Collecting infos...\n"; - llvm::StringMap>> MapOutput; - // In ToolResults, the Key is the hashed USR and the value is the // bitcode-encoded representation of the Info object. - Exec->get()->getToolResults()->forEachResult([&](StringRef Key, - StringRef Value) { - llvm::BitstreamCursor Stream(Value); - doc::ClangDocBitcodeReader Reader(Stream); - auto Infos = Reader.readBitcode(); - for (auto &I : Infos) { - auto R = - MapOutput.try_emplace(Key, std::vector>()); - R.first->second.emplace_back(std::move(I)); - } - }); + llvm::outs() << "Collecting infos...\n"; + llvm::StringMap>> MapOutput; + if (mapResultsInMemory(*Exec->get()->getToolResults(), MapOutput)) + return 1; - // Reducing and generation phases - llvm::outs() << "Reducing " << MapOutput.size() << " infos...\n"; - llvm::StringMap> ReduceOutput; + // First reducing phase (reduce all decls into one info per decl). + llvm::outs() << "Reducing " << MapOutput.size() << " infos by name...\n"; + tooling::InMemoryToolResults ReduceResults; for (auto &Group : MapOutput) { auto Reduced = doc::mergeInfos(Group.getValue()); - if (!Reduced) + if (!Reduced) { llvm::errs() << llvm::toString(Reduced.takeError()); + continue; + } if (DumpIntermediateResult) { SmallString<4096> Buffer; @@ -226,8 +259,36 @@ continue; } + // Prepare for second reduce pass by re-mapping infos by enclosing scope. + if (auto Error = + doc::mapByEnclosingScope(std::move(Reduced.get()), ReduceResults)) + llvm::errs() << toString(std::move(Error)) << "\n"; + } + + // Collect values into output by enclosing scope. + // In ReduceResults, the Key is the hashed USR of the enclosing scope and the + // value is the bitcode-encoded representation of the Info object. + llvm::outs() << "Collecting infos by enclosing scope...\n"; + llvm::StringMap>> ReduceOutput; + if (mapResultsInMemory(ReduceResults, ReduceOutput)) + return 1; + + // Second reducing phase (by scope) and docs generation phase + // This pass reduces the re-mapped infos by enclosing scope, meaning that all + // function and enum infos are absorbed into their parent class or namespace, + // and references to classes/namespaces are stored in their parent + // class/namespace. + llvm::outs() << "Further reducing " << ReduceOutput.size() + << " infos by scope...\n"; + for (auto &Group : ReduceOutput) { // Create the relevant ostream and emit the documentation for this decl. + auto Reduced = doc::mergeInfos(Group.getValue()); + if (!Reduced) { + llvm::errs() << llvm::toString(Reduced.takeError()); + continue; + } doc::Info *I = Reduced.get().get(); + auto InfoPath = getPath(OutDirectory, "." + Format, I->Name, I->Namespace); if (!InfoPath) { llvm::errs() << toString(InfoPath.takeError()) << "\n"; @@ -236,7 +297,7 @@ std::error_code FileErr; llvm::raw_fd_ostream InfoOS(InfoPath.get(), FileErr, llvm::sys::fs::F_None); if (FileErr != OK) { - llvm::errs() << "Error opening index file: " << FileErr.message() << "\n"; + llvm::errs() << "Error opening info file: " << FileErr.message() << "\n"; continue; } Index: clang-tools-extra/test/clang-doc/yaml-comments.cpp =================================================================== --- clang-tools-extra/test/clang-doc/yaml-comments.cpp +++ clang-tools-extra/test/clang-doc/yaml-comments.cpp @@ -3,7 +3,7 @@ // RUN: echo "" > %t/compile_flags.txt // RUN: cp "%s" "%t/test.cpp" // RUN: clang-doc -doxygen -p %t %t/test.cpp -output=%t/docs -// RUN: cat %t/docs/F.yaml | FileCheck %s +// RUN: cat %t/docs/GlobalNamespace.yaml | FileCheck %s /// \brief Brief description. /// @@ -26,8 +26,10 @@ /// Bonus comment on definition void F(int I, int J) {} -// CHECK: --- -// CHECK-NEXT: USR: '7574630614A535710E5A6ABCFFF98BCA2D06A4CA' +// CHECK: --- +// CHECK-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}' +// CHECK-NEXT: ChildFunctions: +// CHECK-NEXT: - USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}' // CHECK-NEXT: Name: 'F' // CHECK-NEXT: Description: // CHECK-NEXT: - Kind: 'FullComment' Index: clang-tools-extra/test/clang-doc/yaml-namespace.cpp =================================================================== --- clang-tools-extra/test/clang-doc/yaml-namespace.cpp +++ clang-tools-extra/test/clang-doc/yaml-namespace.cpp @@ -3,100 +3,104 @@ // RUN: echo "" > %t/compile_flags.txt // RUN: cp "%s" "%t/test.cpp" // RUN: clang-doc -doxygen -p %t %t/test.cpp -output=%t/docs +// RUN: cat %t/docs/GlobalNamespace.yaml | FileCheck %s --check-prefix=CHECK-G // RUN: cat %t/docs/A.yaml | FileCheck %s --check-prefix=CHECK-A // RUN: cat %t/docs/A/B.yaml | FileCheck %s --check-prefix=CHECK-B -// RUN: cat %t/docs/A/f.yaml | FileCheck %s --check-prefix=CHECK-F -// RUN: cat %t/docs/A/B/E.yaml | FileCheck %s --check-prefix=CHECK-E -// RUN: cat %t/docs/A/B/func.yaml | FileCheck %s --check-prefix=CHECK-FUNC -namespace A { - -// CHECK-A: --- -// CHECK-A-NEXT: USR: '8D042EFFC98B373450BC6B5B90A330C25A150E9C' -// CHECK-A-NEXT: Name: 'A' -// CHECK-A-NEXT: ... +// CHECK-G: --- +// CHECK-G-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}' +// CHECK-G-NEXT: ChildNamespaces: +// CHECK-G-NEXT: - Type: Namespace +// CHECK-G-NEXT: Name: 'A' +// CHECK-G-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}' +// CHECK-G-NEXT: ... +namespace A { + void f(); } // namespace A +// CHECK-A: --- +// CHECK-A-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}' +// CHECK-A-NEXT: Name: 'A' +// CHECK-A-NEXT: ChildNamespaces: +// CHECK-A-NEXT: - Type: Namespace +// CHECK-A-NEXT: Name: 'B' +// CHECK-A-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}' +// CHECK-A-NEXT: ChildFunctions: +// CHECK-A-NEXT: - USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}' +// CHECK-A-NEXT: Name: 'f' +// CHECK-A-NEXT: Namespace: +// CHECK-A-NEXT: - Type: Namespace +// CHECK-A-NEXT: Name: 'A' +// CHECK-A-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}' +// CHECK-A-NEXT: DefLocation: +// CHECK-A-NEXT: LineNumber: 52 +// CHECK-A-NEXT: Filename: '{{.*}}' +// CHECK-A-NEXT: Location: +// CHECK-A-NEXT: - LineNumber: 21 +// CHECK-A-NEXT: Filename: '{{.*}}' +// CHECK-A-NEXT: ReturnType: +// CHECK-A-NEXT: Type: +// CHECK-A-NEXT: Name: 'void' +// CHECK-A-NEXT: ... + namespace A { void f(){}; -// CHECK-F: --- -// CHECK-F-NEXT: USR: '39D3C95A5F7CE2BA4937BD7B01BAE09EBC2AD8AC' -// CHECK-F-NEXT: Name: 'f' -// CHECK-F-NEXT: Namespace: -// CHECK-F-NEXT: - Type: Namespace -// CHECK-F-NEXT: Name: 'A' -// CHECK-F-NEXT: USR: '8D042EFFC98B373450BC6B5B90A330C25A150E9C' -// CHECK-F-NEXT: DefLocation: -// CHECK-F-NEXT: LineNumber: 26 -// CHECK-F-NEXT: Filename: '{{.*}}' -// CHECK-F-NEXT: Location: -// CHECK-F-NEXT: - LineNumber: 20 -// CHECK-F-NEXT: Filename: 'test' -// CHECK-F-NEXT: ReturnType: -// CHECK-F-NEXT: Type: -// CHECK-F-NEXT: Name: 'void' -// CHECK-F-NEXT: ... - namespace B { - -// CHECK-B: --- -// CHECK-B-NEXT: USR: 'E21AF79E2A9D02554BA090D10DF39FE273F5CDB5' -// CHECK-B-NEXT: Name: 'B' -// CHECK-B-NEXT: Namespace: -// CHECK-B-NEXT: - Type: Namespace -// CHECK-B-NEXT: Name: 'A' -// CHECK-B-NEXT: USR: '8D042EFFC98B373450BC6B5B90A330C25A150E9C' -// CHECK-B-NEXT: ... - enum E { X }; -// CHECK-E: --- -// CHECK-E-NEXT: USR: 'E9ABF7E7E2425B626723D41E76E4BC7E7A5BD775' -// CHECK-E-NEXT: Name: 'E' -// CHECK-E-NEXT: Namespace: -// CHECK-E-NEXT: - Type: Namespace -// CHECK-E-NEXT: Name: 'B' -// CHECK-E-NEXT: USR: 'E21AF79E2A9D02554BA090D10DF39FE273F5CDB5' -// CHECK-E-NEXT: - Type: Namespace -// CHECK-E-NEXT: Name: 'A' -// CHECK-E-NEXT: USR: '8D042EFFC98B373450BC6B5B90A330C25A150E9C' -// CHECK-E-NEXT: DefLocation: -// CHECK-E-NEXT: LineNumber: 58 -// CHECK-E-NEXT: Filename: '{{.*}}' -// CHECK-E-NEXT: Members: -// CHECK-E-NEXT: - 'X' -// CHECK-E-NEXT: ... - E func(int i) { return X; } -// CHECK-FUNC: --- -// CHECK-FUNC-NEXT: USR: '9A82CB33ED0FDF81EE383D31CD0957D153C5E840' -// CHECK-FUNC-NEXT: Name: 'func' -// CHECK-FUNC-NEXT: Namespace: -// CHECK-FUNC-NEXT: - Type: Namespace -// CHECK-FUNC-NEXT: Name: 'B' -// CHECK-FUNC-NEXT: USR: 'E21AF79E2A9D02554BA090D10DF39FE273F5CDB5' -// CHECK-FUNC-NEXT: - Type: Namespace -// CHECK-FUNC-NEXT: Name: 'A' -// CHECK-FUNC-NEXT: USR: '8D042EFFC98B373450BC6B5B90A330C25A150E9C' -// CHECK-FUNC-NEXT: DefLocation: -// CHECK-FUNC-NEXT: LineNumber: 77 -// CHECK-FUNC-NEXT: Filename: '{{.*}}' -// CHECK-FUNC-NEXT: Params: -// CHECK-FUNC-NEXT: - Type: -// CHECK-FUNC-NEXT: Name: 'int' -// CHECK-FUNC-NEXT: Name: 'i' -// CHECK-FUNC-NEXT: ReturnType: -// CHECK-FUNC-NEXT: Type: -// CHECK-FUNC-NEXT: Name: 'enum A::B::E' -// CHECK-FUNC-NEXT: ... - } // namespace B } // namespace A + +// CHECK-B: --- +// CHECK-B-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}' +// CHECK-B-NEXT: Name: 'B' +// CHECK-B-NEXT: Namespace: +// CHECK-B-NEXT: - Type: Namespace +// CHECK-B-NEXT: Name: 'A' +// CHECK-B-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}' +// CHECK-B-NEXT: ChildFunctions: +// CHECK-B-NEXT: - USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}' +// CHECK-B-NEXT: Name: 'func' +// CHECK-B-NEXT: Namespace: +// CHECK-B-NEXT: - Type: Namespace +// CHECK-B-NEXT: Name: 'B' +// CHECK-B-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}' +// CHECK-B-NEXT: - Type: Namespace +// CHECK-B-NEXT: Name: 'A' +// CHECK-B-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}' +// CHECK-B-NEXT: DefLocation: +// CHECK-B-NEXT: LineNumber: 58 +// CHECK-B-NEXT: Filename: '{{.*}}' +// CHECK-B-NEXT: Params: +// CHECK-B-NEXT: - Type: +// CHECK-B-NEXT: Name: 'int' +// CHECK-B-NEXT: Name: 'i' +// CHECK-B-NEXT: ReturnType: +// CHECK-B-NEXT: Type: +// CHECK-B-NEXT: Name: 'enum A::B::E' +// CHECK-B-NEXT: ChildEnums: +// CHECK-B-NEXT: - USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}' +// CHECK-B-NEXT: Name: 'E' +// CHECK-B-NEXT: Namespace: +// CHECK-B-NEXT: - Type: Namespace +// CHECK-B-NEXT: Name: 'B' +// CHECK-B-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}' +// CHECK-B-NEXT: - Type: Namespace +// CHECK-B-NEXT: Name: 'A' +// CHECK-B-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}' +// CHECK-B-NEXT: DefLocation: +// CHECK-B-NEXT: LineNumber: 56 +// CHECK-B-NEXT: Filename: '{{.*}}' +// CHECK-B-NEXT: Members: +// CHECK-B-NEXT: - 'X' +// CHECK-B-NEXT: ... + Index: clang-tools-extra/test/clang-doc/yaml-record.cpp =================================================================== --- clang-tools-extra/test/clang-doc/yaml-record.cpp +++ clang-tools-extra/test/clang-doc/yaml-record.cpp @@ -1,250 +1,301 @@ // RUN: rm -rf %t // RUN: mkdir %t // RUN: echo "" > %t/compile_flags.txt -// RUN: cp "%s" "%t/test.cpp" -// RUN: clang-doc -doxygen -p %t %t/test.cpp -output=%t/docs -// RUN: cat %t/docs/A.yaml | FileCheck %s --check-prefix=CHECK-A -// RUN: cat %t/docs/Bc.yaml | FileCheck %s --check-prefix=CHECK-BC -// RUN: cat %t/docs/B.yaml | FileCheck %s --check-prefix=CHECK-B -// RUN: cat %t/docs/C.yaml | FileCheck %s --check-prefix=CHECK-C -// RUN: cat %t/docs/D.yaml | FileCheck %s --check-prefix=CHECK-D -// RUN: cat %t/docs/E.yaml | FileCheck %s --check-prefix=CHECK-E -// RUN: cat %t/docs/E/ProtectedMethod.yaml | FileCheck %s --check-prefix=CHECK-EPM -// RUN: cat %t/docs/E/E.yaml | FileCheck %s --check-prefix=CHECK-ECON -// RUN: cat %t/docs/E/'~E.yaml' | FileCheck %s --check-prefix=CHECK-EDES -// RUN: cat %t/docs/F.yaml | FileCheck %s --check-prefix=CHECK-F -// RUN: cat %t/docs/X.yaml | FileCheck %s --check-prefix=CHECK-X -// RUN: cat %t/docs/X/Y.yaml | FileCheck %s --check-prefix=CHECK-Y -// RUN: cat %t/docs/H.yaml | FileCheck %s --check-prefix=CHECK-H -// RUN: cat %t/docs/H/I.yaml | FileCheck %s --check-prefix=CHECK-I - -union A { int X; int Y; }; - -// CHECK-A: --- -// CHECK-A-NEXT: USR: 'ACE81AFA6627B4CEF2B456FB6E1252925674AF7E' -// CHECK-A-NEXT: Name: 'A' -// CHECK-A-NEXT: DefLocation: -// CHECK-A-NEXT: LineNumber: 21 -// CHECK-A-NEXT: Filename: '{{.*}}' -// CHECK-A-NEXT: TagType: Union -// CHECK-A-NEXT: Members: -// CHECK-A-NEXT: - Type: -// CHECK-A-NEXT: Name: 'int' -// CHECK-A-NEXT: Name: 'X' -// CHECK-A-NEXT: - Type: -// CHECK-A-NEXT: Name: 'int' -// CHECK-A-NEXT: Name: 'Y' -// CHECK-A-NEXT: ... +// RUN: cp "%s" "%t/{{.*}}.cpp" +// RUN: clang-doc -doxygen -p %t %t/{{.*}}.cpp -output=%t/docs +// RUN: cat %t/docs/GlobalNamespace.yaml | FileCheck %s --check-prefix=CHECK-G +// RUN: cat %t/docs/Records.yaml | FileCheck %s --check-prefix=CHECK-R +// RUN: cat %t/docs/Records/A.yaml | FileCheck %s --check-prefix=CHECK-A +// RUN: cat %t/docs/Records/C.yaml | FileCheck %s --check-prefix=CHECK-C +// RUN: cat %t/docs/Records/D.yaml | FileCheck %s --check-prefix=CHECK-D +// RUN: cat %t/docs/Records/E.yaml | FileCheck %s --check-prefix=CHECK-E +// RUN: cat %t/docs/Records/F.yaml | FileCheck %s --check-prefix=CHECK-F +// RUN: cat %t/docs/Records/X.yaml | FileCheck %s --check-prefix=CHECK-X +// RUN: cat %t/docs/Records/X/Y.yaml | FileCheck %s --check-prefix=CHECK-Y +namespace Records { -enum B { X, Y }; +union A { + int X; + int Y; +}; -// CHECK-B: --- -// CHECK-B-NEXT: USR: 'FC07BD34D5E77782C263FA944447929EA8753740' -// CHECK-B-NEXT: Name: 'B' -// CHECK-B-NEXT: DefLocation: -// CHECK-B-NEXT: LineNumber: 40 -// CHECK-B-NEXT: Filename: '{{.*}}' -// CHECK-B-NEXT: Members: -// CHECK-B-NEXT: - 'X' -// CHECK-B-NEXT: - 'Y' -// CHECK-B-NEXT: ... +//CHECK-A: --- +//CHECK-A-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}' +//CHECK-A-NEXT: Name: 'A' +//CHECK-A-NEXT: Namespace: +//CHECK-A-NEXT: - Type: Namespace +//CHECK-A-NEXT: Name: 'Records' +//CHECK-A-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}' +//CHECK-A-NEXT: DefLocation: +//CHECK-A-NEXT: LineNumber: 18 +//CHECK-A-NEXT: Filename: '{{.*}}' +//CHECK-A-NEXT: TagType: Union +//CHECK-A-NEXT: Members: +//CHECK-A-NEXT: - Type: +//CHECK-A-NEXT: Name: 'int' +//CHECK-A-NEXT: Name: 'X' +//CHECK-A-NEXT: - Type: +//CHECK-A-NEXT: Name: 'int' +//CHECK-A-NEXT: Name: 'Y' +//CHECK-A-NEXT: ... -enum class Bc { A, B }; +struct C { + int i; +}; + +//CHECK-C: --- +//CHECK-C-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}' +//CHECK-C-NEXT: Name: 'C' +//CHECK-C-NEXT: Namespace: +//CHECK-C-NEXT: - Type: Namespace +//CHECK-C-NEXT: Name: 'Records' +//CHECK-C-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}' +//CHECK-C-NEXT: DefLocation: +//CHECK-C-NEXT: LineNumber: 43 +//CHECK-C-NEXT: Filename: '{{.*}}' +//CHECK-C-NEXT: Members: +//CHECK-C-NEXT: - Type: +//CHECK-C-NEXT: Name: 'int' +//CHECK-C-NEXT: Name: 'i' +//CHECK-C-NEXT: ... -// CHECK-BC: --- -// CHECK-BC-NEXT: USR: '1E3438A08BA22025C0B46289FF0686F92C8924C5' -// CHECK-BC-NEXT: Name: 'Bc' -// CHECK-BC-NEXT: DefLocation: -// CHECK-BC-NEXT: LineNumber: 53 -// CHECK-BC-NEXT: Filename: '{{.*}}' -// CHECK-BC-NEXT: Scoped: true -// CHECK-BC-NEXT: Members: -// CHECK-BC-NEXT: - 'A' -// CHECK-BC-NEXT: - 'B' -// CHECK-BC-NEXT: ... - -struct C { int i; }; - -// CHECK-C: --- -// CHECK-C-NEXT: USR: '06B5F6A19BA9F6A832E127C9968282B94619B210' -// CHECK-C-NEXT: Name: 'C' -// CHECK-C-NEXT: DefLocation: -// CHECK-C-NEXT: LineNumber: 67 -// CHECK-C-NEXT: Filename: '{{.*}}' -// CHECK-C-NEXT: Members: -// CHECK-C-NEXT: - Type: -// CHECK-C-NEXT: Name: 'int' -// CHECK-C-NEXT: Name: 'i' -// CHECK-C-NEXT: ... class D {}; -// CHECK-D: --- -// CHECK-D-NEXT: USR: '0921737541208B8FA9BB42B60F78AC1D779AA054' -// CHECK-D-NEXT: Name: 'D' -// CHECK-D-NEXT: DefLocation: -// CHECK-D-NEXT: LineNumber: 81 -// CHECK-D-NEXT: Filename: '{{.*}}' -// CHECK-D-NEXT: TagType: Class -// CHECK-D-NEXT: ... +//CHECK-D: --- +//CHECK-D-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}' +//CHECK-D-NEXT: Name: 'D' +//CHECK-D-NEXT: Namespace: +//CHECK-D-NEXT: - Type: Namespace +//CHECK-D-NEXT: Name: 'Records' +//CHECK-D-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}' +//CHECK-D-NEXT: DefLocation: +//CHECK-D-NEXT: LineNumber: 64 +//CHECK-D-NEXT: Filename: '{{.*}}' +//CHECK-D-NEXT: TagType: Class +//CHECK-D-NEXT: ... + class E { public: E() {} - -// CHECK-ECON: --- -// CHECK-ECON-NEXT: USR: 'DEB4AC1CD9253CD9EF7FBE6BCAC506D77984ABD4' -// CHECK-ECON-NEXT: Name: 'E' -// CHECK-ECON-NEXT: Namespace: -// CHECK-ECON-NEXT: - Type: Record -// CHECK-ECON-NEXT: Name: 'E' -// CHECK-ECON-NEXT: USR: '289584A8E0FF4178A794622A547AA622503967A1' -// CHECK-ECON-NEXT: DefLocation: -// CHECK-ECON-NEXT: LineNumber: 94 -// CHECK-ECON-NEXT: Filename: '{{.*}}' -// CHECK-ECON-NEXT: IsMethod: true -// CHECK-ECON-NEXT: Parent: -// CHECK-ECON-NEXT: Type: Record -// CHECK-ECON-NEXT: Name: 'E' -// CHECK-ECON-NEXT: USR: '289584A8E0FF4178A794622A547AA622503967A1' -// CHECK-ECON-NEXT: ReturnType: -// CHECK-ECON-NEXT: Type: -// CHECK-ECON-NEXT: Name: 'void' -// CHECK-ECON-NEXT: ... - ~E() {} - -// CHECK-EDES: --- -// CHECK-EDES-NEXT: USR: 'BD2BDEBD423F80BACCEA75DE6D6622D355FC2D17' -// CHECK-EDES-NEXT: Name: '~E' -// CHECK-EDES-NEXT: Namespace: -// CHECK-EDES-NEXT: - Type: Record -// CHECK-EDES-NEXT: Name: 'E' -// CHECK-EDES-NEXT: USR: '289584A8E0FF4178A794622A547AA622503967A1' -// CHECK-EDES-NEXT: DefLocation: -// CHECK-EDES-NEXT: LineNumber: 116 -// CHECK-EDES-NEXT: Filename: '{{.*}}' -// CHECK-EDES-NEXT: IsMethod: true -// CHECK-EDES-NEXT: Parent: -// CHECK-EDES-NEXT: Type: Record -// CHECK-EDES-NEXT: Name: 'E' -// CHECK-EDES-NEXT: USR: '289584A8E0FF4178A794622A547AA622503967A1' -// CHECK-EDES-NEXT: ReturnType: -// CHECK-EDES-NEXT: Type: -// CHECK-EDES-NEXT: Name: 'void' -// CHECK-EDES-NEXT: ... - protected: void ProtectedMethod(); }; -// CHECK-E: --- -// CHECK-E-NEXT: USR: '289584A8E0FF4178A794622A547AA622503967A1' -// CHECK-E-NEXT: Name: 'E' -// CHECK-E-NEXT: DefLocation: -// CHECK-E-NEXT: LineNumber: 92 -// CHECK-E-NEXT: Filename: '{{.*}}' -// CHECK-E-NEXT: TagType: Class -// CHECK-E-NEXT: ... - void E::ProtectedMethod() {} -// CHECK-EPM: --- -// CHECK-EPM-NEXT: USR: '5093D428CDC62096A67547BA52566E4FB9404EEE' -// CHECK-EPM-NEXT: Name: 'ProtectedMethod' -// CHECK-EPM-NEXT: Namespace: -// CHECK-EPM-NEXT: - Type: Record -// CHECK-EPM-NEXT: Name: 'E' -// CHECK-EPM-NEXT: USR: '289584A8E0FF4178A794622A547AA622503967A1' -// CHECK-EPM-NEXT: DefLocation: -// CHECK-EPM-NEXT: LineNumber: 152 -// CHECK-EPM-NEXT: Filename: '{{.*}}' -// CHECK-EPM-NEXT: Location: -// CHECK-EPM-NEXT: - LineNumber: 140 -// CHECK-EPM-NEXT: Filename: '{{.*}}' -// CHECK-EPM-NEXT: IsMethod: true -// CHECK-EPM-NEXT: Parent: -// CHECK-EPM-NEXT: Type: Record -// CHECK-EPM-NEXT: Name: 'E' -// CHECK-EPM-NEXT: USR: '289584A8E0FF4178A794622A547AA622503967A1' -// CHECK-EPM-NEXT: ReturnType: -// CHECK-EPM-NEXT: Type: -// CHECK-EPM-NEXT: Name: 'void' -// CHECK-EPM-NEXT: ... +//CHECK-E: --- +//CHECK-E-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}' +//CHECK-E-NEXT: Name: 'E' +//CHECK-E-NEXT: Namespace: +//CHECK-E-NEXT: - Type: Namespace +//CHECK-E-NEXT: Name: 'Records' +//CHECK-E-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}' +//CHECK-E-NEXT: DefLocation: +//CHECK-E-NEXT: LineNumber: 80 +//CHECK-E-NEXT: Filename: '{{.*}}' +//CHECK-E-NEXT: TagType: Class +//CHECK-E-NEXT: ChildFunctions: +//CHECK-E-NEXT: - USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}' +//CHECK-E-NEXT: Name: '~E' +//CHECK-E-NEXT: Namespace: +//CHECK-E-NEXT: - Type: Record +//CHECK-E-NEXT: Name: 'E' +//CHECK-E-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}' +//CHECK-E-NEXT: - Type: Namespace +//CHECK-E-NEXT: Name: 'Records' +//CHECK-E-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}' +//CHECK-E-NEXT: DefLocation: +//CHECK-E-NEXT: LineNumber: 83 +//CHECK-E-NEXT: Filename: '{{.*}}' +//CHECK-E-NEXT: IsMethod: true +//CHECK-E-NEXT: Parent: +//CHECK-E-NEXT: Type: Record +//CHECK-E-NEXT: Name: 'E' +//CHECK-E-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}' +//CHECK-E-NEXT: ReturnType: +//CHECK-E-NEXT: Type: +//CHECK-E-NEXT: Name: 'void' +//CHECK-E-NEXT: - USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}' +//CHECK-E-NEXT: Name: 'ProtectedMethod' +//CHECK-E-NEXT: Namespace: +//CHECK-E-NEXT: - Type: Record +//CHECK-E-NEXT: Name: 'E' +//CHECK-E-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}' +//CHECK-E-NEXT: - Type: Namespace +//CHECK-E-NEXT: Name: 'Records' +//CHECK-E-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}' +//CHECK-E-NEXT: DefLocation: +//CHECK-E-NEXT: LineNumber: 89 +//CHECK-E-NEXT: Filename: '{{.*}}' +//CHECK-E-NEXT: Location: +//CHECK-E-NEXT: - LineNumber: 86 +//CHECK-E-NEXT: Filename: '{{.*}}' +//CHECK-E-NEXT: IsMethod: true +//CHECK-E-NEXT: Parent: +//CHECK-E-NEXT: Type: Record +//CHECK-E-NEXT: Name: 'E' +//CHECK-E-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}' +//CHECK-E-NEXT: ReturnType: +//CHECK-E-NEXT: Type: +//CHECK-E-NEXT: Name: 'void' +//CHECK-E-NEXT: - USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}' +//CHECK-E-NEXT: Name: 'E' +//CHECK-E-NEXT: Namespace: +//CHECK-E-NEXT: - Type: Record +//CHECK-E-NEXT: Name: 'E' +//CHECK-E-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}' +//CHECK-E-NEXT: - Type: Namespace +//CHECK-E-NEXT: Name: 'Records' +//CHECK-E-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}' +//CHECK-E-NEXT: DefLocation: +//CHECK-E-NEXT: LineNumber: 82 +//CHECK-E-NEXT: Filename: '{{.*}}' +//CHECK-E-NEXT: IsMethod: true +//CHECK-E-NEXT: Parent: +//CHECK-E-NEXT: Type: Record +//CHECK-E-NEXT: Name: 'E' +//CHECK-E-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}' +//CHECK-E-NEXT: ReturnType: +//CHECK-E-NEXT: Type: +//CHECK-E-NEXT: Name: 'void' +//CHECK-E-NEXT: ... class F : virtual private D, public E {}; -// CHECK-F: --- -// CHECK-F-NEXT: USR: 'E3B54702FABFF4037025BA194FC27C47006330B5' -// CHECK-F-NEXT: Name: 'F' -// CHECK-F-NEXT: DefLocation: -// CHECK-F-NEXT: LineNumber: 177 -// CHECK-F-NEXT: Filename: '{{.*}}' -// CHECK-F-NEXT: TagType: Class -// CHECK-F-NEXT: Parents: -// CHECK-F-NEXT: - Type: Record -// CHECK-F-NEXT: Name: 'E' -// CHECK-F-NEXT: USR: '289584A8E0FF4178A794622A547AA622503967A1' -// CHECK-F-NEXT: VirtualParents: -// CHECK-F-NEXT: - Type: Record -// CHECK-F-NEXT: Name: 'D' -// CHECK-F-NEXT: USR: '0921737541208B8FA9BB42B60F78AC1D779AA054' -// CHECK-F-NEXT: ... +//CHECK-F: --- +//CHECK-F-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}' +//CHECK-F-NEXT: Name: 'F' +//CHECK-F-NEXT: Namespace: +//CHECK-F-NEXT: - Type: Namespace +//CHECK-F-NEXT: Name: 'Records' +//CHECK-F-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}' +//CHECK-F-NEXT: DefLocation: +//CHECK-F-NEXT: LineNumber: 168 +//CHECK-F-NEXT: Filename: '{{.*}}' +//CHECK-F-NEXT: TagType: Class +//CHECK-F-NEXT: Parents: +//CHECK-F-NEXT: - Type: Record +//CHECK-F-NEXT: Name: 'E' +//CHECK-F-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}' +//CHECK-F-NEXT: VirtualParents: +//CHECK-F-NEXT: - Type: Record +//CHECK-F-NEXT: Name: 'D' +//CHECK-F-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}' +//CHECK-F-NEXT: ... class X { class Y {}; -// CHECK-Y: --- -// CHECK-Y-NEXT: USR: '641AB4A3D36399954ACDE29C7A8833032BF40472' -// CHECK-Y-NEXT: Name: 'Y' -// CHECK-Y-NEXT: Namespace: -// CHECK-Y-NEXT: - Type: Record -// CHECK-Y-NEXT: Name: 'X' -// CHECK-Y-NEXT: USR: 'CA7C7935730B5EACD25F080E9C83FA087CCDC75E' -// CHECK-Y-NEXT: DefLocation: -// CHECK-Y-NEXT: LineNumber: 197 -// CHECK-Y-NEXT: Filename: '{{.*}}' -// CHECK-Y-NEXT: TagType: Class -// CHECK-Y-NEXT: ... +//CHECK-Y: --- +//CHECK-Y-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}' +//CHECK-Y-NEXT: Name: 'Y' +//CHECK-Y-NEXT: Namespace: +//CHECK-Y-NEXT: - Type: Record +//CHECK-Y-NEXT: Name: 'X' +//CHECK-Y-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}' +//CHECK-Y-NEXT: - Type: Namespace +//CHECK-Y-NEXT: Name: 'Records' +//CHECK-Y-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}' +//CHECK-Y-NEXT: DefLocation: +//CHECK-Y-NEXT: LineNumber: 192 +//CHECK-Y-NEXT: Filename: '{{.*}}' +//CHECK-Y-NEXT: TagType: Class +//CHECK-Y-NEXT: ... }; -// CHECK-X: --- -// CHECK-X-NEXT: USR: 'CA7C7935730B5EACD25F080E9C83FA087CCDC75E' -// CHECK-X-NEXT: Name: 'X' -// CHECK-X-NEXT: DefLocation: -// CHECK-X-NEXT: LineNumber: 196 -// CHECK-X-NEXT: Filename: '{{.*}}' -// CHECK-X-NEXT: TagType: Class -// CHECK-X-NEXT: ... +//CHECK-X: --- +//CHECK-X-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}' +//CHECK-X-NEXT: Name: 'X' +//CHECK-X-NEXT: Namespace: +//CHECK-X-NEXT: - Type: Namespace +//CHECK-X-NEXT: Name: 'Records' +//CHECK-X-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}' +//CHECK-X-NEXT: DefLocation: +//CHECK-X-NEXT: LineNumber: 191 +//CHECK-X-NEXT: Filename: '{{.*}}' +//CHECK-X-NEXT: TagType: Class +//CHECK-X-NEXT: ChildRecords: +//CHECK-X-NEXT: - Type: Record +//CHECK-X-NEXT: Name: 'Y' +//CHECK-X-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}' +//CHECK-X-NEXT: ... void H() { class I {}; - -// CHECK-I: --- -// CHECK-I-NEXT: USR: '{{.*}}' -// CHECK-I-NEXT: Name: 'I' -// CHECK-I-NEXT: Namespace: -// CHECK-I-NEXT: - Type: Function -// CHECK-I-NEXT: Name: 'H' -// CHECK-I-NEXT: USR: 'B6AC4C5C9F2EA3F2B3ECE1A33D349F4EE502B24E' -// CHECK-I-NEXT: DefLocation: -// CHECK-I-NEXT: LineNumber: 224 -// CHECK-I-NEXT: Filename: 'test' -// CHECK-I-NEXT: TagType: Class -// CHECK-I-NEXT: ... - } -// CHECK-H: --- -// CHECK-H-NEXT: USR: 'B6AC4C5C9F2EA3F2B3ECE1A33D349F4EE502B24E' -// CHECK-H-NEXT: Name: 'H' -// CHECK-H-NEXT: DefLocation: -// CHECK-H-NEXT: LineNumber: 223 -// CHECK-H-NEXT: Filename: 'test' -// CHECK-H-NEXT: ReturnType: -// CHECK-H-NEXT: Type: -// CHECK-H-NEXT: Name: 'void' -// CHECK-H-NEXT: ... +} // namespace Records + +//CHECK-R: --- +//CHECK-R-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}' +//CHECK-R-NEXT: Name: 'Records' +//CHECK-R-NEXT: ChildRecords: +//CHECK-R-NEXT: - Type: Record +//CHECK-R-NEXT: Name: 'F' +//CHECK-R-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}' +//CHECK-R-NEXT: - Type: Record +//CHECK-R-NEXT: Name: 'D' +//CHECK-R-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}' +//CHECK-R-NEXT: - Type: Record +//CHECK-R-NEXT: Name: 'E' +//CHECK-R-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}' +//CHECK-R-NEXT: - Type: Record +//CHECK-R-NEXT: Name: 'X' +//CHECK-R-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}' +//CHECK-R-NEXT: - Type: Record +//CHECK-R-NEXT: Name: 'A' +//CHECK-R-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}' +//CHECK-R-NEXT: - Type: Record +//CHECK-R-NEXT: Name: 'C' +//CHECK-R-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}' +//CHECK-R-NEXT: ChildFunctions: +//CHECK-R-NEXT: - USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}' +//CHECK-R-NEXT: Name: 'H' +//CHECK-R-NEXT: Namespace: +//CHECK-R-NEXT: - Type: Namespace +//CHECK-R-NEXT: Name: 'Records' +//CHECK-R-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}' +//CHECK-R-NEXT: DefLocation: +//CHECK-R-NEXT: LineNumber: 229 +//CHECK-R-NEXT: Filename: '{{.*}}' +//CHECK-R-NEXT: ReturnType: +//CHECK-R-NEXT: Type: +//CHECK-R-NEXT: Name: 'void' +//CHECK-R-NEXT: ... + + +enum B { X, Y }; + +enum class Bc { A, B }; + +//CHECK-G: --- +//CHECK-G-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}' +//CHECK-G-NEXT: ChildNamespaces: +//CHECK-G-NEXT: - Type: Namespace +//CHECK-G-NEXT: Name: 'Records' +//CHECK-G-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}' +//CHECK-G-NEXT: ChildEnums: +//CHECK-G-NEXT: - USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}' +//CHECK-G-NEXT: Name: 'B' +//CHECK-G-NEXT: DefLocation: +//CHECK-G-NEXT: LineNumber: 273 +//CHECK-G-NEXT: Filename: '{{.*}}' +//CHECK-G-NEXT: Members: +//CHECK-G-NEXT: - 'X' +//CHECK-G-NEXT: - 'Y' +//CHECK-G-NEXT: - USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}' +//CHECK-G-NEXT: Name: 'Bc' +//CHECK-G-NEXT: DefLocation: +//CHECK-G-NEXT: LineNumber: 275 +//CHECK-G-NEXT: Filename: '{{.*}}' +//CHECK-G-NEXT: Scoped: true +//CHECK-G-NEXT: Members: +//CHECK-G-NEXT: - 'A' +//CHECK-G-NEXT: - 'B' +//CHECK-G-NEXT: ...