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; 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: lib/CodeGen/CGDebugInfo.cpp =================================================================== --- lib/CodeGen/CGDebugInfo.cpp +++ lib/CodeGen/CGDebugInfo.cpp @@ -422,11 +422,18 @@ } SmallString<32> Checksum; - Optional CSKind = - computeChecksum(SM.getFileID(Loc), Checksum); Optional> 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 CSKind = + computeChecksum(SM.getFileID(Loc), Checksum); + if (CSKind) + CSInfo.emplace(*CSKind, Checksum); + } return createFile(FileName, CSInfo, getSource(SM, SM.getFileID(Loc))); } 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: 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: "{{[^"]*}}")