diff options
-rw-r--r-- | clang/include/clang/AST/JSONNodeDumper.h | 6 | ||||
-rw-r--r-- | clang/lib/AST/JSONNodeDumper.cpp | 29 | ||||
-rw-r--r-- | clang/test/AST/ast-dump-stmt-json.c | 147 |
3 files changed, 169 insertions, 13 deletions
diff --git a/clang/include/clang/AST/JSONNodeDumper.h b/clang/include/clang/AST/JSONNodeDumper.h index fe155adda0f..238e43aad78 100644 --- a/clang/include/clang/AST/JSONNodeDumper.h +++ b/clang/include/clang/AST/JSONNodeDumper.h @@ -125,7 +125,7 @@ class JSONNodeDumper PrintingPolicy PrintPolicy; const comments::CommandTraits *Traits; StringRef LastLocFilename; - unsigned LastLocLine; + unsigned LastLocLine, LastLocPresumedLine; using InnerAttrVisitor = ConstAttrVisitor<JSONNodeDumper>; using InnerCommentVisitor = @@ -142,7 +142,7 @@ class JSONNodeDumper } // Writes the attributes of a SourceLocation object without. - void writeBareSourceLocation(SourceLocation Loc); + void writeBareSourceLocation(SourceLocation Loc, bool IsSpelling); // Writes the attributes of a SourceLocation to JSON based on its presumed // spelling location. If the given location represents a macro invocation, @@ -181,7 +181,7 @@ public: const PrintingPolicy &PrintPolicy, const comments::CommandTraits *Traits) : NodeStreamer(OS), SM(SrcMgr), Ctx(Ctx), PrintPolicy(PrintPolicy), - Traits(Traits), LastLocLine(0) {} + Traits(Traits), LastLocLine(0), LastLocPresumedLine(0) {} void Visit(const Attr *A); void Visit(const Stmt *Node); diff --git a/clang/lib/AST/JSONNodeDumper.cpp b/clang/lib/AST/JSONNodeDumper.cpp index 60f3c0f8601..04b933b0fb3 100644 --- a/clang/lib/AST/JSONNodeDumper.cpp +++ b/clang/lib/AST/JSONNodeDumper.cpp @@ -171,20 +171,28 @@ void JSONNodeDumper::Visit(const GenericSelectionExpr::ConstAssociation &A) { attributeOnlyIfTrue("selected", A.isSelected()); } -void JSONNodeDumper::writeBareSourceLocation(SourceLocation Loc) { +void JSONNodeDumper::writeBareSourceLocation(SourceLocation Loc, + bool IsSpelling) { PresumedLoc Presumed = SM.getPresumedLoc(Loc); - + unsigned ActualLine = IsSpelling ? SM.getSpellingLineNumber(Loc) + : SM.getExpansionLineNumber(Loc); if (Presumed.isValid()) { if (LastLocFilename != Presumed.getFilename()) { JOS.attribute("file", Presumed.getFilename()); - JOS.attribute("line", Presumed.getLine()); - } else if (LastLocLine != Presumed.getLine()) - JOS.attribute("line", Presumed.getLine()); + JOS.attribute("line", ActualLine); + } else if (LastLocLine != ActualLine) + JOS.attribute("line", ActualLine); + + unsigned PresumedLine = Presumed.getLine(); + if (ActualLine != PresumedLine && LastLocPresumedLine != PresumedLine) + JOS.attribute("presumedLine", PresumedLine); + JOS.attribute("col", Presumed.getColumn()); JOS.attribute("tokLen", Lexer::MeasureTokenLength(Loc, SM, Ctx.getLangOpts())); LastLocFilename = Presumed.getFilename(); - LastLocLine = Presumed.getLine(); + LastLocPresumedLine = PresumedLine; + LastLocLine = ActualLine; } } @@ -195,17 +203,18 @@ void JSONNodeDumper::writeSourceLocation(SourceLocation Loc) { if (Expansion != Spelling) { // If the expansion and the spelling are different, output subobjects // describing both locations. - JOS.attributeObject( - "spellingLoc", [Spelling, this] { writeBareSourceLocation(Spelling); }); + JOS.attributeObject("spellingLoc", [Spelling, this] { + writeBareSourceLocation(Spelling, /*IsSpelling*/ true); + }); JOS.attributeObject("expansionLoc", [Expansion, Loc, this] { - writeBareSourceLocation(Expansion); + writeBareSourceLocation(Expansion, /*IsSpelling*/ false); // If there is a macro expansion, add extra information if the interesting // bit is the macro arg expansion. if (SM.isMacroArgExpansion(Loc)) JOS.attribute("isMacroArgExpansion", true); }); } else - writeBareSourceLocation(Spelling); + writeBareSourceLocation(Spelling, /*IsSpelling*/ true); } void JSONNodeDumper::writeSourceRange(SourceRange R) { diff --git a/clang/test/AST/ast-dump-stmt-json.c b/clang/test/AST/ast-dump-stmt-json.c index ed1ccc9be0c..03552a382f1 100644 --- a/clang/test/AST/ast-dump-stmt-json.c +++ b/clang/test/AST/ast-dump-stmt-json.c @@ -133,6 +133,20 @@ void TestMiscStmts(void) { ({int a = 10; a;}); } +void TestLineNumbers(void) { + int a; + +#define FOO(x) x + +#line 100000 + int b; + +#line 200000 + FOO(1); + +#undef FOO +} + // NOTE: CHECK lines have been autogenerated by gen_ast_dump_json_test.py // using --filters=VarDecl,CompoundStmt @@ -4777,3 +4791,136 @@ void TestMiscStmts(void) { // CHECK-NEXT: } // CHECK-NEXT: ] // CHECK-NEXT: } + + +// CHECK: "kind": "CompoundStmt", +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": { +// CHECK-NEXT: "line": 136, +// CHECK-NEXT: "col": 28, +// CHECK-NEXT: "tokLen": 1 +// CHECK-NEXT: }, +// CHECK-NEXT: "end": { +// CHECK-NEXT: "line": 148, +// CHECK-NEXT: "presumedLine": 200003, +// CHECK-NEXT: "col": 1, +// CHECK-NEXT: "tokLen": 1 +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "inner": [ +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "DeclStmt", +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": { +// CHECK-NEXT: "line": 137, +// CHECK-NEXT: "col": 3, +// CHECK-NEXT: "tokLen": 3 +// CHECK-NEXT: }, +// CHECK-NEXT: "end": { +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 1 +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "inner": [ +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "VarDecl", +// CHECK-NEXT: "loc": { +// CHECK-NEXT: "col": 7, +// CHECK-NEXT: "tokLen": 1 +// CHECK-NEXT: }, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": { +// CHECK-NEXT: "col": 3, +// CHECK-NEXT: "tokLen": 3 +// CHECK-NEXT: }, +// CHECK-NEXT: "end": { +// CHECK-NEXT: "col": 7, +// CHECK-NEXT: "tokLen": 1 +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "name": "a", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "int" +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: ] +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "DeclStmt", +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": { +// CHECK-NEXT: "line": 142, +// CHECK-NEXT: "presumedLine": 100000, +// CHECK-NEXT: "col": 3, +// CHECK-NEXT: "tokLen": 3 +// CHECK-NEXT: }, +// CHECK-NEXT: "end": { +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 1 +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "inner": [ +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "VarDecl", +// CHECK-NEXT: "loc": { +// CHECK-NEXT: "col": 7, +// CHECK-NEXT: "tokLen": 1 +// CHECK-NEXT: }, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": { +// CHECK-NEXT: "col": 3, +// CHECK-NEXT: "tokLen": 3 +// CHECK-NEXT: }, +// CHECK-NEXT: "end": { +// CHECK-NEXT: "col": 7, +// CHECK-NEXT: "tokLen": 1 +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "name": "b", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "int" +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: ] +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "IntegerLiteral", +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": { +// CHECK-NEXT: "spellingLoc": { +// CHECK-NEXT: "line": 145, +// CHECK-NEXT: "presumedLine": 200000, +// CHECK-NEXT: "col": 7, +// CHECK-NEXT: "tokLen": 1 +// CHECK-NEXT: }, +// CHECK-NEXT: "expansionLoc": { +// CHECK-NEXT: "col": 3, +// CHECK-NEXT: "tokLen": 3, +// CHECK-NEXT: "isMacroArgExpansion": true +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "end": { +// CHECK-NEXT: "spellingLoc": { +// CHECK-NEXT: "col": 7, +// CHECK-NEXT: "tokLen": 1 +// CHECK-NEXT: }, +// CHECK-NEXT: "expansionLoc": { +// CHECK-NEXT: "col": 3, +// CHECK-NEXT: "tokLen": 3, +// CHECK-NEXT: "isMacroArgExpansion": true +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "int" +// CHECK-NEXT: }, +// CHECK-NEXT: "valueCategory": "rvalue", +// CHECK-NEXT: "value": "1" +// CHECK-NEXT: } +// CHECK-NEXT: ] +// CHECK-NEXT: } |