aganea updated this revision to Diff 193886. aganea marked 2 inline comments as done. aganea edited the summary of this revision. aganea added a comment.
I made a more elegant change, where no additional lookups or string compares are required. I noted btw that clang /E does not generate `#line` directives, but simply `#`. In contrast, MSVC cl /E generates `#line` in the preprocessed output. The issue is that MSVC doesn't like `#` alone and throws an error. ie: $ cat test.cpp void test() { } $ clang-cl /c /E test.cpp >test-pre.cpp $ cat test-pre.cpp # 1 "C:\\Users\\aganea\\Desktop\\test\\test.cpp" # 1 "<built-in>" 1 # 1 "<built-in>" 3 # 361 "<built-in>" 3 # 1 "<command line>" 1 # 1 "<built-in>" 2 # 1 "C:\\Users\\aganea\\Desktop\\test\\test.cpp" 2 void test() { } $ cl /c test-pre.cpp Microsoft (R) C/C++ Optimizing Compiler Version 19.16.27027.1 for x64 Copyright (C) Microsoft Corporation. All rights reserved. test-pre.cpp C:\Users\aganea\Desktop\test\test-pre.cpp(1): error C2019: expected preprocessor directive, found '1' C:\Users\aganea\Desktop\test\test-pre.cpp(2): error C2019: expected preprocessor directive, found '1' C:\Users\aganea\Desktop\test\test-pre.cpp(3): error C2019: expected preprocessor directive, found '1' C:\Users\aganea\Desktop\test\test-pre.cpp(4): error C2019: expected preprocessor directive, found '3' C:\Users\aganea\Desktop\test\test-pre.cpp(5): error C2019: expected preprocessor directive, found '1' C:\Users\aganea\Desktop\test\test-pre.cpp(6): error C2019: expected preprocessor directive, found '1' C:\Users\aganea\Desktop\test\test-pre.cpp(7): error C2019: expected preprocessor directive, found '1' $ cl /c /E test.cpp >test-pre.cpp $ cat test-pre.cpp #line 1 "C:\\Users\\aganea\\Desktop\\test\\test.cpp" void test() { } $ cl /c test-pre.cpp Microsoft (R) C/C++ Optimizing Compiler Version 19.16.27027.1 for x64 Copyright (C) Microsoft Corporation. All rights reserved. test-pre.cpp Repository: rC Clang CHANGES SINCE LAST ACTION https://reviews.llvm.org/D60283/new/ https://reviews.llvm.org/D60283 Files: include/clang/Basic/SourceLocation.h lib/Basic/SourceManager.cpp lib/CodeGen/CGDebugInfo.cpp test/CodeGen/Inputs/debug-info-file-checksum-pre.cpp test/CodeGen/debug-info-file-checksum.c
Index: test/CodeGen/debug-info-file-checksum.c =================================================================== --- test/CodeGen/debug-info-file-checksum.c +++ test/CodeGen/debug-info-file-checksum.c @@ -4,3 +4,11 @@ // Check that "checksum" is created correctly for the compiled file. // CHECK: !DIFile(filename:{{.*}}, directory:{{.*}}, checksumkind: CSK_MD5, checksum: "a3b7d27af071accdeccaa933fc603608") + +// Ensure #line directives (in already pre-processed files) do not emit checksums + +// RUN: %clang -emit-llvm -S -g -gcodeview -x c %S/Inputs/debug-info-file-checksum-pre.cpp -o - | FileCheck %s --check-prefix NOCHECKSUM + +// NOCHECKSUM-LABEL: !DIFile(filename: "{{.*}}code-coverage-filter1.h", directory: "{{[^"]*}}") +// NOCHECKSUM-LABEL: !DIFile(filename: "{{.*}}code-coverage-filter2.h", directory: "{{[^"]*}}") +// NOCHECKSUM-LABEL: !DIFile(filename: "{{.*}}debug-info-file-checksum.c", directory: "{{[^"]*}}") Index: test/CodeGen/Inputs/debug-info-file-checksum-pre.cpp =================================================================== --- test/CodeGen/Inputs/debug-info-file-checksum-pre.cpp +++ test/CodeGen/Inputs/debug-info-file-checksum-pre.cpp @@ -0,0 +1,10 @@ +#line 1 "F:\\svn\\clang\\test\\CodeGen\\Inputs\\debug-info-file-checksum.c" +#line 1 "f:\\svn\\clang\\test\\codegen\\inputs\\code-coverage-filter1.h" +void test1() {} +#line 2 "F:\\svn\\clang\\test\\CodeGen\\Inputs\\debug-info-file-checksum.c" +#line 1 "f:\\svn\\clang\\test\\codegen\\inputs\\code-coverage-filter2.h" +void test2() {} +#line 3 "F:\\svn\\clang\\test\\CodeGen\\Inputs\\debug-info-file-checksum.c" +int foo(int x) { + return x+1; +} Index: lib/CodeGen/CGDebugInfo.cpp =================================================================== --- lib/CodeGen/CGDebugInfo.cpp +++ lib/CodeGen/CGDebugInfo.cpp @@ -422,11 +422,18 @@ } SmallString<32> Checksum; - Optional<llvm::DIFile::ChecksumKind> CSKind = - computeChecksum(SM.getFileID(Loc), Checksum); Optional<llvm::DIFile::ChecksumInfo<StringRef>> CSInfo; - if (CSKind) - CSInfo.emplace(*CSKind, Checksum); + + // Don't compute checksums if the location is affected by a #line directive. + // We would otherwise end up with the same checksum for all the files referred + // by #line. Instead we simply leave the checksum empty, and the debugger will + // open the file without checksums. + if (!PLoc.isAffectedByLineDirective()) { + Optional<llvm::DIFile::ChecksumKind> CSKind = + computeChecksum(SM.getFileID(Loc), Checksum); + if (CSKind) + CSInfo.emplace(*CSKind, Checksum); + } return createFile(FileName, CSInfo, getSource(SM, SM.getFileID(Loc))); } Index: lib/Basic/SourceManager.cpp =================================================================== --- lib/Basic/SourceManager.cpp +++ lib/Basic/SourceManager.cpp @@ -1442,6 +1442,7 @@ return PresumedLoc(); SourceLocation IncludeLoc = FI.getIncludeLoc(); + bool LineDirective = false; // If we have #line directives in this file, update and overwrite the physical // location info if appropriate. @@ -1468,10 +1469,11 @@ IncludeLoc = getLocForStartOfFile(LocInfo.first); IncludeLoc = IncludeLoc.getLocWithOffset(Entry->IncludeOffset); } + LineDirective = true; } } - return PresumedLoc(Filename.data(), LineNo, ColNo, IncludeLoc); + return PresumedLoc(Filename.data(), LineNo, ColNo, IncludeLoc, LineDirective); } /// Returns whether the PresumedLoc for a given SourceLocation is Index: include/clang/Basic/SourceLocation.h =================================================================== --- include/clang/Basic/SourceLocation.h +++ include/clang/Basic/SourceLocation.h @@ -284,11 +284,14 @@ const char *Filename = nullptr; unsigned Line, Col; SourceLocation IncludeLoc; + bool InLineDirective = false; public: PresumedLoc() = default; - PresumedLoc(const char *FN, unsigned Ln, unsigned Co, SourceLocation IL) - : Filename(FN), Line(Ln), Col(Co), IncludeLoc(IL) {} + PresumedLoc(const char *FN, unsigned Ln, unsigned Co, SourceLocation IL, + bool Line) + : Filename(FN), Line(Ln), Col(Co), IncludeLoc(IL), InLineDirective(Line) { + } /// Return true if this object is invalid or uninitialized. /// @@ -328,6 +331,12 @@ assert(isValid()); return IncludeLoc; } + + /// Tells if the current location is affected by GNU linemarker directives. + bool isAffectedByLineDirective() const { + assert(isValid()); + return InLineDirective; + } }; class FileEntry;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits