From fa6c157ebeef55fd1e00266d1d1ad6aaa6161ef2 Mon Sep 17 00:00:00 2001 From: Aaron Ballman Date: Tue, 3 Dec 2019 13:04:45 -0500 Subject: [PATCH] Differentiate between the presumed and actual file when dumping the AST to JSON Currently, when dumping the AST to JSON, the presumed file is what is included when dumping a source location. This patch changes the behavior to instead dump the actual file, and only dump a presumed file name when it differs from the actual file. This also corrects an issue with the test script generator that would prevent it from working on Windows due to file permissions issues. --- clang/include/clang/AST/JSONNodeDumper.h | 2 +- clang/lib/AST/JSONNodeDumper.cpp | 13 +- clang/test/AST/ast-dump-file-line-json.c | 309 +++++++++++++++++++++++++++++++ clang/test/AST/gen_ast_dump_json_test.py | 4 +- 4 files changed, 323 insertions(+), 5 deletions(-) create mode 100644 clang/test/AST/ast-dump-file-line-json.c diff --git a/clang/include/clang/AST/JSONNodeDumper.h b/clang/include/clang/AST/JSONNodeDumper.h index 37ab8c0..4023e02 100644 --- a/clang/include/clang/AST/JSONNodeDumper.h +++ b/clang/include/clang/AST/JSONNodeDumper.h @@ -126,7 +126,7 @@ class JSONNodeDumper ASTNameGenerator ASTNameGen; PrintingPolicy PrintPolicy; const comments::CommandTraits *Traits; - StringRef LastLocFilename; + StringRef LastLocFilename, LastLocPresumedFilename; unsigned LastLocLine, LastLocPresumedLine; using InnerAttrVisitor = ConstAttrVisitor; diff --git a/clang/lib/AST/JSONNodeDumper.cpp b/clang/lib/AST/JSONNodeDumper.cpp index 274cc25..40c6c83 100644 --- a/clang/lib/AST/JSONNodeDumper.cpp +++ b/clang/lib/AST/JSONNodeDumper.cpp @@ -202,14 +202,20 @@ void JSONNodeDumper::writeBareSourceLocation(SourceLocation Loc, PresumedLoc Presumed = SM.getPresumedLoc(Loc); unsigned ActualLine = IsSpelling ? SM.getSpellingLineNumber(Loc) : SM.getExpansionLineNumber(Loc); + StringRef ActualFile = SM.getBufferName(Loc); + if (Presumed.isValid()) { JOS.attribute("offset", SM.getDecomposedLoc(Loc).second); - if (LastLocFilename != Presumed.getFilename()) { - JOS.attribute("file", Presumed.getFilename()); + if (LastLocFilename != ActualFile) { + JOS.attribute("file", ActualFile); JOS.attribute("line", ActualLine); } else if (LastLocLine != ActualLine) JOS.attribute("line", ActualLine); + StringRef PresumedFile = Presumed.getFilename(); + if (PresumedFile != ActualFile && LastLocPresumedFilename != PresumedFile) + JOS.attribute("presumedFile", PresumedFile); + unsigned PresumedLine = Presumed.getLine(); if (ActualLine != PresumedLine && LastLocPresumedLine != PresumedLine) JOS.attribute("presumedLine", PresumedLine); @@ -217,7 +223,8 @@ void JSONNodeDumper::writeBareSourceLocation(SourceLocation Loc, JOS.attribute("col", Presumed.getColumn()); JOS.attribute("tokLen", Lexer::MeasureTokenLength(Loc, SM, Ctx.getLangOpts())); - LastLocFilename = Presumed.getFilename(); + LastLocFilename = ActualFile; + LastLocPresumedFilename = PresumedFile; LastLocPresumedLine = PresumedLine; LastLocLine = ActualLine; diff --git a/clang/test/AST/ast-dump-file-line-json.c b/clang/test/AST/ast-dump-file-line-json.c new file mode 100644 index 0000000..11e85b8 --- /dev/null +++ b/clang/test/AST/ast-dump-file-line-json.c @@ -0,0 +1,309 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -ast-dump=json %s | FileCheck %s + +#line 4 "test.c" +int a; + +#line 32 "bar.h" +int b; +int c; + +#line 11 "test.c" +int d; +int e; +// NOTE: CHECK lines have been autogenerated by gen_ast_dump_json_test.py + + +// CHECK: "kind": "TranslationUnitDecl", +// CHECK-NEXT: "loc": {}, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": {}, +// CHECK-NEXT: "end": {} +// CHECK-NEXT: }, +// CHECK-NEXT: "inner": [ +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "TypedefDecl", +// CHECK-NEXT: "loc": {}, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": {}, +// CHECK-NEXT: "end": {} +// CHECK-NEXT: }, +// CHECK-NEXT: "isImplicit": true, +// CHECK-NEXT: "name": "__int128_t", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "__int128" +// CHECK-NEXT: }, +// CHECK-NEXT: "inner": [ +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "BuiltinType", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "__int128" +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: ] +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "TypedefDecl", +// CHECK-NEXT: "loc": {}, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": {}, +// CHECK-NEXT: "end": {} +// CHECK-NEXT: }, +// CHECK-NEXT: "isImplicit": true, +// CHECK-NEXT: "name": "__uint128_t", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "unsigned __int128" +// CHECK-NEXT: }, +// CHECK-NEXT: "inner": [ +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "BuiltinType", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "unsigned __int128" +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: ] +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "TypedefDecl", +// CHECK-NEXT: "loc": {}, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": {}, +// CHECK-NEXT: "end": {} +// CHECK-NEXT: }, +// CHECK-NEXT: "isImplicit": true, +// CHECK-NEXT: "name": "__NSConstantString", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "struct __NSConstantString_tag" +// CHECK-NEXT: }, +// CHECK-NEXT: "inner": [ +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "RecordType", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "struct __NSConstantString_tag" +// CHECK-NEXT: }, +// CHECK-NEXT: "decl": { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "RecordDecl", +// CHECK-NEXT: "name": "__NSConstantString_tag" +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: ] +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "TypedefDecl", +// CHECK-NEXT: "loc": {}, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": {}, +// CHECK-NEXT: "end": {} +// CHECK-NEXT: }, +// CHECK-NEXT: "isImplicit": true, +// CHECK-NEXT: "name": "__builtin_ms_va_list", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "char *" +// CHECK-NEXT: }, +// CHECK-NEXT: "inner": [ +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "PointerType", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "char *" +// CHECK-NEXT: }, +// CHECK-NEXT: "inner": [ +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "BuiltinType", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "char" +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: ] +// CHECK-NEXT: } +// CHECK-NEXT: ] +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "TypedefDecl", +// CHECK-NEXT: "loc": {}, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": {}, +// CHECK-NEXT: "end": {} +// CHECK-NEXT: }, +// CHECK-NEXT: "isImplicit": true, +// CHECK-NEXT: "name": "__builtin_va_list", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "struct __va_list_tag [1]" +// CHECK-NEXT: }, +// CHECK-NEXT: "inner": [ +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "ConstantArrayType", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "struct __va_list_tag [1]" +// CHECK-NEXT: }, +// CHECK-NEXT: "size": 1, +// CHECK-NEXT: "inner": [ +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "RecordType", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "struct __va_list_tag" +// CHECK-NEXT: }, +// CHECK-NEXT: "decl": { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "RecordDecl", +// CHECK-NEXT: "name": "__va_list_tag" +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: ] +// CHECK-NEXT: } +// CHECK-NEXT: ] +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "VarDecl", +// CHECK-NEXT: "loc": { +// CHECK-NEXT: "offset": 108, +// CHECK-NEXT: "file": "{{.*}}", +// CHECK-NEXT: "line": 4, +// CHECK-NEXT: "presumedFile": "test.c", +// CHECK-NEXT: "col": 5, +// CHECK-NEXT: "tokLen": 1 +// CHECK-NEXT: }, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": { +// CHECK-NEXT: "offset": 104, +// CHECK-NEXT: "col": 1, +// CHECK-NEXT: "tokLen": 3 +// CHECK-NEXT: }, +// CHECK-NEXT: "end": { +// CHECK-NEXT: "offset": 108, +// CHECK-NEXT: "col": 5, +// CHECK-NEXT: "tokLen": 1 +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "name": "a", +// CHECK-NEXT: "mangledName": "a", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "int" +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "VarDecl", +// CHECK-NEXT: "loc": { +// CHECK-NEXT: "offset": 136, +// CHECK-NEXT: "line": 7, +// CHECK-NEXT: "presumedFile": "bar.h", +// CHECK-NEXT: "presumedLine": 32, +// CHECK-NEXT: "col": 5, +// CHECK-NEXT: "tokLen": 1 +// CHECK-NEXT: }, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": { +// CHECK-NEXT: "offset": 132, +// CHECK-NEXT: "col": 1, +// CHECK-NEXT: "tokLen": 3 +// CHECK-NEXT: }, +// CHECK-NEXT: "end": { +// CHECK-NEXT: "offset": 136, +// CHECK-NEXT: "col": 5, +// CHECK-NEXT: "tokLen": 1 +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "name": "b", +// CHECK-NEXT: "mangledName": "b", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "int" +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "VarDecl", +// CHECK-NEXT: "loc": { +// CHECK-NEXT: "offset": 144, +// CHECK-NEXT: "line": 8, +// CHECK-NEXT: "presumedLine": 33, +// CHECK-NEXT: "col": 5, +// CHECK-NEXT: "tokLen": 1 +// CHECK-NEXT: }, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": { +// CHECK-NEXT: "offset": 140, +// CHECK-NEXT: "col": 1, +// CHECK-NEXT: "tokLen": 3 +// CHECK-NEXT: }, +// CHECK-NEXT: "end": { +// CHECK-NEXT: "offset": 144, +// CHECK-NEXT: "col": 5, +// CHECK-NEXT: "tokLen": 1 +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "name": "c", +// CHECK-NEXT: "mangledName": "c", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "int" +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "VarDecl", +// CHECK-NEXT: "loc": { +// CHECK-NEXT: "offset": 173, +// CHECK-NEXT: "line": 11, +// CHECK-NEXT: "presumedFile": "test.c", +// CHECK-NEXT: "col": 5, +// CHECK-NEXT: "tokLen": 1 +// CHECK-NEXT: }, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": { +// CHECK-NEXT: "offset": 169, +// CHECK-NEXT: "col": 1, +// CHECK-NEXT: "tokLen": 3 +// CHECK-NEXT: }, +// CHECK-NEXT: "end": { +// CHECK-NEXT: "offset": 173, +// CHECK-NEXT: "col": 5, +// CHECK-NEXT: "tokLen": 1 +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "name": "d", +// CHECK-NEXT: "mangledName": "d", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "int" +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "VarDecl", +// CHECK-NEXT: "loc": { +// CHECK-NEXT: "offset": 181, +// CHECK-NEXT: "line": 12, +// CHECK-NEXT: "col": 5, +// CHECK-NEXT: "tokLen": 1 +// CHECK-NEXT: }, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": { +// CHECK-NEXT: "offset": 177, +// CHECK-NEXT: "col": 1, +// CHECK-NEXT: "tokLen": 3 +// CHECK-NEXT: }, +// CHECK-NEXT: "end": { +// CHECK-NEXT: "offset": 181, +// CHECK-NEXT: "col": 5, +// CHECK-NEXT: "tokLen": 1 +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "name": "e", +// CHECK-NEXT: "mangledName": "e", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "int" +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: ] +// CHECK-NEXT: } diff --git a/clang/test/AST/gen_ast_dump_json_test.py b/clang/test/AST/gen_ast_dump_json_test.py index 3a40646..87b3318 100644 --- a/clang/test/AST/gen_ast_dump_json_test.py +++ b/clang/test/AST/gen_ast_dump_json_test.py @@ -180,7 +180,7 @@ def process_file(source_file, clang_binary, cmdline_filters, cmdline_opts, filter_json(j, filters, out_asts) - with tempfile.NamedTemporaryFile("w") as f: + with tempfile.NamedTemporaryFile("w", delete=False) as f: with open(source_file, "r") as srcf: for line in srcf.readlines(): # copy up to the note: @@ -201,6 +201,7 @@ def process_file(source_file, clang_binary, cmdline_filters, cmdline_opts, f.write(out_str) f.flush() + f.close() if do_update: print("Updating json appended source file to %s." % source_file) copyfile(f.name, source_file) @@ -209,6 +210,7 @@ def process_file(source_file, clang_binary, cmdline_filters, cmdline_opts, dest_path = '%s-json%s%s' % (partition[0], partition[1], partition[2]) print("Writing json appended source file to %s." % dest_path) copyfile(f.name, dest_path) + os.remove(f.name) return 0 -- 2.7.4