From 40e3760472eae18919f4be8906869701db8f8f03 Mon Sep 17 00:00:00 2001 From: Aaron Ballman Date: Wed, 4 Sep 2019 20:30:00 +0000 Subject: [PATCH] Generate parent context id from Decl* instead of DeclContext*. Because of multiple inheritance, a DeclContext pointer does not produce the same pointer representation as a Decl pointer that references the same AST Node. When dumping the parentDeclContextId field of a node, convert the pointer to Decl* first, so the id can be used to find the AST node it references. Patch by Bert Belder. llvm-svn: 370970 --- clang/lib/AST/JSONNodeDumper.cpp | 11 +- clang/test/AST/ast-dump-decl-context-json.cpp | 286 ++++++++++++++++++ clang/test/AST/ast-dump-decl-json.c | 2 +- clang/test/AST/ast-dump-funcs-json.cpp | 2 +- .../test/AST/ast-dump-template-decls-json.cpp | 4 +- 5 files changed, 298 insertions(+), 7 deletions(-) create mode 100644 clang/test/AST/ast-dump-decl-context-json.cpp diff --git a/clang/lib/AST/JSONNodeDumper.cpp b/clang/lib/AST/JSONNodeDumper.cpp index 68f5b2977553..b7e8c882244e 100644 --- a/clang/lib/AST/JSONNodeDumper.cpp +++ b/clang/lib/AST/JSONNodeDumper.cpp @@ -111,9 +111,14 @@ void JSONNodeDumper::Visit(const Decl *D) { 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); diff --git a/clang/test/AST/ast-dump-decl-context-json.cpp b/clang/test/AST/ast-dump-decl-context-json.cpp new file mode 100644 index 000000000000..beb72ef4401f --- /dev/null +++ b/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: } diff --git a/clang/test/AST/ast-dump-decl-json.c b/clang/test/AST/ast-dump-decl-json.c index 0321a6650b76..cfa17a06f347 100644 --- a/clang/test/AST/ast-dump-decl-json.c +++ b/clang/test/AST/ast-dump-decl-json.c @@ -226,7 +226,7 @@ void testParmVarDecl(int TestParmVarDecl); // 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, diff --git a/clang/test/AST/ast-dump-funcs-json.cpp b/clang/test/AST/ast-dump-funcs-json.cpp index b42be3b1afbd..ab5623ebff30 100644 --- a/clang/test/AST/ast-dump-funcs-json.cpp +++ b/clang/test/AST/ast-dump-funcs-json.cpp @@ -426,7 +426,7 @@ int main() { // 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": { diff --git a/clang/test/AST/ast-dump-template-decls-json.cpp b/clang/test/AST/ast-dump-template-decls-json.cpp index a6825c0d06c0..21574af2c4a2 100644 --- a/clang/test/AST/ast-dump-template-decls-json.cpp +++ b/clang/test/AST/ast-dump-template-decls-json.cpp @@ -2217,7 +2217,7 @@ void V::f() {} // 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 @@ void V::f() {} // 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": {