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: 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: lib/CodeGen/CGDebugInfo.cpp =================================================================== --- lib/CodeGen/CGDebugInfo.cpp +++ lib/CodeGen/CGDebugInfo.cpp @@ -324,7 +324,8 @@ 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); @@ -332,7 +333,8 @@ 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,8 +346,14 @@ return cast(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; @@ -353,7 +361,8 @@ 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: 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; +} 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/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"