Dump actual line numbers when dumping the AST to JSON.

The "line" attribute is now the physical line within the source file for the location. A "presumedLine" attribute is printed when the presumed line number does not match the given source line number. We continue to not print repeated line information in subsequent source locations, but we track presumed and actual lines separately.

llvm-svn: 365919
This commit is contained in:
Aaron Ballman 2019-07-12 16:53:57 +00:00
parent 8b76e622b3
commit 352f0a22b8
3 changed files with 169 additions and 13 deletions

View File

@ -125,7 +125,7 @@ class JSONNodeDumper
PrintingPolicy PrintPolicy; PrintingPolicy PrintPolicy;
const comments::CommandTraits *Traits; const comments::CommandTraits *Traits;
StringRef LastLocFilename; StringRef LastLocFilename;
unsigned LastLocLine; unsigned LastLocLine, LastLocPresumedLine;
using InnerAttrVisitor = ConstAttrVisitor<JSONNodeDumper>; using InnerAttrVisitor = ConstAttrVisitor<JSONNodeDumper>;
using InnerCommentVisitor = using InnerCommentVisitor =
@ -142,7 +142,7 @@ class JSONNodeDumper
} }
// Writes the attributes of a SourceLocation object without. // 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 // Writes the attributes of a SourceLocation to JSON based on its presumed
// spelling location. If the given location represents a macro invocation, // spelling location. If the given location represents a macro invocation,
@ -181,7 +181,7 @@ public:
const PrintingPolicy &PrintPolicy, const PrintingPolicy &PrintPolicy,
const comments::CommandTraits *Traits) const comments::CommandTraits *Traits)
: NodeStreamer(OS), SM(SrcMgr), Ctx(Ctx), PrintPolicy(PrintPolicy), : 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 Attr *A);
void Visit(const Stmt *Node); void Visit(const Stmt *Node);

View File

@ -171,20 +171,28 @@ void JSONNodeDumper::Visit(const GenericSelectionExpr::ConstAssociation &A) {
attributeOnlyIfTrue("selected", A.isSelected()); attributeOnlyIfTrue("selected", A.isSelected());
} }
void JSONNodeDumper::writeBareSourceLocation(SourceLocation Loc) { void JSONNodeDumper::writeBareSourceLocation(SourceLocation Loc,
bool IsSpelling) {
PresumedLoc Presumed = SM.getPresumedLoc(Loc); PresumedLoc Presumed = SM.getPresumedLoc(Loc);
unsigned ActualLine = IsSpelling ? SM.getSpellingLineNumber(Loc)
: SM.getExpansionLineNumber(Loc);
if (Presumed.isValid()) { if (Presumed.isValid()) {
if (LastLocFilename != Presumed.getFilename()) { if (LastLocFilename != Presumed.getFilename()) {
JOS.attribute("file", Presumed.getFilename()); JOS.attribute("file", Presumed.getFilename());
JOS.attribute("line", Presumed.getLine()); JOS.attribute("line", ActualLine);
} else if (LastLocLine != Presumed.getLine()) } else if (LastLocLine != ActualLine)
JOS.attribute("line", Presumed.getLine()); JOS.attribute("line", ActualLine);
unsigned PresumedLine = Presumed.getLine();
if (ActualLine != PresumedLine && LastLocPresumedLine != PresumedLine)
JOS.attribute("presumedLine", PresumedLine);
JOS.attribute("col", Presumed.getColumn()); JOS.attribute("col", Presumed.getColumn());
JOS.attribute("tokLen", JOS.attribute("tokLen",
Lexer::MeasureTokenLength(Loc, SM, Ctx.getLangOpts())); Lexer::MeasureTokenLength(Loc, SM, Ctx.getLangOpts()));
LastLocFilename = Presumed.getFilename(); LastLocFilename = Presumed.getFilename();
LastLocLine = Presumed.getLine(); LastLocPresumedLine = PresumedLine;
LastLocLine = ActualLine;
} }
} }
@ -195,17 +203,18 @@ void JSONNodeDumper::writeSourceLocation(SourceLocation Loc) {
if (Expansion != Spelling) { if (Expansion != Spelling) {
// If the expansion and the spelling are different, output subobjects // If the expansion and the spelling are different, output subobjects
// describing both locations. // describing both locations.
JOS.attributeObject( JOS.attributeObject("spellingLoc", [Spelling, this] {
"spellingLoc", [Spelling, this] { writeBareSourceLocation(Spelling); }); writeBareSourceLocation(Spelling, /*IsSpelling*/ true);
});
JOS.attributeObject("expansionLoc", [Expansion, Loc, this] { JOS.attributeObject("expansionLoc", [Expansion, Loc, this] {
writeBareSourceLocation(Expansion); writeBareSourceLocation(Expansion, /*IsSpelling*/ false);
// If there is a macro expansion, add extra information if the interesting // If there is a macro expansion, add extra information if the interesting
// bit is the macro arg expansion. // bit is the macro arg expansion.
if (SM.isMacroArgExpansion(Loc)) if (SM.isMacroArgExpansion(Loc))
JOS.attribute("isMacroArgExpansion", true); JOS.attribute("isMacroArgExpansion", true);
}); });
} else } else
writeBareSourceLocation(Spelling); writeBareSourceLocation(Spelling, /*IsSpelling*/ true);
} }
void JSONNodeDumper::writeSourceRange(SourceRange R) { void JSONNodeDumper::writeSourceRange(SourceRange R) {

View File

@ -133,6 +133,20 @@ void TestMiscStmts(void) {
({int a = 10; a;}); ({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 // NOTE: CHECK lines have been autogenerated by gen_ast_dump_json_test.py
// using --filters=VarDecl,CompoundStmt // using --filters=VarDecl,CompoundStmt
@ -4777,3 +4791,136 @@ void TestMiscStmts(void) {
// CHECK-NEXT: } // CHECK-NEXT: }
// CHECK-NEXT: ] // 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: }