Index: clang-tools-extra/clang-doc/BitcodeReader.cpp =================================================================== --- clang-tools-extra/clang-doc/BitcodeReader.cpp +++ clang-tools-extra/clang-doc/BitcodeReader.cpp @@ -292,6 +292,8 @@ return decodeRecord(R, I->RefType, Blob); case REFERENCE_PATH: return decodeRecord(R, I->Path, Blob); + case REFERENCE_IS_IN_GLOBAL_NAMESPACE: + return decodeRecord(R, I->IsInGlobalNamespace, Blob); case REFERENCE_FIELD: return decodeRecord(R, F, Blob); default: Index: clang-tools-extra/clang-doc/BitcodeWriter.h =================================================================== --- clang-tools-extra/clang-doc/BitcodeWriter.h +++ clang-tools-extra/clang-doc/BitcodeWriter.h @@ -109,6 +109,7 @@ REFERENCE_NAME, REFERENCE_TYPE, REFERENCE_PATH, + REFERENCE_IS_IN_GLOBAL_NAMESPACE, REFERENCE_FIELD, RI_LAST, RI_FIRST = VERSION Index: clang-tools-extra/clang-doc/BitcodeWriter.cpp =================================================================== --- clang-tools-extra/clang-doc/BitcodeWriter.cpp +++ clang-tools-extra/clang-doc/BitcodeWriter.cpp @@ -172,6 +172,8 @@ {REFERENCE_NAME, {"Name", &StringAbbrev}}, {REFERENCE_TYPE, {"RefType", &IntAbbrev}}, {REFERENCE_PATH, {"Path", &StringAbbrev}}, + {REFERENCE_IS_IN_GLOBAL_NAMESPACE, + {"IsInGlobalNamespace", &BoolAbbrev}}, {REFERENCE_FIELD, {"Field", &IntAbbrev}}}; assert(Inits.size() == RecordIdCount); for (const auto &Init : Inits) { @@ -215,7 +217,7 @@ // Reference Block {BI_REFERENCE_BLOCK_ID, {REFERENCE_USR, REFERENCE_NAME, REFERENCE_TYPE, REFERENCE_PATH, - REFERENCE_FIELD}}}; + REFERENCE_IS_IN_GLOBAL_NAMESPACE, REFERENCE_FIELD}}}; // AbbreviationMap @@ -387,6 +389,7 @@ emitRecord(R.Name, REFERENCE_NAME); emitRecord((unsigned)R.RefType, REFERENCE_TYPE); emitRecord(R.Path, REFERENCE_PATH); + emitRecord(R.IsInGlobalNamespace, REFERENCE_IS_IN_GLOBAL_NAMESPACE); emitRecord((unsigned)Field, REFERENCE_FIELD); } Index: clang-tools-extra/clang-doc/HTMLGenerator.cpp =================================================================== --- clang-tools-extra/clang-doc/HTMLGenerator.cpp +++ clang-tools-extra/clang-doc/HTMLGenerator.cpp @@ -245,7 +245,7 @@ static std::unique_ptr genTypeReference(const Reference &Type, StringRef CurrentDirectory) { - if (Type.Path.empty()) + if (Type.Path.empty() && !Type.IsInGlobalNamespace) return llvm::make_unique(Type.Name); llvm::SmallString<128> Path = computeRelativePath(Type.Path, CurrentDirectory); Index: clang-tools-extra/clang-doc/Representation.h =================================================================== --- clang-tools-extra/clang-doc/Representation.h +++ clang-tools-extra/clang-doc/Representation.h @@ -114,11 +114,17 @@ struct Reference { Reference() = default; Reference(llvm::StringRef Name) : Name(Name) {} - Reference(llvm::StringRef Name, StringRef Path) : Name(Name), Path(Path) {} + // An empty path means the info is in the globalnamespace because the path is + // a composite of the parent namespaces. + Reference(llvm::StringRef Name, StringRef Path) + : Name(Name), Path(Path), IsInGlobalNamespace(Path.empty()) {} Reference(SymbolID USR, StringRef Name, InfoType IT) : USR(USR), Name(Name), RefType(IT) {} + // An empty path means the info is in the globalnamespace because the path is + // a composite of the parent namespaces. Reference(SymbolID USR, StringRef Name, InfoType IT, StringRef Path) - : USR(USR), Name(Name), RefType(IT), Path(Path) {} + : USR(USR), Name(Name), RefType(IT), Path(Path), + IsInGlobalNamespace(Path.empty()) {} bool operator==(const Reference &Other) const { return std::tie(USR, Name, RefType) == @@ -130,8 +136,12 @@ InfoType RefType = InfoType::IT_default; // Indicates the type of this // Reference (namespace, record, // function, enum, default). - llvm::SmallString<128> Path; // Path of directory where the clang-doc - // generated file will be saved + llvm::SmallString<128> + Path; // Path of directory where the clang-doc generated file will be + // saved (possibly unresolved) + bool IsInGlobalNamespace = + false; // Indicates if the info's parent is the global namespace, or if + // the info is the global namespace }; // A base struct for TypeInfos Index: clang-tools-extra/clang-doc/YAMLGenerator.cpp =================================================================== --- clang-tools-extra/clang-doc/YAMLGenerator.cpp +++ clang-tools-extra/clang-doc/YAMLGenerator.cpp @@ -156,6 +156,7 @@ IO.mapOptional("Name", Ref.Name, SmallString<16>()); IO.mapOptional("USR", Ref.USR, SymbolID()); IO.mapOptional("Path", Ref.Path, SmallString<128>()); + IO.mapOptional("IsInGlobalNamespace", Ref.IsInGlobalNamespace, false); } }; Index: clang-tools-extra/unittests/clang-doc/YAMLGeneratorTest.cpp =================================================================== --- clang-tools-extra/unittests/clang-doc/YAMLGeneratorTest.cpp +++ clang-tools-extra/unittests/clang-doc/YAMLGeneratorTest.cpp @@ -80,7 +80,8 @@ I.Members.emplace_back("int", "path/to/int", "X", AccessSpecifier::AS_private); I.TagType = TagTypeKind::TTK_Class; - I.Parents.emplace_back(EmptySID, "F", InfoType::IT_record, "path/to/F"); + I.Parents.emplace_back(EmptySID, "F", InfoType::IT_record, + ""); // F is in the global namespace I.VirtualParents.emplace_back(EmptySID, "G", InfoType::IT_record, "path/to/G"); @@ -120,7 +121,7 @@ Parents: - Type: Record Name: 'F' - Path: 'path/to/F' + IsInGlobalNamespace: true VirtualParents: - Type: Record Name: 'G'