From: Aaron Ballman Date: Fri, 21 Jun 2019 16:06:09 +0000 (+0000) Subject: Print more type node information when dumping the AST to JSON. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=4089ba457f8ba9db007b3bed0d5b6d92c78e1ab9;p=clang Print more type node information when dumping the AST to JSON. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@364067 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/JSONNodeDumper.h b/include/clang/AST/JSONNodeDumper.h index b8a34aaa29..d04499cd44 100644 --- a/include/clang/AST/JSONNodeDumper.h +++ b/include/clang/AST/JSONNodeDumper.h @@ -211,6 +211,9 @@ public: void VisitInjectedClassNameType(const InjectedClassNameType *ICNT); void VisitObjCInterfaceType(const ObjCInterfaceType *OIT); void VisitPackExpansionType(const PackExpansionType *PET); + void VisitElaboratedType(const ElaboratedType *ET); + void VisitMacroQualifiedType(const MacroQualifiedType *MQT); + void VisitMemberPointerType(const MemberPointerType *MPT); void VisitNamedDecl(const NamedDecl *ND); void VisitTypedefDecl(const TypedefDecl *TD); diff --git a/lib/AST/JSONNodeDumper.cpp b/lib/AST/JSONNodeDumper.cpp index fd8569658a..550f6ef94e 100644 --- a/lib/AST/JSONNodeDumper.cpp +++ b/lib/AST/JSONNodeDumper.cpp @@ -611,6 +611,26 @@ void JSONNodeDumper::VisitPackExpansionType(const PackExpansionType *PET) { JOS.attribute("numExpansions", *N); } +void JSONNodeDumper::VisitElaboratedType(const ElaboratedType *ET) { + if (const NestedNameSpecifier *NNS = ET->getQualifier()) { + std::string Str; + llvm::raw_string_ostream OS(Str); + NNS->print(OS, PrintPolicy, /*ResolveTemplateArgs*/ true); + JOS.attribute("qualifier", OS.str()); + } + if (const TagDecl *TD = ET->getOwnedTagDecl()) + JOS.attribute("ownedTagDecl", createBareDeclRef(TD)); +} + +void JSONNodeDumper::VisitMacroQualifiedType(const MacroQualifiedType *MQT) { + JOS.attribute("macroName", MQT->getMacroIdentifier()->getName()); +} + +void JSONNodeDumper::VisitMemberPointerType(const MemberPointerType *MPT) { + attributeOnlyIfTrue("isData", MPT->isMemberDataPointer()); + attributeOnlyIfTrue("isFunction", MPT->isMemberFunctionPointer()); +} + void JSONNodeDumper::VisitNamedDecl(const NamedDecl *ND) { if (ND && ND->getDeclName()) JOS.attribute("name", ND->getNameAsString()); diff --git a/test/AST/ast-dump-types-json.cpp b/test/AST/ast-dump-types-json.cpp new file mode 100644 index 0000000000..64198c4aca --- /dev/null +++ b/test/AST/ast-dump-types-json.cpp @@ -0,0 +1,358 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fsyntax-only -ast-dump=json -ast-dump-filter Test %s | FileCheck %s + +namespace NS { +struct S {}; +} + +struct T { + int I; + void F(); +}; + +typedef struct T TestElaboratedType1; +typedef NS::S TestElaboratedType2; + +#define CDECL __attribute__((cdecl)) +typedef void (CDECL *TestMacroQualifiedType)(); + +typedef void (T::* TestMemberFunctionPointerType)(); +typedef int T::*TestMemberDataPointerType; + +// NOTE: CHECK lines have been autogenerated by gen_ast_dump_json_test.py + + +// CHECK: "kind": "TypedefDecl", +// CHECK-NEXT: "loc": { +// CHECK-NEXT: "col": 18, +// CHECK-NEXT: "file": "{{.*}}", +// CHECK-NEXT: "line": 12 +// CHECK-NEXT: }, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": { +// CHECK-NEXT: "col": 1, +// CHECK-NEXT: "file": "{{.*}}", +// CHECK-NEXT: "line": 12 +// CHECK-NEXT: }, +// CHECK-NEXT: "end": { +// CHECK-NEXT: "col": 18, +// CHECK-NEXT: "file": "{{.*}}", +// CHECK-NEXT: "line": 12 +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "name": "TestElaboratedType1", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "desugaredQualType": "T", +// CHECK-NEXT: "qualType": "struct T" +// CHECK-NEXT: }, +// CHECK-NEXT: "inner": [ +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "ElaboratedType", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "struct T" +// CHECK-NEXT: }, +// CHECK-NEXT: "inner": [ +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "RecordType", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "T" +// CHECK-NEXT: }, +// CHECK-NEXT: "decl": { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "CXXRecordDecl", +// CHECK-NEXT: "name": "T" +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: ] +// CHECK-NEXT: } +// CHECK-NEXT: ] +// CHECK-NEXT: } + + +// CHECK: "kind": "TypedefDecl", +// CHECK-NEXT: "loc": { +// CHECK-NEXT: "col": 15, +// CHECK-NEXT: "file": "{{.*}}", +// CHECK-NEXT: "line": 13 +// CHECK-NEXT: }, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": { +// CHECK-NEXT: "col": 1, +// CHECK-NEXT: "file": "{{.*}}", +// CHECK-NEXT: "line": 13 +// CHECK-NEXT: }, +// CHECK-NEXT: "end": { +// CHECK-NEXT: "col": 15, +// CHECK-NEXT: "file": "{{.*}}", +// CHECK-NEXT: "line": 13 +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "name": "TestElaboratedType2", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "desugaredQualType": "NS::S", +// CHECK-NEXT: "qualType": "NS::S" +// CHECK-NEXT: }, +// CHECK-NEXT: "inner": [ +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "ElaboratedType", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "NS::S" +// CHECK-NEXT: }, +// CHECK-NEXT: "qualifier": "NS::", +// CHECK-NEXT: "inner": [ +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "RecordType", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "NS::S" +// CHECK-NEXT: }, +// CHECK-NEXT: "decl": { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "CXXRecordDecl", +// CHECK-NEXT: "name": "S" +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: ] +// CHECK-NEXT: } +// CHECK-NEXT: ] +// CHECK-NEXT: } + + +// CHECK: "kind": "TypedefDecl", +// CHECK-NEXT: "loc": { +// CHECK-NEXT: "col": 22, +// CHECK-NEXT: "file": "{{.*}}", +// CHECK-NEXT: "line": 16 +// CHECK-NEXT: }, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": { +// CHECK-NEXT: "col": 1, +// CHECK-NEXT: "file": "{{.*}}", +// CHECK-NEXT: "line": 16 +// CHECK-NEXT: }, +// CHECK-NEXT: "end": { +// CHECK-NEXT: "col": 22, +// CHECK-NEXT: "file": "{{.*}}", +// CHECK-NEXT: "line": 16 +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "name": "TestMacroQualifiedType", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "CDECL void (*)()" +// CHECK-NEXT: }, +// CHECK-NEXT: "inner": [ +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "PointerType", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "CDECL void (*)()" +// CHECK-NEXT: }, +// CHECK-NEXT: "inner": [ +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "MacroQualifiedType", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "CDECL void ()" +// CHECK-NEXT: }, +// CHECK-NEXT: "macroName": "CDECL", +// CHECK-NEXT: "inner": [ +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "AttributedType", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "void () __attribute__((cdecl))" +// CHECK-NEXT: }, +// CHECK-NEXT: "inner": [ +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "ParenType", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "void ()" +// CHECK-NEXT: }, +// CHECK-NEXT: "inner": [ +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "FunctionProtoType", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "void ()" +// CHECK-NEXT: }, +// CHECK-NEXT: "cc": "cdecl", +// CHECK-NEXT: "inner": [ +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "BuiltinType", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "void" +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: ] +// CHECK-NEXT: } +// CHECK-NEXT: ] +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "ParenType", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "void ()" +// CHECK-NEXT: }, +// CHECK-NEXT: "inner": [ +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "FunctionProtoType", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "void ()" +// CHECK-NEXT: }, +// CHECK-NEXT: "cc": "cdecl", +// CHECK-NEXT: "inner": [ +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "BuiltinType", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "void" +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: ] +// CHECK-NEXT: } +// CHECK-NEXT: ] +// CHECK-NEXT: } +// CHECK-NEXT: ] +// CHECK-NEXT: } +// CHECK-NEXT: ] +// CHECK-NEXT: } +// CHECK-NEXT: ] +// CHECK-NEXT: } +// CHECK-NEXT: ] +// CHECK-NEXT: } + + +// CHECK: "kind": "TypedefDecl", +// CHECK-NEXT: "loc": { +// CHECK-NEXT: "col": 20, +// CHECK-NEXT: "file": "{{.*}}", +// CHECK-NEXT: "line": 18 +// CHECK-NEXT: }, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": { +// CHECK-NEXT: "col": 1, +// CHECK-NEXT: "file": "{{.*}}", +// CHECK-NEXT: "line": 18 +// CHECK-NEXT: }, +// CHECK-NEXT: "end": { +// CHECK-NEXT: "col": 51, +// CHECK-NEXT: "file": "{{.*}}", +// CHECK-NEXT: "line": 18 +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "name": "TestMemberFunctionPointerType", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "void (T::*)()" +// CHECK-NEXT: }, +// CHECK-NEXT: "inner": [ +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "MemberPointerType", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "void (T::*)()" +// CHECK-NEXT: }, +// CHECK-NEXT: "isFunction": true, +// CHECK-NEXT: "inner": [ +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "RecordType", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "T" +// CHECK-NEXT: }, +// CHECK-NEXT: "decl": { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "CXXRecordDecl", +// CHECK-NEXT: "name": "T" +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "ParenType", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "void ()" +// CHECK-NEXT: }, +// CHECK-NEXT: "inner": [ +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "FunctionProtoType", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "void ()" +// CHECK-NEXT: }, +// CHECK-NEXT: "cc": "cdecl", +// CHECK-NEXT: "inner": [ +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "BuiltinType", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "void" +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: ] +// CHECK-NEXT: } +// CHECK-NEXT: ] +// CHECK-NEXT: } +// CHECK-NEXT: ] +// CHECK-NEXT: } +// CHECK-NEXT: ] +// CHECK-NEXT: } + + +// CHECK: "kind": "TypedefDecl", +// CHECK-NEXT: "loc": { +// CHECK-NEXT: "col": 17, +// CHECK-NEXT: "file": "{{.*}}", +// CHECK-NEXT: "line": 19 +// CHECK-NEXT: }, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": { +// CHECK-NEXT: "col": 1, +// CHECK-NEXT: "file": "{{.*}}", +// CHECK-NEXT: "line": 19 +// CHECK-NEXT: }, +// CHECK-NEXT: "end": { +// CHECK-NEXT: "col": 17, +// CHECK-NEXT: "file": "{{.*}}", +// CHECK-NEXT: "line": 19 +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "name": "TestMemberDataPointerType", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "int T::*" +// CHECK-NEXT: }, +// CHECK-NEXT: "inner": [ +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "MemberPointerType", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "int T::*" +// CHECK-NEXT: }, +// CHECK-NEXT: "isData": true, +// CHECK-NEXT: "inner": [ +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "RecordType", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "T" +// CHECK-NEXT: }, +// CHECK-NEXT: "decl": { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "CXXRecordDecl", +// CHECK-NEXT: "name": "T" +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "BuiltinType", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "int" +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: ] +// CHECK-NEXT: } +// CHECK-NEXT: ] +// CHECK-NEXT: }