aaboud created this revision.
aaboud added reviewers: rnk, probinson, rsmith.
aaboud added a subscriber: cfe-commits.

Resolve Bug 30978 <https://llvm.org/bugs/show_bug.cgi?id=30978>.

This patch contains changes in Clang to support Checksum debug info feature.


https://reviews.llvm.org/D27641

Files:
  include/clang/Basic/SourceManager.h
  lib/Basic/SourceManager.cpp
  lib/CodeGen/CGDebugInfo.cpp
  test/CodeGen/debug-info-atomic.c
  test/CodeGen/debug-info-file-checksum.c
  test/CodeGen/debug-info-file-checksum.c.source
  test/CodeGen/debug-prefix-map.c
  test/PCH/debug-info-pch-path.c

Index: lib/CodeGen/CGDebugInfo.cpp
===================================================================
--- lib/CodeGen/CGDebugInfo.cpp
+++ lib/CodeGen/CGDebugInfo.cpp
@@ -324,15 +324,17 @@
   if (!Loc.isValid())
     // If Location is not valid then use main input file.
     return DBuilder.createFile(remapDIPath(TheCU->getFilename()),
-                               remapDIPath(TheCU->getDirectory()));
+                               remapDIPath(TheCU->getDirectory()),
+                               TheCU->getChecksum());
 
   SourceManager &SM = CGM.getContext().getSourceManager();
   PresumedLoc PLoc = SM.getPresumedLoc(Loc);
 
   if (PLoc.isInvalid() || StringRef(PLoc.getFilename()).empty())
     // If the location is not valid then use main input file.
     return DBuilder.createFile(remapDIPath(TheCU->getFilename()),
-                               remapDIPath(TheCU->getDirectory()));
+                               remapDIPath(TheCU->getDirectory()),
+                               TheCU->getChecksum());
 
   // Cache the results.
   const char *fname = PLoc.getFilename();
@@ -344,16 +346,23 @@
       return cast<llvm::DIFile>(V);
   }
 
+  std::string Checksum;
+  SM.getChecksumMD5(SM.getFileID(Loc), Checksum);
+
+  llvm::DIChecksum *C =
+      DBuilder.createChecksum(llvm::DIChecksum::MD5, Checksum);
+
   llvm::DIFile *F = DBuilder.createFile(remapDIPath(PLoc.getFilename()),
-                                        remapDIPath(getCurrentDirname()));
+                                        remapDIPath(getCurrentDirname()), C);
 
   DIFileCache[fname].reset(F);
   return F;
 }
 
 llvm::DIFile *CGDebugInfo::getOrCreateMainFile() {
   return DBuilder.createFile(remapDIPath(TheCU->getFilename()),
-                             remapDIPath(TheCU->getDirectory()));
+                             remapDIPath(TheCU->getDirectory()),
+                             TheCU->getChecksum());
 }
 
 std::string CGDebugInfo::remapDIPath(StringRef Path) const {
@@ -396,6 +405,7 @@
 }
 
 void CGDebugInfo::CreateCompileUnit() {
+  std::string Checksum;
 
   // Should we be asking the SourceManager for the main file name, instead of
   // accepting it as an argument? This just causes the main file name to
@@ -422,6 +432,7 @@
       llvm::sys::path::append(MainFileDirSS, MainFileName);
       MainFileName = MainFileDirSS.str();
     }
+    SM.getChecksumMD5(SM.getMainFileID(), Checksum);
   }
 
   llvm::dwarf::SourceLanguage LangTag;
@@ -467,7 +478,8 @@
   // FIXME - Eliminate TheCU.
   TheCU = DBuilder.createCompileUnit(
       LangTag, remapDIPath(MainFileName), remapDIPath(getCurrentDirname()),
-      Producer, LO.Optimize, CGM.getCodeGenOpts().DwarfDebugFlags, RuntimeVers,
+      llvm::DIChecksum::MD5, Checksum, Producer, LO.Optimize,
+      CGM.getCodeGenOpts().DwarfDebugFlags, RuntimeVers,
       CGM.getCodeGenOpts().SplitDwarfFile, EmissionKind, 0 /* DWOid */,
       CGM.getCodeGenOpts().SplitDwarfInlining);
 }
@@ -1978,9 +1990,10 @@
     uint64_t Signature = Mod.getSignature() ? Mod.getSignature() : ~1ULL;
     llvm::DIBuilder DIB(CGM.getModule());
     DIB.createCompileUnit(TheCU->getSourceLanguage(), Mod.getModuleName(),
-                          Mod.getPath(), TheCU->getProducer(), true,
-                          StringRef(), 0, Mod.getASTFile(),
-                          llvm::DICompileUnit::FullDebug, Signature);
+                          Mod.getPath(), llvm::DIChecksum::None, "",
+                          TheCU->getProducer(), true, StringRef(), 0,
+                          Mod.getASTFile(), llvm::DICompileUnit::FullDebug,
+                          Signature);
     DIB.finalize();
   }
   llvm::DIModule *Parent =
Index: lib/Basic/SourceManager.cpp
===================================================================
--- lib/Basic/SourceManager.cpp
+++ lib/Basic/SourceManager.cpp
@@ -20,6 +20,8 @@
 #include "llvm/ADT/StringSwitch.h"
 #include "llvm/Support/Capacity.h"
 #include "llvm/Support/Compiler.h"
+#include "llvm/Support/Format.h"
+#include "llvm/Support/MD5.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/raw_ostream.h"
@@ -1442,6 +1444,24 @@
   return getBuffer(getFileID(Loc), Invalid)->getBufferIdentifier();
 }
 
+void SourceManager::getChecksumMD5(FileID FID, std::string &Checksum) const {
+  bool Invalid;
+
+  llvm::MemoryBuffer *MemBuffer = getBuffer(FID, &Invalid);
+  if (Invalid) return;
+
+  llvm::MD5 Hash;
+  llvm::MD5::MD5Result Result;
+
+  Hash.update(MemBuffer->getBuffer());
+  Hash.final(Result);
+
+  llvm::raw_string_ostream OS(Checksum);
+
+  for (unsigned i = 0; i < sizeof(Result); i++)
+    OS << llvm::format("%02x", Result[i]);
+}
+
 
 /// getPresumedLoc - This method returns the "presumed" location of a
 /// SourceLocation specifies.  A "presumed location" can be modified by \#line
Index: include/clang/Basic/SourceManager.h
===================================================================
--- include/clang/Basic/SourceManager.h
+++ include/clang/Basic/SourceManager.h
@@ -1301,6 +1301,9 @@
   /// getPresumedLoc for normal clients.
   StringRef getBufferName(SourceLocation Loc, bool *Invalid = nullptr) const;
 
+  /// Return the checksum of the given file in MD5 format.
+  void getChecksumMD5(FileID FID, std::string &Checksum) const;
+
   /// \brief Return the file characteristic of the specified source
   /// location, indicating whether this is a normal file, a system
   /// header, or an "implicit extern C" system header.
Index: test/PCH/debug-info-pch-path.c
===================================================================
--- test/PCH/debug-info-pch-path.c
+++ test/PCH/debug-info-pch-path.c
@@ -20,7 +20,7 @@
 // CHECK-REL-NODIR: !DICompileUnit
 // CHECK-REL-NODIR-SAME:           file: ![[C:[0-9]+]]
 // CHECK-REL-NODIR-NOT: dwoId
-// CHECK-REL-NODIR: ![[C]] = !DIFile({{.*}}directory: "[[DIR:.*]]"
+// CHECK-REL-NODIR: ![[C]] = !DIFile({{.*}}directory: "[[DIR:.*]]",
 // CHECK-REL-NODIR: !DICompileUnit(
 // CHECK-REL-NODIR-SAME:           file: ![[PCH:[0-9]+]]
 // CHECK-REL-NODIR-SAME:           splitDebugFilename: "prefix.pch"
@@ -44,7 +44,7 @@
 // CHECK-REL: !DICompileUnit
 // CHECK-REL-SAME:           file: ![[C:[0-9]+]]
 // CHECK-REL-NOT: dwoId
-// CHECK-REL: ![[C]] = !DIFile({{.*}}directory: "[[DIR:.*]]"
+// CHECK-REL: ![[C]] = !DIFile({{.*}}directory: "[[DIR:.*]]",
 // CHECK-REL: !DICompileUnit(
 // CHECK-REL-SAME:           file: ![[PCH:[0-9]+]]
 // CHECK-REL-SAME:           splitDebugFilename: "prefix.pch"
@@ -67,7 +67,7 @@
 // CHECK-ABS: !DICompileUnit
 // CHECK-ABS-SAME:           file: ![[C:[0-9]+]]
 // CHECK-ABS-NOT: dwoId
-// CHECK-ABS: ![[C]] = !DIFile({{.*}}directory: "[[DIR:.*]]"
+// CHECK-ABS: ![[C]] = !DIFile({{.*}}directory: "[[DIR:.*]]",
 // CHECK-ABS: !DICompileUnit(
 // CHECK-ABS-SAME:           file: ![[PCH:[0-9]+]]
 // CHECK-ABS-SAME:           splitDebugFilename: "prefix.pch"
Index: test/CodeGen/debug-prefix-map.c
===================================================================
--- test/CodeGen/debug-prefix-map.c
+++ test/CodeGen/debug-prefix-map.c
@@ -29,6 +29,6 @@
 // CHECK: !DIFile(filename: "/var/empty{{[/\\]}}Inputs/stdio.h"
 // CHECK-NOT: !DIFile(filename:
 
-// CHECK-COMPILATION-DIR: !DIFile(filename: "/var/empty{{[/\\]}}{{.*}}", directory: "/var/empty")
-// CHECK-COMPILATION-DIR: !DIFile(filename: "/var/empty{{[/\\]}}Inputs/stdio.h", directory: "/var/empty")
+// CHECK-COMPILATION-DIR: !DIFile(filename: "/var/empty{{[/\\]}}{{.*}}", directory: "/var/empty"
+// CHECK-COMPILATION-DIR: !DIFile(filename: "/var/empty{{[/\\]}}Inputs/stdio.h", directory: "/var/empty"
 // CHECK-COMPILATION-DIR-NOT: !DIFile(filename:
Index: test/CodeGen/debug-info-atomic.c
===================================================================
--- test/CodeGen/debug-info-atomic.c
+++ test/CodeGen/debug-info-atomic.c
@@ -1,7 +1,7 @@
 // RUN: %clang -g -c -std=c11 -S -emit-llvm -o - %s | FileCheck %s
 
-// CHECK: !DIGlobalVariable(name: "i"{{.*}}type: !5, isLocal: false, isDefinition: true)
-// CHECK: !5 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !6)
-// CHECK: !6 = !DIDerivedType(tag: DW_TAG_atomic_type, baseType: !7)
-// CHECK: !7 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+// CHECK: !DIGlobalVariable(name: "i"{{.*}}type: [[CONST:![0-9]+]], isLocal: false, isDefinition: true)
+// CHECK: [[CONST]] = !DIDerivedType(tag: DW_TAG_const_type, baseType: [[ATOMIC:![0-9]+]])
+// CHECK: [[ATOMIC]] = !DIDerivedType(tag: DW_TAG_atomic_type, baseType: [[INT32:![0-9]+]])
+// CHECK: [[INT32]] = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
 _Atomic const int i;
Index: test/CodeGen/debug-info-file-checksum.c
===================================================================
--- test/CodeGen/debug-info-file-checksum.c
+++ test/CodeGen/debug-info-file-checksum.c
@@ -0,0 +1,6 @@
+// RUN: %clang -emit-llvm -S -g -x c %s.source -o - | FileCheck %s
+
+// Check that "checksum" is created correctly for the compiled file.
+
+// CHECK: !DIFile(filename:{{.*}}, directory:{{.*}}, checksum: [[CHECKSUM:![0-9]+]])
+// CHECK: [[CHECKSUM]] = !DIChecksum(type: ChecksumType_MD5, data: "a3b7d27af071accdeccaa933fc603608")
Index: test/CodeGen/debug-info-file-checksum.c.source
===================================================================
--- test/CodeGen/debug-info-file-checksum.c.source
+++ test/CodeGen/debug-info-file-checksum.c.source
@@ -0,0 +1,3 @@
+int foo(int x) {
+  return x+1;
+}
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to