Index: clang/lib/AST/JSONNodeDumper.cpp =================================================================== --- clang/lib/AST/JSONNodeDumper.cpp +++ clang/lib/AST/JSONNodeDumper.cpp @@ -111,9 +111,14 @@ if (const auto *ND = dyn_cast(D)) attributeOnlyIfTrue("isHidden", ND->isHidden()); - if (D->getLexicalDeclContext() != D->getDeclContext()) - JOS.attribute("parentDeclContext", - createPointerRepresentation(D->getDeclContext())); + if (D->getLexicalDeclContext() != D->getDeclContext()) { + // Because of multiple inheritance, a DeclContext pointer does not produce + // the same pointer representation as a Decl pointer that references the + // same AST Node. + const auto *ParentDeclContextDecl = dyn_cast(D->getDeclContext()); + JOS.attribute("parentDeclContextId", + createPointerRepresentation(ParentDeclContextDecl)); + } addPreviousDeclaration(D); InnerDeclVisitor::Visit(D); Index: clang/test/AST/ast-dump-decl-context-json.cpp =================================================================== --- /dev/null +++ clang/test/AST/ast-dump-decl-context-json.cpp @@ -0,0 +1,286 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -ast-dump=json -ast-dump-filter Test %s | FileCheck %s + +namespace Test { + +namespace NS { +void Function(); +} +void NS::Function() {} + +struct S { + void Method(); +}; +void S::Method() {} + +} // namespace Test + +// CHECK: "kind": "NamespaceDecl", +// CHECK-NEXT: "loc": { +// CHECK-NEXT: "file": "{{.*}}", +// CHECK-NEXT: "line": 3, +// CHECK-NEXT: "col": 11, +// CHECK-NEXT: "tokLen": 4 +// CHECK-NEXT: }, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": { +// CHECK-NEXT: "col": 1, +// CHECK-NEXT: "tokLen": 9 +// CHECK-NEXT: }, +// CHECK-NEXT: "end": { +// CHECK-NEXT: "line": 15, +// CHECK-NEXT: "col": 1, +// CHECK-NEXT: "tokLen": 1 +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "name": "Test", +// CHECK-NEXT: "inner": [ +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x[[NS_ID:.*]]", +// CHECK-NEXT: "kind": "NamespaceDecl", +// CHECK-NEXT: "loc": { +// CHECK-NEXT: "line": 5, +// CHECK-NEXT: "col": 11, +// CHECK-NEXT: "tokLen": 2 +// CHECK-NEXT: }, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": { +// CHECK-NEXT: "col": 1, +// CHECK-NEXT: "tokLen": 9 +// CHECK-NEXT: }, +// CHECK-NEXT: "end": { +// CHECK-NEXT: "line": 7, +// CHECK-NEXT: "col": 1, +// CHECK-NEXT: "tokLen": 1 +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "name": "NS", +// CHECK-NEXT: "inner": [ +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x[[FUNCTION_ID:.*]]", +// CHECK-NEXT: "kind": "FunctionDecl", +// CHECK-NEXT: "loc": { +// CHECK-NEXT: "line": 6, +// CHECK-NEXT: "col": 6, +// CHECK-NEXT: "tokLen": 8 +// CHECK-NEXT: }, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": { +// CHECK-NEXT: "col": 1, +// CHECK-NEXT: "tokLen": 4 +// CHECK-NEXT: }, +// CHECK-NEXT: "end": { +// CHECK-NEXT: "col": 15, +// CHECK-NEXT: "tokLen": 1 +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "name": "Function", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "void ()" +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: ] +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "FunctionDecl", +// CHECK-NEXT: "loc": { +// CHECK-NEXT: "line": 8, +// CHECK-NEXT: "col": 10, +// CHECK-NEXT: "tokLen": 8 +// CHECK-NEXT: }, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": { +// CHECK-NEXT: "col": 1, +// CHECK-NEXT: "tokLen": 4 +// CHECK-NEXT: }, +// CHECK-NEXT: "end": { +// CHECK-NEXT: "col": 22, +// CHECK-NEXT: "tokLen": 1 +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "parentDeclContextId": "0x[[NS_ID]]", +// CHECK-NEXT: "previousDecl": "0x[[FUNCTION_ID]]", +// CHECK-NEXT: "name": "Function", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "void ()" +// CHECK-NEXT: }, +// CHECK-NEXT: "inner": [ +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "CompoundStmt", +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": { +// CHECK-NEXT: "col": 21, +// CHECK-NEXT: "tokLen": 1 +// CHECK-NEXT: }, +// CHECK-NEXT: "end": { +// CHECK-NEXT: "col": 22, +// CHECK-NEXT: "tokLen": 1 +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: ] +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x[[S_ID:.*]]", +// CHECK-NEXT: "kind": "CXXRecordDecl", +// CHECK-NEXT: "loc": { +// CHECK-NEXT: "line": 10, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 1 +// CHECK-NEXT: }, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": { +// CHECK-NEXT: "col": 1, +// CHECK-NEXT: "tokLen": 6 +// CHECK-NEXT: }, +// CHECK-NEXT: "end": { +// CHECK-NEXT: "line": 12, +// CHECK-NEXT: "col": 1, +// CHECK-NEXT: "tokLen": 1 +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "name": "S", +// CHECK-NEXT: "tagUsed": "struct", +// CHECK-NEXT: "completeDefinition": true, +// CHECK-NEXT: "definitionData": { +// CHECK-NEXT: "canConstDefaultInit": true, +// CHECK-NEXT: "canPassInRegisters": true, +// CHECK-NEXT: "copyAssign": { +// CHECK-NEXT: "hasConstParam": true, +// CHECK-NEXT: "implicitHasConstParam": true, +// CHECK-NEXT: "needsImplicit": true, +// CHECK-NEXT: "trivial": true +// CHECK-NEXT: }, +// CHECK-NEXT: "copyCtor": { +// CHECK-NEXT: "hasConstParam": true, +// CHECK-NEXT: "implicitHasConstParam": true, +// CHECK-NEXT: "needsImplicit": true, +// CHECK-NEXT: "simple": true, +// CHECK-NEXT: "trivial": true +// CHECK-NEXT: }, +// CHECK-NEXT: "defaultCtor": { +// CHECK-NEXT: "defaultedIsConstexpr": true, +// CHECK-NEXT: "exists": true, +// CHECK-NEXT: "isConstexpr": true, +// CHECK-NEXT: "needsImplicit": true, +// CHECK-NEXT: "trivial": true +// CHECK-NEXT: }, +// CHECK-NEXT: "dtor": { +// CHECK-NEXT: "irrelevant": true, +// CHECK-NEXT: "needsImplicit": true, +// CHECK-NEXT: "simple": true, +// CHECK-NEXT: "trivial": true +// CHECK-NEXT: }, +// CHECK-NEXT: "hasConstexprNonCopyMoveConstructor": true, +// CHECK-NEXT: "isAggregate": true, +// CHECK-NEXT: "isEmpty": true, +// CHECK-NEXT: "isLiteral": true, +// CHECK-NEXT: "isPOD": true, +// CHECK-NEXT: "isStandardLayout": true, +// CHECK-NEXT: "isTrivial": true, +// CHECK-NEXT: "isTriviallyCopyable": true, +// CHECK-NEXT: "moveAssign": { +// CHECK-NEXT: "exists": true, +// CHECK-NEXT: "needsImplicit": true, +// CHECK-NEXT: "simple": true, +// CHECK-NEXT: "trivial": true +// CHECK-NEXT: }, +// CHECK-NEXT: "moveCtor": { +// CHECK-NEXT: "exists": true, +// CHECK-NEXT: "needsImplicit": true, +// CHECK-NEXT: "simple": true, +// CHECK-NEXT: "trivial": true +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "inner": [ +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "CXXRecordDecl", +// CHECK-NEXT: "loc": { +// CHECK-NEXT: "line": 10, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 1 +// CHECK-NEXT: }, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": { +// CHECK-NEXT: "col": 1, +// CHECK-NEXT: "tokLen": 6 +// CHECK-NEXT: }, +// CHECK-NEXT: "end": { +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 1 +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "isImplicit": true, +// CHECK-NEXT: "name": "S", +// CHECK-NEXT: "tagUsed": "struct" +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x[[METHOD_ID:.*]]", +// CHECK-NEXT: "kind": "CXXMethodDecl", +// CHECK-NEXT: "loc": { +// CHECK-NEXT: "line": 11, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 6 +// CHECK-NEXT: }, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": { +// CHECK-NEXT: "col": 3, +// CHECK-NEXT: "tokLen": 4 +// CHECK-NEXT: }, +// CHECK-NEXT: "end": { +// CHECK-NEXT: "col": 15, +// CHECK-NEXT: "tokLen": 1 +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "name": "Method", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "void ()" +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: ] +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "CXXMethodDecl", +// CHECK-NEXT: "loc": { +// CHECK-NEXT: "line": 13, +// CHECK-NEXT: "col": 9, +// CHECK-NEXT: "tokLen": 6 +// CHECK-NEXT: }, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": { +// CHECK-NEXT: "col": 1, +// CHECK-NEXT: "tokLen": 4 +// CHECK-NEXT: }, +// CHECK-NEXT: "end": { +// CHECK-NEXT: "col": 19, +// CHECK-NEXT: "tokLen": 1 +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "parentDeclContextId": "0x[[S_ID]]", +// CHECK-NEXT: "previousDecl": "0x[[METHOD_ID]]", +// CHECK-NEXT: "name": "Method", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "void ()" +// CHECK-NEXT: }, +// CHECK-NEXT: "inner": [ +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "CompoundStmt", +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": { +// CHECK-NEXT: "col": 18, +// CHECK-NEXT: "tokLen": 1 +// CHECK-NEXT: }, +// CHECK-NEXT: "end": { +// CHECK-NEXT: "col": 19, +// CHECK-NEXT: "tokLen": 1 +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: ] +// CHECK-NEXT: } +// CHECK-NEXT: ] +// CHECK-NEXT: } Index: clang/test/AST/ast-dump-decl-json.c =================================================================== --- clang/test/AST/ast-dump-decl-json.c +++ clang/test/AST/ast-dump-decl-json.c @@ -226,7 +226,7 @@ // CHECK-NEXT: "tokLen": 1 // CHECK-NEXT: } // CHECK-NEXT: }, -// CHECK-NEXT: "parentDeclContext": "0x{{.*}}", +// CHECK-NEXT: "parentDeclContextId": "0x{{.*}}", // CHECK-NEXT: "name": "y", // CHECK-NEXT: "tagUsed": "struct", // CHECK-NEXT: "completeDefinition": true, Index: clang/test/AST/ast-dump-funcs-json.cpp =================================================================== --- clang/test/AST/ast-dump-funcs-json.cpp +++ clang/test/AST/ast-dump-funcs-json.cpp @@ -426,7 +426,7 @@ // CHECK-NEXT: "tokLen": 1 // CHECK-NEXT: } // CHECK-NEXT: }, -// CHECK-NEXT: "parentDeclContext": "0x{{.*}}", +// CHECK-NEXT: "parentDeclContextId": "0x{{.*}}", // CHECK-NEXT: "previousDecl": "0x{{.*}}", // CHECK-NEXT: "name": "Test1", // CHECK-NEXT: "type": { Index: clang/test/AST/ast-dump-template-decls-json.cpp =================================================================== --- clang/test/AST/ast-dump-template-decls-json.cpp +++ clang/test/AST/ast-dump-template-decls-json.cpp @@ -2217,7 +2217,7 @@ // CHECK-NEXT: "tokLen": 1 // CHECK-NEXT: } // CHECK-NEXT: }, -// CHECK-NEXT: "parentDeclContext": "0x{{.*}}", +// CHECK-NEXT: "parentDeclContextId": "0x{{.*}}", // CHECK-NEXT: "previousDecl": "0x{{.*}}", // CHECK-NEXT: "name": "f", // CHECK-NEXT: "inner": [ @@ -2264,7 +2264,7 @@ // CHECK-NEXT: "tokLen": 1 // CHECK-NEXT: } // CHECK-NEXT: }, -// CHECK-NEXT: "parentDeclContext": "0x{{.*}}", +// CHECK-NEXT: "parentDeclContextId": "0x{{.*}}", // CHECK-NEXT: "previousDecl": "0x{{.*}}", // CHECK-NEXT: "name": "f", // CHECK-NEXT: "type": {