-
{{Type}} {{Name}}
+
{{#IsStatic}}static {{/IsStatic}}{{Type}} {{Name}}
{{#MemberComments}}
{{>Comments}}
diff --git a/clang-tools-extra/test/clang-doc/basic-project.mustache.test b/clang-tools-extra/test/clang-doc/basic-project.mustache.test
index b985a39265de7..d406c9f297960 100644
--- a/clang-tools-extra/test/clang-doc/basic-project.mustache.test
+++ b/clang-tools-extra/test/clang-doc/basic-project.mustache.test
@@ -204,7 +204,7 @@ HTML-CALC:
HTML-CALC:
int public_val
HTML-CALC:
HTML-CALC:
-HTML-CALC:
const int static_val
+HTML-CALC:
static const int static_val
HTML-CALC:
HTML-CALC:
HTML-CALC:
diff --git a/clang-tools-extra/test/clang-doc/json/class.cpp b/clang-tools-extra/test/clang-doc/json/class.cpp
index 8bf9402adf054..9d3102a11db9d 100644
--- a/clang-tools-extra/test/clang-doc/json/class.cpp
+++ b/clang-tools-extra/test/clang-doc/json/class.cpp
@@ -158,6 +158,7 @@ struct MyClass {
// CHECK-NEXT: ],
// CHECK-NEXT: "ProtectedMembers": [
// CHECK-NEXT: {
+// CHECK-NEXT: "IsStatic": false,
// CHECK-NEXT: "Name": "ProtectedField",
// CHECK-NEXT: "Type": "int"
// CHECK-NEXT: }
@@ -198,6 +199,7 @@ struct MyClass {
// CHECK-NEXT: },
// CHECK: "PublicMembers": [
// CHECK-NEXT: {
+// CHECK-NEXT: "IsStatic": false,
// CHECK-NEXT: "Name": "PublicField",
// CHECK-NEXT: "Type": "int"
// CHECK-NEXT: }
diff --git a/clang-tools-extra/test/clang-doc/json/inheritance.cpp b/clang-tools-extra/test/clang-doc/json/inheritance.cpp
new file mode 100644
index 0000000000000..53476da870c61
--- /dev/null
+++ b/clang-tools-extra/test/clang-doc/json/inheritance.cpp
@@ -0,0 +1,111 @@
+// RUN: rm -rf %t && mkdir -p %t
+// RUN: clang-doc --output=%t --format=json --executor=standalone %s
+// RUN: FileCheck %s < %t/json/GlobalNamespace/_ZTV7MyClass.json
+
+class Virtual {};
+class Foo : virtual Virtual {};
+class Bar : Foo {};
+class Fizz : virtual Virtual {};
+class Buzz : Fizz {};
+
+class MyClass : Bar, Buzz {};
+
+// CHECK: "Bases": [
+// CHECK-NEXT: {
+// CHECK-NEXT: "Access": "private",
+// CHECK-NEXT: "InfoType": "record",
+// CHECK-NEXT: "IsParent": true,
+// CHECK-NEXT: "IsTypedef": false,
+// CHECK-NEXT: "IsVirtual": false,
+// CHECK-NEXT: "MangledName": "",
+// CHECK-NEXT: "Name": "Bar",
+// CHECK-NEXT: "Path": "GlobalNamespace",
+// CHECK-NEXT: "TagType": "struct",
+// CHECK-NEXT: "USR": "{{[0-9A-F]*}}"
+// CHECK-NEXT: },
+// CHECK-NEXT: {
+// CHECK-NEXT: "Access": "private",
+// CHECK-NEXT: "InfoType": "record",
+// CHECK-NEXT: "IsParent": false,
+// CHECK-NEXT: "IsTypedef": false,
+// CHECK-NEXT: "IsVirtual": false,
+// CHECK-NEXT: "MangledName": "",
+// CHECK-NEXT: "Name": "Foo",
+// CHECK-NEXT: "Path": "GlobalNamespace",
+// CHECK-NEXT: "TagType": "struct",
+// CHECK-NEXT: "USR": "{{[0-9A-F]*}}"
+// CHECK-NEXT: },
+// CHECK-NEXT: {
+// CHECK-NEXT: "Access": "private",
+// CHECK-NEXT: "InfoType": "record",
+// CHECK-NEXT: "IsParent": false,
+// CHECK-NEXT: "IsTypedef": false,
+// CHECK-NEXT: "IsVirtual": true,
+// CHECK-NEXT: "MangledName": "",
+// CHECK-NEXT: "Name": "Virtual",
+// CHECK-NEXT: "Path": "GlobalNamespace",
+// CHECK-NEXT: "TagType": "struct",
+// CHECK-NEXT: "USR": "{{[0-9A-F]*}}"
+// CHECK-NEXT: },
+// CHECK-NEXT: {
+// CHECK-NEXT: "Access": "private",
+// CHECK-NEXT: "InfoType": "record",
+// CHECK-NEXT: "IsParent": true,
+// CHECK-NEXT: "IsTypedef": false,
+// CHECK-NEXT: "IsVirtual": false,
+// CHECK-NEXT: "MangledName": "",
+// CHECK-NEXT: "Name": "Buzz",
+// CHECK-NEXT: "Path": "GlobalNamespace",
+// CHECK-NEXT: "TagType": "struct",
+// CHECK-NEXT: "USR": "{{[0-9A-F]*}}"
+// CHECK-NEXT: },
+// CHECK-NEXT: {
+// CHECK-NEXT: "Access": "private",
+// CHECK-NEXT: "InfoType": "record",
+// CHECK-NEXT: "IsParent": false,
+// CHECK-NEXT: "IsTypedef": false,
+// CHECK-NEXT: "IsVirtual": false,
+// CHECK-NEXT: "MangledName": "",
+// CHECK-NEXT: "Name": "Fizz",
+// CHECK-NEXT: "Path": "GlobalNamespace",
+// CHECK-NEXT: "TagType": "struct",
+// CHECK-NEXT: "USR": "{{[0-9A-F]*}}"
+// CHECK-NEXT: },
+// CHECK-NEXT: {
+// CHECK-NEXT: "Access": "private",
+// CHECK-NEXT: "End": true,
+// CHECK-NEXT: "InfoType": "record",
+// CHECK-NEXT: "IsParent": false,
+// CHECK-NEXT: "IsTypedef": false,
+// CHECK-NEXT: "IsVirtual": true,
+// CHECK-NEXT: "MangledName": "",
+// CHECK-NEXT: "Name": "Virtual",
+// CHECK-NEXT: "Path": "GlobalNamespace",
+// CHECK-NEXT: "TagType": "struct",
+// CHECK-NEXT: "USR": "{{[0-9A-F]*}}"
+// CHECK-NEXT: }
+// CHECK-NEXT: ],
+// CHECK: "Parents": [
+// CHECK-NEXT: {
+// CHECK-NEXT: "Name": "Bar",
+// CHECK-NEXT: "Path": "GlobalNamespace",
+// CHECK-NEXT: "QualName": "Bar",
+// CHECK-NEXT: "USR": "{{[0-9A-F]*}}"
+// CHECK-NEXT: },
+// CHECK-NEXT: {
+// CHECK-NEXT: "End": true,
+// CHECK-NEXT: "Name": "Buzz",
+// CHECK-NEXT: "Path": "GlobalNamespace",
+// CHECK-NEXT: "QualName": "Buzz",
+// CHECK-NEXT: "USR": "{{[0-9A-F]*}}"
+// CHECK-NEXT: }
+// CHECK-NEXT: ],
+// CHECK: "VirtualParents": [
+// CHECK-NEXT: {
+// CHECK-NEXT: "End": true,
+// CHECK-NEXT: "Name": "Virtual",
+// CHECK-NEXT: "Path": "GlobalNamespace",
+// CHECK-NEXT: "QualName": "Virtual",
+// CHECK-NEXT: "USR": "{{[0-9A-F]*}}"
+// CHECK-NEXT: }
+// CHECK-NEXT: ]
\ No newline at end of file
diff --git a/clang-tools-extra/unittests/clang-doc/JSONGeneratorTest.cpp b/clang-tools-extra/unittests/clang-doc/JSONGeneratorTest.cpp
index bd437553961f6..bcb9fd8e47bc6 100644
--- a/clang-tools-extra/unittests/clang-doc/JSONGeneratorTest.cpp
+++ b/clang-tools-extra/unittests/clang-doc/JSONGeneratorTest.cpp
@@ -90,6 +90,7 @@ TEST_F(JSONGeneratorTest, emitRecordJSON) {
],
"PublicMembers": [
{
+ "IsStatic": false,
"Name": "N",
"Type": "int"
}
@@ -115,8 +116,10 @@ TEST_F(JSONGeneratorTest, emitRecordJSON) {
}
],
"HasEnums": true,
+ "HasParents": true,
"HasPublicFunctions": true,
"HasRecords": true,
+ "HasVirtualParents": true,
"InfoType": "record",
"IsTypedef": false,
"Location": {
@@ -140,6 +143,7 @@ TEST_F(JSONGeneratorTest, emitRecordJSON) {
"Path": "GlobalNamespace",
"ProtectedMembers": [
{
+ "IsStatic": false,
"Name": "X",
"Type": "int"
}