aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--clang-tools-extra/clang-doc/BitcodeReader.cpp2
-rw-r--r--clang-tools-extra/clang-doc/BitcodeWriter.cpp4
-rw-r--r--clang-tools-extra/clang-doc/BitcodeWriter.h1
-rw-r--r--clang-tools-extra/clang-doc/JSONGenerator.cpp60
-rw-r--r--clang-tools-extra/clang-doc/Representation.cpp2
-rw-r--r--clang-tools-extra/clang-doc/Representation.h10
-rw-r--r--clang-tools-extra/clang-doc/Serialize.cpp11
-rw-r--r--clang-tools-extra/test/clang-doc/json/class-requires.cpp1
-rw-r--r--clang-tools-extra/test/clang-doc/json/class-template.cpp1
-rw-r--r--clang-tools-extra/test/clang-doc/json/class.cpp18
-rw-r--r--clang-tools-extra/test/clang-doc/json/compound-constraints.cpp4
-rw-r--r--clang-tools-extra/test/clang-doc/json/concept.cpp2
-rw-r--r--clang-tools-extra/test/clang-doc/json/function-requires.cpp7
-rw-r--r--clang-tools-extra/test/clang-doc/json/method-template.cpp2
-rw-r--r--clang-tools-extra/test/clang-doc/json/namespace.cpp17
-rw-r--r--clang-tools-extra/test/clang-doc/json/nested-namespace.cpp4
-rw-r--r--clang-tools-extra/unittests/clang-doc/JSONGeneratorTest.cpp25
17 files changed, 158 insertions, 13 deletions
diff --git a/clang-tools-extra/clang-doc/BitcodeReader.cpp b/clang-tools-extra/clang-doc/BitcodeReader.cpp
index dce34a8..4efbbd3 100644
--- a/clang-tools-extra/clang-doc/BitcodeReader.cpp
+++ b/clang-tools-extra/clang-doc/BitcodeReader.cpp
@@ -384,6 +384,8 @@ static llvm::Error parseRecord(const Record &R, unsigned ID,
return decodeRecord(R, I->Path, Blob);
case REFERENCE_FIELD:
return decodeRecord(R, F, Blob);
+ case REFERENCE_FILE:
+ return decodeRecord(R, I->DocumentationFileName, Blob);
default:
return llvm::createStringError(llvm::inconvertibleErrorCode(),
"invalid field for Reference");
diff --git a/clang-tools-extra/clang-doc/BitcodeWriter.cpp b/clang-tools-extra/clang-doc/BitcodeWriter.cpp
index eed2372..e23511b 100644
--- a/clang-tools-extra/clang-doc/BitcodeWriter.cpp
+++ b/clang-tools-extra/clang-doc/BitcodeWriter.cpp
@@ -210,6 +210,7 @@ static const llvm::IndexedMap<RecordIdDsc, RecordIdToIndexFunctor>
{REFERENCE_TYPE, {"RefType", &genIntAbbrev}},
{REFERENCE_PATH, {"Path", &genStringAbbrev}},
{REFERENCE_FIELD, {"Field", &genIntAbbrev}},
+ {REFERENCE_FILE, {"File", &genStringAbbrev}},
{TEMPLATE_PARAM_CONTENTS, {"Contents", &genStringAbbrev}},
{TEMPLATE_SPECIALIZATION_OF,
{"SpecializationOf", &genSymbolIdAbbrev}},
@@ -286,7 +287,7 @@ static const std::vector<std::pair<BlockId, std::vector<RecordId>>>
// Reference Block
{BI_REFERENCE_BLOCK_ID,
{REFERENCE_USR, REFERENCE_NAME, REFERENCE_QUAL_NAME, REFERENCE_TYPE,
- REFERENCE_PATH, REFERENCE_FIELD}},
+ REFERENCE_PATH, REFERENCE_FIELD, REFERENCE_FILE}},
// Template Blocks.
{BI_TEMPLATE_BLOCK_ID, {}},
{BI_TEMPLATE_PARAM_BLOCK_ID, {TEMPLATE_PARAM_CONTENTS}},
@@ -479,6 +480,7 @@ void ClangDocBitcodeWriter::emitBlock(const Reference &R, FieldId Field) {
emitRecord((unsigned)R.RefType, REFERENCE_TYPE);
emitRecord(R.Path, REFERENCE_PATH);
emitRecord((unsigned)Field, REFERENCE_FIELD);
+ emitRecord(R.DocumentationFileName, REFERENCE_FILE);
}
void ClangDocBitcodeWriter::emitBlock(const FriendInfo &R) {
diff --git a/clang-tools-extra/clang-doc/BitcodeWriter.h b/clang-tools-extra/clang-doc/BitcodeWriter.h
index 501af12..688f886 100644
--- a/clang-tools-extra/clang-doc/BitcodeWriter.h
+++ b/clang-tools-extra/clang-doc/BitcodeWriter.h
@@ -140,6 +140,7 @@ enum RecordId {
REFERENCE_TYPE,
REFERENCE_PATH,
REFERENCE_FIELD,
+ REFERENCE_FILE,
TEMPLATE_PARAM_CONTENTS,
TEMPLATE_SPECIALIZATION_OF,
TYPEDEF_USR,
diff --git a/clang-tools-extra/clang-doc/JSONGenerator.cpp b/clang-tools-extra/clang-doc/JSONGenerator.cpp
index cc4c683..30243c9 100644
--- a/clang-tools-extra/clang-doc/JSONGenerator.cpp
+++ b/clang-tools-extra/clang-doc/JSONGenerator.cpp
@@ -43,6 +43,30 @@ static auto SerializeReferenceLambda = [](const auto &Ref, Object &Object) {
serializeReference(Ref, Object);
};
+static std::string infoTypeToString(InfoType IT) {
+ switch (IT) {
+ case InfoType::IT_default:
+ return "default";
+ case InfoType::IT_namespace:
+ return "namespace";
+ case InfoType::IT_record:
+ return "record";
+ case InfoType::IT_function:
+ return "function";
+ case InfoType::IT_enum:
+ return "enum";
+ case InfoType::IT_typedef:
+ return "typedef";
+ case InfoType::IT_concept:
+ return "concept";
+ case InfoType::IT_variable:
+ return "variable";
+ case InfoType::IT_friend:
+ return "friend";
+ }
+ llvm_unreachable("Unknown InfoType encountered.");
+}
+
static json::Object
serializeLocation(const Location &Loc,
const std::optional<StringRef> RepositoryUrl) {
@@ -172,6 +196,9 @@ serializeCommonAttributes(const Info &I, json::Object &Obj,
const std::optional<StringRef> RepositoryUrl) {
Obj["Name"] = I.Name;
Obj["USR"] = toHex(toStringRef(I.USR));
+ Obj["InfoType"] = infoTypeToString(I.IT);
+ if (!I.DocumentationFileName.empty())
+ Obj["DocumentationFileName"] = I.DocumentationFileName;
if (!I.Path.empty())
Obj["Path"] = I.Path;
@@ -205,6 +232,8 @@ static void serializeReference(const Reference &Ref, Object &ReferenceObj) {
ReferenceObj["Name"] = Ref.Name;
ReferenceObj["QualName"] = Ref.QualName;
ReferenceObj["USR"] = toHex(toStringRef(Ref.USR));
+ if (!Ref.DocumentationFileName.empty())
+ ReferenceObj["DocumentationFileName"] = Ref.DocumentationFileName;
}
// Although namespaces and records both have ScopeChildren, they serialize them
@@ -217,14 +246,18 @@ serializeCommonChildren(const ScopeChildren &Children, json::Object &Obj,
serializeInfo(Info, Object, RepositoryUrl);
};
- if (!Children.Enums.empty())
+ if (!Children.Enums.empty()) {
serializeArray(Children.Enums, Obj, "Enums", SerializeInfo);
+ Obj["HasEnums"] = true;
+ }
if (!Children.Typedefs.empty())
serializeArray(Children.Typedefs, Obj, "Typedefs", SerializeInfo);
- if (!Children.Records.empty())
+ if (!Children.Records.empty()) {
serializeArray(Children.Records, Obj, "Records", SerializeReferenceLambda);
+ Obj["HasRecords"] = true;
+ }
}
template <typename Container, typename SerializationFunc>
@@ -234,10 +267,12 @@ static void serializeArray(const Container &Records, Object &Obj,
json::Value RecordsArray = Array();
auto &RecordsArrayRef = *RecordsArray.getAsArray();
RecordsArrayRef.reserve(Records.size());
- for (const auto &Item : Records) {
+ for (size_t Index = 0; Index < Records.size(); ++Index) {
json::Value ItemVal = Object();
auto &ItemObj = *ItemVal.getAsObject();
- SerializeInfo(Item, ItemObj);
+ SerializeInfo(Records[Index], ItemObj);
+ if (Index == Records.size() - 1)
+ ItemObj["End"] = true;
RecordsArrayRef.push_back(ItemVal);
}
Obj[Key] = RecordsArray;
@@ -380,6 +415,11 @@ static void serializeInfo(const FriendInfo &I, Object &Obj) {
}
}
+static void insertArray(Object &Obj, json::Value &Array, StringRef Key) {
+ Obj[Key] = Array;
+ Obj["Has" + Key.str()] = true;
+}
+
static void serializeInfo(const RecordInfo &I, json::Object &Obj,
const std::optional<StringRef> &RepositoryUrl) {
serializeCommonAttributes(I, Obj, RepositoryUrl);
@@ -406,7 +446,7 @@ static void serializeInfo(const RecordInfo &I, json::Object &Obj,
}
if (!PubFunctionsArrayRef.empty())
- Obj["PublicFunctions"] = PubFunctionsArray;
+ insertArray(Obj, PubFunctionsArray, "PublicFunctions");
if (!ProtFunctionsArrayRef.empty())
Obj["ProtectedFunctions"] = ProtFunctionsArray;
}
@@ -430,7 +470,7 @@ static void serializeInfo(const RecordInfo &I, json::Object &Obj,
}
if (!PubMembersArrayRef.empty())
- Obj["PublicMembers"] = PublicMembersArray;
+ insertArray(Obj, PublicMembersArray, "PublicMembers");
if (!ProtMembersArrayRef.empty())
Obj["ProtectedMembers"] = ProtectedMembersArray;
}
@@ -496,10 +536,7 @@ static SmallString<16> determineFileName(Info *I, SmallString<128> &Path) {
SmallString<16> FileName;
if (I->IT == InfoType::IT_record) {
auto *RecordSymbolInfo = static_cast<SymbolInfo *>(I);
- if (RecordSymbolInfo->MangledName.size() < 255)
- FileName = RecordSymbolInfo->MangledName;
- else
- FileName = toStringRef(toHex(RecordSymbolInfo->USR));
+ FileName = RecordSymbolInfo->MangledName;
} else if (I->IT == InfoType::IT_namespace && I->Name != "")
// Serialize the global namespace as index.json
FileName = I->Name;
@@ -527,7 +564,10 @@ Error JSONGenerator::generateDocs(
}
SmallString<16> FileName = determineFileName(Info, Path);
+ if (FileToInfos.contains(Path))
+ continue;
FileToInfos[Path].push_back(Info);
+ Info->DocumentationFileName = FileName;
}
for (const auto &Group : FileToInfos) {
diff --git a/clang-tools-extra/clang-doc/Representation.cpp b/clang-tools-extra/clang-doc/Representation.cpp
index beaf314..79850e1 100644
--- a/clang-tools-extra/clang-doc/Representation.cpp
+++ b/clang-tools-extra/clang-doc/Representation.cpp
@@ -247,6 +247,8 @@ void Reference::merge(Reference &&Other) {
Name = Other.Name;
if (Path.empty())
Path = Other.Path;
+ if (DocumentationFileName.empty())
+ DocumentationFileName = Other.DocumentationFileName;
}
bool FriendInfo::mergeable(const FriendInfo &Other) {
diff --git a/clang-tools-extra/clang-doc/Representation.h b/clang-tools-extra/clang-doc/Representation.h
index 23f0e90..2a75f89 100644
--- a/clang-tools-extra/clang-doc/Representation.h
+++ b/clang-tools-extra/clang-doc/Representation.h
@@ -121,6 +121,10 @@ struct Reference {
Reference(SymbolID USR, StringRef Name, InfoType IT, StringRef QualName,
StringRef Path = StringRef())
: USR(USR), Name(Name), QualName(QualName), RefType(IT), Path(Path) {}
+ Reference(SymbolID USR, StringRef Name, InfoType IT, StringRef QualName,
+ StringRef Path, SmallString<16> DocumentationFileName)
+ : USR(USR), Name(Name), QualName(QualName), RefType(IT), Path(Path),
+ DocumentationFileName(DocumentationFileName) {}
bool operator==(const Reference &Other) const {
return std::tie(USR, Name, QualName, RefType) ==
@@ -155,6 +159,7 @@ struct Reference {
// Path of directory where the clang-doc generated file will be saved
// (possibly unresolved)
llvm::SmallString<128> Path;
+ SmallString<16> DocumentationFileName;
};
// Holds the children of a record or namespace.
@@ -331,6 +336,11 @@ struct Info {
llvm::SmallString<128> Path; // Path of directory where the clang-doc
// generated file will be saved
+ // The name used for the file that this info is documented in.
+ // In the JSON generator, infos are documented in files with mangled names.
+ // Thus, we keep track of the physical filename for linking purposes.
+ SmallString<16> DocumentationFileName;
+
void mergeBase(Info &&I);
bool mergeable(const Info &Other);
diff --git a/clang-tools-extra/clang-doc/Serialize.cpp b/clang-tools-extra/clang-doc/Serialize.cpp
index 7a0e00c..de73f68 100644
--- a/clang-tools-extra/clang-doc/Serialize.cpp
+++ b/clang-tools-extra/clang-doc/Serialize.cpp
@@ -495,7 +495,8 @@ static void InsertChild(ScopeChildren &Scope, const NamespaceInfo &Info) {
static void InsertChild(ScopeChildren &Scope, const RecordInfo &Info) {
Scope.Records.emplace_back(Info.USR, Info.Name, InfoType::IT_record,
- Info.Name, getInfoRelativePath(Info.Namespace));
+ Info.Name, getInfoRelativePath(Info.Namespace),
+ Info.MangledName);
}
static void InsertChild(ScopeChildren &Scope, EnumInfo Info) {
@@ -777,7 +778,13 @@ static void populateSymbolInfo(SymbolInfo &I, const T *D, const FullComment *C,
Mangler->mangleCXXVTable(CXXD, MangledStream);
else
MangledStream << D->getNameAsString();
- I.MangledName = MangledName;
+ if (MangledName.size() > 255)
+ // File creation fails if the mangled name is too long, so default to the
+ // USR. We should look for a better check since filesystems differ in
+ // maximum filename length
+ I.MangledName = llvm::toStringRef(llvm::toHex(I.USR));
+ else
+ I.MangledName = MangledName;
delete Mangler;
}
diff --git a/clang-tools-extra/test/clang-doc/json/class-requires.cpp b/clang-tools-extra/test/clang-doc/json/class-requires.cpp
index 213da93..bf6c889 100644
--- a/clang-tools-extra/test/clang-doc/json/class-requires.cpp
+++ b/clang-tools-extra/test/clang-doc/json/class-requires.cpp
@@ -20,6 +20,7 @@ struct MyClass;
// CHECK-NEXT: "Template": {
// CHECK-NEXT: "Constraints": [
// CHECK-NEXT: {
+// CHECK-NEXT: "End": true,
// CHECK-NEXT: "Expression": "Addable<T>",
// CHECK-NEXT: "Name": "Addable",
// CHECK-NEXT: "Path": "",
diff --git a/clang-tools-extra/test/clang-doc/json/class-template.cpp b/clang-tools-extra/test/clang-doc/json/class-template.cpp
index 6cdc3e9..149248c 100644
--- a/clang-tools-extra/test/clang-doc/json/class-template.cpp
+++ b/clang-tools-extra/test/clang-doc/json/class-template.cpp
@@ -11,6 +11,7 @@ template<typename T> struct MyClass {
// CHECK: "Name": "method",
// CHECK: "Params": [
// CHECK-NEXT: {
+// CHECK-NEXT: "End": true,
// CHECK-NEXT: "Name": "Param",
// CHECK-NEXT: "Type": "T"
// CHECK-NEXT: }
diff --git a/clang-tools-extra/test/clang-doc/json/class.cpp b/clang-tools-extra/test/clang-doc/json/class.cpp
index d8317ea..a3635898 100644
--- a/clang-tools-extra/test/clang-doc/json/class.cpp
+++ b/clang-tools-extra/test/clang-doc/json/class.cpp
@@ -60,8 +60,11 @@ protected:
// CHECK-NEXT: "TextComment": " This is a brief description."
// CHECK-NEXT: }
// CHECK: "Command": "brief"
+// CHECK: "DocumentationFileName": "_ZTV7MyClass",
// CHECK: "Enums": [
// CHECK-NEXT: {
+// CHECK-NEXT: "End": true,
+// CHECK-NEXT: "InfoType": "enum",
// CHECK-NEXT: "Location": {
// CHECK-NEXT: "Filename": "{{.*}}class.cpp",
// CHECK-NEXT: "LineNumber": 17
@@ -76,6 +79,7 @@ protected:
// CHECK-NEXT: "Value": "1"
// CHECK-NEXT: },
// CHECK-NEXT: {
+// CHECK-NEXT: "End": true,
// CHECK-NEXT: "Name": "BLUE",
// CHECK-NEXT: "ValueExpr": "5"
// CHECK-NEXT: }
@@ -94,6 +98,7 @@ protected:
// CHECK-NEXT: "IsClass": false,
// CHECK-NEXT: "Params": [
// CHECK-NEXT: {
+// CHECK-NEXT: "End": true,
// CHECK-NEXT: "Name": "",
// CHECK-NEXT: "Type": "int"
// CHECK-NEXT: }
@@ -118,6 +123,7 @@ protected:
// CHECK-NEXT: }
// CHECK-NEXT: },
// CHECK-NEXT: {
+// CHECK-NEXT: "End": true,
// CHECK-NEXT: "IsClass": true,
// CHECK-NEXT: "Reference": {
// CHECK-NEXT: "Name": "Foo",
@@ -129,6 +135,11 @@ protected:
// CHECK-NEXT: ],
// COM: FIXME: FullName is not emitted correctly.
// CHECK-NEXT: "FullName": "",
+// CHECK-NEXT: "HasEnums": true,
+// CHECK-NEXT: "HasPublicFunctions": true,
+// CHECK-NEXT: "HasPublicMembers": true,
+// CHECK-NEXT: "HasRecords": true,
+// CHECK-NEXT: "InfoType": "record",
// CHECK-NEXT: "IsTypedef": false,
// CHECK-NEXT: "Location": {
// CHECK-NEXT: "Filename": "{{.*}}class.cpp",
@@ -142,6 +153,7 @@ protected:
// CHECK-NEXT: "Path": "GlobalNamespace",
// CHECK-NEXT: "ProtectedFunctions": [
// CHECK-NEXT: {
+// CHECK-NEXT: "InfoType": "function",
// CHECK-NEXT: "IsStatic": false,
// CHECK-NEXT: "Name": "protectedMethod",
// CHECK-NEXT: "Namespace": [
@@ -166,6 +178,7 @@ protected:
// CHECK-NEXT: ],
// CHECK-NEXT: "PublicFunctions": [
// CHECK-NEXT: {
+// CHECK-NEXT: "InfoType": "function",
// CHECK-NEXT: "IsStatic": false,
// CHECK-NEXT: "Name": "myMethod",
// CHECK-NEXT: "Namespace": [
@@ -174,6 +187,7 @@ protected:
// CHECK-NEXT: ],
// CHECK-NEXT: "Params": [
// CHECK-NEXT: {
+// CHECK-NEXT: "End": true,
// CHECK-NEXT: "Name": "MyParam",
// CHECK-NEXT: "Type": "int"
// CHECK-NEXT: }
@@ -204,6 +218,8 @@ protected:
// CHECK-NEXT: ],
// CHECK-NEXT: "Records": [
// CHECK-NEXT: {
+// CHECK-NEXT: "DocumentationFileName": "_ZTVN7MyClass11NestedClassE",
+// CHECK-NEXT: "End": true,
// CHECK-NEXT: "Name": "NestedClass",
// CHECK-NEXT: "Path": "GlobalNamespace{{[\/]+}}MyClass",
// CHECK-NEXT: "QualName": "NestedClass",
@@ -213,6 +229,8 @@ protected:
// CHECK-NEXT: "TagType": "struct",
// CHECK-NEXT: "Typedefs": [
// CHECK-NEXT: {
+// CHECK-NEXT: "End": true,
+// CHECK-NEXT: "InfoType": "typedef",
// CHECK-NEXT: "IsUsing": false,
// CHECK-NEXT: "Location": {
// CHECK-NEXT: "Filename": "{{.*}}class.cpp",
diff --git a/clang-tools-extra/test/clang-doc/json/compound-constraints.cpp b/clang-tools-extra/test/clang-doc/json/compound-constraints.cpp
index 34acb68..bb2b4ca 100644
--- a/clang-tools-extra/test/clang-doc/json/compound-constraints.cpp
+++ b/clang-tools-extra/test/clang-doc/json/compound-constraints.cpp
@@ -37,6 +37,7 @@ template<typename T> requires (Incrementable<T> && Decrementable<T>) || PreIncre
// CHECK-NEXT: "USR": "{{[0-9A-F]*}}"
// CHECK-NEXT: },
// CHECK-NEXT: {
+// CHECK-NEXT: "End": true,
// CHECK-NEXT: "Expression": "Decrementable<T>",
// CHECK-NEXT: "Name": "Decrementable",
// CHECK-NEXT: "Path": "",
@@ -55,6 +56,7 @@ template<typename T> requires (Incrementable<T> && Decrementable<T>) || PreIncre
// CHECK-NEXT: "USR": "{{[0-9A-F]*}}"
// CHECK-NEXT: },
// CHECK-NEXT: {
+// CHECK-NEXT: "End": true,
// CHECK-NEXT: "Expression": "Decrementable<T>",
// CHECK-NEXT: "Name": "Decrementable",
// CHECK-NEXT: "Path": "",
@@ -87,6 +89,7 @@ template<typename T> requires (Incrementable<T> && Decrementable<T>) || PreIncre
// CHECK-NEXT: "USR": "{{[0-9A-F]*}}"
// CHECK-NEXT: },
// CHECK-NEXT: {
+// CHECK-NEXT: "End": true,
// CHECK-NEXT: "Expression": "PreDecrementable<T>",
// CHECK-NEXT: "Name": "PreDecrementable",
// CHECK-NEXT: "Path": "",
@@ -112,6 +115,7 @@ template<typename T> requires (Incrementable<T> && Decrementable<T>) || PreIncre
// CHECK-NEXT: "USR": "{{[0-9A-F]*}}"
// CHECK-NEXT: },
// CHECK-NEXT: {
+// CHECK-NEXT: "End": true,
// CHECK-NEXT: "Expression": "PreIncrementable<T>",
// CHECK-NEXT: "Name": "PreIncrementable",
// CHECK-NEXT: "Path": "",
diff --git a/clang-tools-extra/test/clang-doc/json/concept.cpp b/clang-tools-extra/test/clang-doc/json/concept.cpp
index b946393..766415b 100644
--- a/clang-tools-extra/test/clang-doc/json/concept.cpp
+++ b/clang-tools-extra/test/clang-doc/json/concept.cpp
@@ -23,6 +23,8 @@ concept Incrementable = requires(T x) {
// CHECK-NEXT: {
// CHECK-NEXT: "TextComment": " Requires that T suports post and pre-incrementing."
// CHECK: ],
+// CHECK: "End": true,
+// CHECK-NEXT: "InfoType": "concept",
// CHECK-NEXT: "IsType": true,
// CHECK-NEXT: "Name": "Incrementable",
// CHECK-NEXT: "Template": {
diff --git a/clang-tools-extra/test/clang-doc/json/function-requires.cpp b/clang-tools-extra/test/clang-doc/json/function-requires.cpp
index 08ac4c7..59ed39e 100644
--- a/clang-tools-extra/test/clang-doc/json/function-requires.cpp
+++ b/clang-tools-extra/test/clang-doc/json/function-requires.cpp
@@ -14,10 +14,12 @@ template<Incrementable T> Incrementable auto incrementTwo(T t);
// CHECK: "Functions": [
// CHECK-NEXT: {
+// CHECK-NEXT: "InfoType": "function",
// CHECK-NEXT: "IsStatic": false,
// CHECK-NEXT: "Name": "increment",
// CHECK-NEXT: "Params": [
// CHECK-NEXT: {
+// CHECK-NEXT: "End": true,
// CHECK-NEXT: "Name": "t",
// CHECK-NEXT: "Type": "T"
// CHECK-NEXT: }
@@ -32,6 +34,7 @@ template<Incrementable T> Incrementable auto incrementTwo(T t);
// CHECK-NEXT: "Template": {
// CHECK-NEXT: "Constraints": [
// CHECK-NEXT: {
+// CHECK-NEXT: "End": true,
// CHECK-NEXT: "Expression": "Incrementable<T>",
// CHECK-NEXT: "Name": "Incrementable",
// CHECK-NEXT: "Path": "",
@@ -46,10 +49,13 @@ template<Incrementable T> Incrementable auto incrementTwo(T t);
// CHECK-NEXT: "USR": "{{[0-9A-F]*}}"
// CHECK-NEXT: },
// CHECK-NEXT: {
+// CHECK-NEXT: "End": true,
+// CHECK-NEXT: "InfoType": "function",
// CHECK-NEXT: "IsStatic": false,
// CHECK-NEXT: "Name": "incrementTwo",
// CHECK-NEXT: "Params": [
// CHECK-NEXT: {
+// CHECK-NEXT: "End": true,
// CHECK-NEXT: "Name": "t",
// CHECK-NEXT: "Type": "T"
// CHECK-NEXT: }
@@ -64,6 +70,7 @@ template<Incrementable T> Incrementable auto incrementTwo(T t);
// CHECK-NEXT: "Template": {
// CHECK-NEXT: "Constraints": [
// CHECK-NEXT: {
+// CHECK-NEXT: "End": true,
// CHECK-NEXT: "Expression": "Incrementable<T>",
// CHECK-NEXT: "Name": "Incrementable",
// CHECK-NEXT: "Path": "",
diff --git a/clang-tools-extra/test/clang-doc/json/method-template.cpp b/clang-tools-extra/test/clang-doc/json/method-template.cpp
index ac8450a..14232d0 100644
--- a/clang-tools-extra/test/clang-doc/json/method-template.cpp
+++ b/clang-tools-extra/test/clang-doc/json/method-template.cpp
@@ -9,6 +9,7 @@ struct MyClass {
// CHECK: "PublicFunctions": [
// CHECK-NEXT: {
+// CHECK-NEXT: "InfoType": "function",
// CHECK-NEXT: "IsStatic": false,
// CHECK-NEXT: "Location": {
// CHECK-NEXT: "Filename": "{{.*}}method-template.cpp",
@@ -21,6 +22,7 @@ struct MyClass {
// CHECK-NEXT: ],
// CHECK-NEXT: "Params": [
// CHECK-NEXT: {
+// CHECK-NEXT: "End": true,
// CHECK-NEXT: "Name": "param",
// CHECK-NEXT: "Type": "T"
// CHECK-NEXT: }
diff --git a/clang-tools-extra/test/clang-doc/json/namespace.cpp b/clang-tools-extra/test/clang-doc/json/namespace.cpp
index 779d7b49..4b6b388 100644
--- a/clang-tools-extra/test/clang-doc/json/namespace.cpp
+++ b/clang-tools-extra/test/clang-doc/json/namespace.cpp
@@ -20,8 +20,11 @@ enum Color {
typedef int MyTypedef;
// CHECK: {
+// CHECK-NEXT: "DocumentationFileName": "index",
// CHECK-NEXT: "Enums": [
// CHECK-NEXT: {
+// CHECK-NEXT: "End": true,
+// CHECK-NEXT: "InfoType": "enum",
// CHECK-NEXT: "Location": {
// CHECK-NEXT: "Filename": "{{.*}}namespace.cpp",
// CHECK-NEXT: "LineNumber": 14
@@ -36,6 +39,7 @@ typedef int MyTypedef;
// CHECK-NEXT: "Value": "1"
// CHECK-NEXT: },
// CHECK-NEXT: {
+// CHECK-NEXT: "End": true,
// CHECK-NEXT: "Name": "BLUE",
// CHECK-NEXT: "ValueExpr": "5"
// CHECK-NEXT: }
@@ -47,10 +51,13 @@ typedef int MyTypedef;
// CHECK-NEXT: ],
// CHECK-NEXT: "Functions": [
// CHECK-NEXT: {
+// CHECK-NEXT: "End": true,
+// CHECK-NEXT: "InfoType": "function",
// CHECK-NEXT: "IsStatic": false,
// CHECK-NEXT: "Name": "myFunction",
// CHECK-NEXT: "Params": [
// CHECK-NEXT: {
+// CHECK-NEXT: "End": true,
// CHECK-NEXT: "Name": "Param",
// CHECK-NEXT: "Type": "int"
// CHECK-NEXT: }
@@ -65,9 +72,13 @@ typedef int MyTypedef;
// CHECK-NEXT: "USR": "{{[0-9A-F]*}}"
// CHECK-NEXT: }
// CHECK-NEXT: ],
+// CHECK-NEXT: "HasEnums": true,
+// CHECK-NEXT: "HasRecords": true,
+// CHECK-NEXT: "InfoType": "namespace",
// CHECK-NEXT: "Name": "",
// CHECK-NEXT: "Namespaces": [
// CHECK-NEXT: {
+// CHECK-NEXT: "End": true,
// CHECK-NEXT: "Name": "NestedNamespace",
// CHECK-NEXT: "Path": "",
// CHECK-NEXT: "QualName": "NestedNamespace",
@@ -76,6 +87,8 @@ typedef int MyTypedef;
// CHECK-NEXT: ],
// CHECK-NEXT: "Records": [
// CHECK-NEXT: {
+// CHECK-NEXT: "DocumentationFileName": "_ZTV7MyClass",
+// CHECK-NEXT: "End": true,
// CHECK-NEXT: "Name": "MyClass",
// CHECK-NEXT: "Path": "GlobalNamespace",
// CHECK-NEXT: "QualName": "MyClass",
@@ -84,6 +97,8 @@ typedef int MyTypedef;
// CHECK-NEXT: ],
// CHECK-NEXT: "Typedefs": [
// CHECK-NEXT: {
+// CHECK-NEXT: "End": true,
+// CHECK-NEXT: "InfoType": "typedef",
// CHECK-NEXT: "IsUsing": false,
// CHECK-NEXT: "Location": {
// CHECK-NEXT: "Filename": "{{.*}}namespace.cpp",
@@ -104,6 +119,8 @@ typedef int MyTypedef;
// CHECK-NEXT: "USR": "0000000000000000000000000000000000000000"
// CHECK-NEXT: "Variables": [
// CHECK-NEXT: {
+// CHECK-NEXT: "End": true,
+// CHECK-NEXT: "InfoType": "variable",
// CHECK-NEXT: "IsStatic": true,
// CHECK-NEXT: "Location": {
// CHECK-NEXT: "Filename": "{{.*}}namespace.cpp",
diff --git a/clang-tools-extra/test/clang-doc/json/nested-namespace.cpp b/clang-tools-extra/test/clang-doc/json/nested-namespace.cpp
index 54f95c4..255e540 100644
--- a/clang-tools-extra/test/clang-doc/json/nested-namespace.cpp
+++ b/clang-tools-extra/test/clang-doc/json/nested-namespace.cpp
@@ -12,6 +12,8 @@ namespace nested {
// NESTED: "Variables": [
// NESTED-NEXT: {
+// NESTED-NEXT: "End": true,
+// NESTED-NEXT: "InfoType": "variable",
// NESTED-NEXT: "IsStatic": false,
// NESTED-NEXT: "Location": {
// NESTED-NEXT: "Filename": "{{.*}}nested-namespace.cpp",
@@ -24,6 +26,8 @@ namespace nested {
// INNER: "Variables": [
// INNER-NEXT: {
+// INNER-NEXT: "End": true,
+// INNER-NEXT: "InfoType": "variable",
// INNER-NEXT: "IsStatic": false,
// INNER-NEXT: "Location": {
// INNER-NEXT: "Filename": "{{.*}}nested-namespace.cpp",
diff --git a/clang-tools-extra/unittests/clang-doc/JSONGeneratorTest.cpp b/clang-tools-extra/unittests/clang-doc/JSONGeneratorTest.cpp
index 5927235b..07c761f 100644
--- a/clang-tools-extra/unittests/clang-doc/JSONGeneratorTest.cpp
+++ b/clang-tools-extra/unittests/clang-doc/JSONGeneratorTest.cpp
@@ -63,7 +63,11 @@ TEST(JSONGeneratorTest, emitRecordJSON) {
"Bases": [
{
"Access": "public",
+ "End": true,
"FullName": "",
+ "HasPublicFunctions": true,
+ "HasPublicMembers": true,
+ "InfoType": "record",
"IsParent": true,
"IsTypedef": false,
"IsVirtual": true,
@@ -72,6 +76,7 @@ TEST(JSONGeneratorTest, emitRecordJSON) {
"Path": "path/to/F",
"PublicFunctions": [
{
+ "InfoType": "function",
"IsStatic": false,
"Name": "InheritedFunctionOne",
"ReturnType": {
@@ -96,8 +101,11 @@ TEST(JSONGeneratorTest, emitRecordJSON) {
],
"Enums": [
{
+ "End": true,
+ "InfoType": "enum",
"Members": [
{
+ "End": true,
"Name": "RED",
"Value": "0"
}
@@ -108,6 +116,10 @@ TEST(JSONGeneratorTest, emitRecordJSON) {
}
],
"FullName": "",
+ "HasEnums": true,
+ "HasPublicFunctions": true,
+ "HasRecords": true,
+ "InfoType": "record",
"IsTypedef": false,
"Location": {
"Filename": "main.cpp",
@@ -120,6 +132,7 @@ TEST(JSONGeneratorTest, emitRecordJSON) {
],
"Parents": [
{
+ "End": true,
"Name": "F",
"Path": "",
"QualName": "",
@@ -135,6 +148,7 @@ TEST(JSONGeneratorTest, emitRecordJSON) {
],
"PublicFunctions": [
{
+ "InfoType": "function",
"IsStatic": false,
"Name": "OneFunction",
"ReturnType": {
@@ -149,6 +163,7 @@ TEST(JSONGeneratorTest, emitRecordJSON) {
],
"Records": [
{
+ "End": true,
"Name": "ChildStruct",
"Path": "path/to/A/r",
"QualName": "path::to::A::r::ChildStruct",
@@ -164,6 +179,7 @@ TEST(JSONGeneratorTest, emitRecordJSON) {
"USR": "0000000000000000000000000000000000000000",
"VirtualParents": [
{
+ "End": true,
"Name": "G",
"Path": "path/to/G",
"QualName": "path::to::G::G",
@@ -201,6 +217,8 @@ TEST(JSONGeneratorTest, emitNamespaceJSON) {
std::string Expected = R"raw({
"Enums": [
{
+ "End": true,
+ "InfoType": "enum",
"Name": "OneEnum",
"Scoped": false,
"USR": "0000000000000000000000000000000000000000"
@@ -208,6 +226,8 @@ TEST(JSONGeneratorTest, emitNamespaceJSON) {
],
"Functions": [
{
+ "End": true,
+ "InfoType": "function",
"IsStatic": false,
"Name": "OneFunction",
"ReturnType": {
@@ -220,12 +240,16 @@ TEST(JSONGeneratorTest, emitNamespaceJSON) {
"USR": "0000000000000000000000000000000000000000"
}
],
+ "HasEnums": true,
+ "HasRecords": true,
+ "InfoType": "namespace",
"Name": "Namespace",
"Namespace": [
"A"
],
"Namespaces": [
{
+ "End": true,
"Name": "ChildNamespace",
"Path": "path/to/A/Namespace",
"QualName": "path::to::A::Namespace::ChildNamespace",
@@ -235,6 +259,7 @@ TEST(JSONGeneratorTest, emitNamespaceJSON) {
"Path": "path/to/A",
"Records": [
{
+ "End": true,
"Name": "ChildStruct",
"Path": "path/to/A/Namespace",
"QualName": "path::to::A::Namespace::ChildStruct",