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

Reply via email to