From: Aaron Ballman Date: Mon, 20 May 2019 16:46:44 +0000 (+0000) Subject: Dump macro expansion information as needed when outputting the AST to JSON. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=84671b19e00952930c253709a0450ee67fa51f7b;p=clang Dump macro expansion information as needed when outputting the AST to JSON. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@361172 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/JSONNodeDumper.h b/include/clang/AST/JSONNodeDumper.h index 283147517d..85b60ec8db 100644 --- a/include/clang/AST/JSONNodeDumper.h +++ b/include/clang/AST/JSONNodeDumper.h @@ -132,6 +132,12 @@ class JSONNodeDumper JOS.attribute(Key, Value); } + // Creates a single SourceLocation JSON representation of the given location. + llvm::json::Object createBareSourceLocation(SourceLocation Loc); + // Creates a JSON representation of a SourceLocation based on its presumed + // spelling location. If the given location represents a macro invocation, + // this outputs two sub-objects: one for the spelling and one for the + // expansion location. llvm::json::Object createSourceLocation(SourceLocation Loc); llvm::json::Object createSourceRange(SourceRange R); std::string createPointerRepresentation(const void *Ptr); diff --git a/lib/AST/JSONNodeDumper.cpp b/lib/AST/JSONNodeDumper.cpp index ce003ad7c3..37040eaaab 100644 --- a/lib/AST/JSONNodeDumper.cpp +++ b/lib/AST/JSONNodeDumper.cpp @@ -146,9 +146,9 @@ void JSONNodeDumper::Visit(const GenericSelectionExpr::ConstAssociation &A) { attributeOnlyIfTrue("selected", A.isSelected()); } -llvm::json::Object JSONNodeDumper::createSourceLocation(SourceLocation Loc) { - SourceLocation Spelling = SM.getSpellingLoc(Loc); - PresumedLoc Presumed = SM.getPresumedLoc(Spelling); +llvm::json::Object +JSONNodeDumper::createBareSourceLocation(SourceLocation Loc) { + PresumedLoc Presumed = SM.getPresumedLoc(Loc); if (Presumed.isInvalid()) return llvm::json::Object{}; @@ -158,6 +158,28 @@ llvm::json::Object JSONNodeDumper::createSourceLocation(SourceLocation Loc) { {"col", Presumed.getColumn()}}; } +llvm::json::Object JSONNodeDumper::createSourceLocation(SourceLocation Loc) { + SourceLocation Spelling = SM.getSpellingLoc(Loc); + SourceLocation Expansion = SM.getExpansionLoc(Loc); + + llvm::json::Object SLoc = createBareSourceLocation(Spelling); + if (Expansion != Spelling) { + // If the expansion and the spelling are different, output subobjects + // describing both locations. + llvm::json::Object ELoc = createBareSourceLocation(Expansion); + + // If there is a macro expansion, add extra information if the interesting + // bit is the macro arg expansion. + if (SM.isMacroArgExpansion(Loc)) + ELoc["isMacroArgExpansion"] = true; + + return llvm::json::Object{{"spellingLoc", std::move(SLoc)}, + {"expansionLoc", std::move(ELoc)}}; + } + + return SLoc; +} + llvm::json::Object JSONNodeDumper::createSourceRange(SourceRange R) { return llvm::json::Object{{"begin", createSourceLocation(R.getBegin())}, {"end", createSourceLocation(R.getEnd())}}; diff --git a/test/AST/ast-dump-macro-json.c b/test/AST/ast-dump-macro-json.c new file mode 100644 index 0000000000..14b88adcfa --- /dev/null +++ b/test/AST/ast-dump-macro-json.c @@ -0,0 +1,179 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -ast-dump=json %s | FileCheck %s + +#define FOO frobble +#define BAR FOO + +void FOO(void); +void BAR(void); + +#define BING(x) x + +void BING(quux)(void); + +#define BLIP(x, y) x ## y +#define BLAP(x, y) BLIP(x, y) + +void BLAP(foo, __COUNTER__)(void); +void BLAP(foo, __COUNTER__)(void); + + +// CHECK: "kind": "FunctionDecl", +// CHECK-NEXT: "loc": { +// CHECK-NEXT: "expansionLoc": { +// CHECK-NEXT: "col": 6, +// CHECK-NEXT: "file": "{{.*}}", +// CHECK-NEXT: "line": 6 +// CHECK-NEXT: }, +// CHECK-NEXT: "spellingLoc": { +// CHECK-NEXT: "col": 13, +// CHECK-NEXT: "file": "{{.*}}", +// CHECK-NEXT: "line": 3 +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": { +// CHECK-NEXT: "col": 1, +// CHECK-NEXT: "file": "{{.*}}", +// CHECK-NEXT: "line": 6 +// CHECK-NEXT: }, +// CHECK-NEXT: "end": { +// CHECK-NEXT: "col": 14, +// CHECK-NEXT: "file": "{{.*}}", +// CHECK-NEXT: "line": 6 +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "name": "frobble", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "void (void)" +// CHECK-NEXT: } +// CHECK-NEXT: } + + +// CHECK: "kind": "FunctionDecl", +// CHECK-NEXT: "loc": { +// CHECK-NEXT: "expansionLoc": { +// CHECK-NEXT: "col": 6, +// CHECK-NEXT: "file": "{{.*}}", +// CHECK-NEXT: "line": 7 +// CHECK-NEXT: }, +// CHECK-NEXT: "spellingLoc": { +// CHECK-NEXT: "col": 13, +// CHECK-NEXT: "file": "{{.*}}", +// CHECK-NEXT: "line": 3 +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": { +// CHECK-NEXT: "col": 1, +// CHECK-NEXT: "file": "{{.*}}", +// CHECK-NEXT: "line": 7 +// CHECK-NEXT: }, +// CHECK-NEXT: "end": { +// CHECK-NEXT: "col": 14, +// CHECK-NEXT: "file": "{{.*}}", +// CHECK-NEXT: "line": 7 +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "previousDecl": "0x{{.*}}", +// CHECK-NEXT: "name": "frobble", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "void (void)" +// CHECK-NEXT: } +// CHECK-NEXT: } + + +// CHECK: "kind": "FunctionDecl", +// CHECK-NEXT: "loc": { +// CHECK-NEXT: "expansionLoc": { +// CHECK-NEXT: "col": 6, +// CHECK-NEXT: "file": "{{.*}}", +// CHECK-NEXT: "isMacroArgExpansion": true, +// CHECK-NEXT: "line": 11 +// CHECK-NEXT: }, +// CHECK-NEXT: "spellingLoc": { +// CHECK-NEXT: "col": 11, +// CHECK-NEXT: "file": "{{.*}}", +// CHECK-NEXT: "line": 11 +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": { +// CHECK-NEXT: "col": 1, +// CHECK-NEXT: "file": "{{.*}}", +// CHECK-NEXT: "line": 11 +// CHECK-NEXT: }, +// CHECK-NEXT: "end": { +// CHECK-NEXT: "col": 21, +// CHECK-NEXT: "file": "{{.*}}", +// CHECK-NEXT: "line": 11 +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "name": "quux", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "void (void)" +// CHECK-NEXT: } +// CHECK-NEXT: } + + +// CHECK: "kind": "FunctionDecl", +// CHECK-NEXT: "loc": { +// CHECK-NEXT: "expansionLoc": { +// CHECK-NEXT: "col": 6, +// CHECK-NEXT: "file": "{{.*}}", +// CHECK-NEXT: "line": 16 +// CHECK-NEXT: }, +// CHECK-NEXT: "spellingLoc": { +// CHECK-NEXT: "col": 1, +// CHECK-NEXT: "file": "", +// CHECK-NEXT: "line": 3 +// CHECK-NEXT: } +// 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": 33, +// CHECK-NEXT: "file": "{{.*}}", +// CHECK-NEXT: "line": 16 +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "name": "foo0", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "void (void)" +// CHECK-NEXT: } +// CHECK-NEXT: } + + +// CHECK: "kind": "FunctionDecl", +// CHECK-NEXT: "loc": { +// CHECK-NEXT: "expansionLoc": { +// CHECK-NEXT: "col": 6, +// CHECK-NEXT: "file": "{{.*}}", +// CHECK-NEXT: "line": 17 +// CHECK-NEXT: }, +// CHECK-NEXT: "spellingLoc": { +// CHECK-NEXT: "col": 1, +// CHECK-NEXT: "file": "", +// CHECK-NEXT: "line": 5 +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": { +// CHECK-NEXT: "col": 1, +// CHECK-NEXT: "file": "{{.*}}", +// CHECK-NEXT: "line": 17 +// CHECK-NEXT: }, +// CHECK-NEXT: "end": { +// CHECK-NEXT: "col": 33, +// CHECK-NEXT: "file": "{{.*}}", +// CHECK-NEXT: "line": 17 +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "name": "foo1", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "void (void)" +// CHECK-NEXT: } +// CHECK-NEXT: }