Index: lib/Transforms/Instrumentation/GCOVProfiling.cpp =================================================================== --- lib/Transforms/Instrumentation/GCOVProfiling.cpp +++ lib/Transforms/Instrumentation/GCOVProfiling.cpp @@ -118,7 +118,8 @@ Function *insertFlush(ArrayRef>); void insertIndirectCounterIncrement(); - std::string mangleName(const DICompileUnit *CU, const char *NewStem); + enum GCovFileType { GCNO, GCDA }; + std::string mangleName(const DICompileUnit *CU, GCovFileType NewStem); GCOVOptions Options; @@ -418,24 +419,37 @@ } std::string GCOVProfiler::mangleName(const DICompileUnit *CU, - const char *NewStem) { + GCovFileType NewStem) { if (NamedMDNode *GCov = M->getNamedMetadata("llvm.gcov")) { for (int i = 0, e = GCov->getNumOperands(); i != e; ++i) { MDNode *N = GCov->getOperand(i); + if (N->getNumOperands() == 3) { + // These nodes have no mangling to apply, it's stored mangled in the + // bitcode. + MDString *NotesFile = dyn_cast(N->getOperand(0)); + MDString *DataFile = dyn_cast(N->getOperand(1)); + MDNode *CompileUnit = dyn_cast(N->getOperand(2)); + if (!NotesFile || !DataFile || !CompileUnit) continue; + if (CompileUnit == CU) + return NewStem == GCNO ? NotesFile->getString() + : DataFile->getString(); + } if (N->getNumOperands() != 2) continue; MDString *GCovFile = dyn_cast(N->getOperand(0)); MDNode *CompileUnit = dyn_cast(N->getOperand(1)); if (!GCovFile || !CompileUnit) continue; if (CompileUnit == CU) { - SmallString<128> Filename = GCovFile->getString(); - sys::path::replace_extension(Filename, NewStem); + SmallString<128> Filename; + Filename = GCovFile->getString(); + sys::path::replace_extension(Filename, + NewStem == GCNO ? "gcno" : "gcda"); return Filename.str(); } } } SmallString<128> Filename = CU->getFilename(); - sys::path::replace_extension(Filename, NewStem); + sys::path::replace_extension(Filename, NewStem == GCNO ? "gcno" : "gcda"); StringRef FName = sys::path::filename(Filename); SmallString<128> CurPath; if (sys::fs::current_path(CurPath)) return FName; @@ -501,7 +515,7 @@ continue; std::error_code EC; - raw_fd_ostream out(mangleName(CU, "gcno"), EC, sys::fs::F_None); + raw_fd_ostream out(mangleName(CU, GCNO), EC, sys::fs::F_None); std::string EdgeDestinations; unsigned FunctionIdent = 0; @@ -849,7 +863,7 @@ if (CU->getDWOId()) continue; - std::string FilenameGcda = mangleName(CU, "gcda"); + std::string FilenameGcda = mangleName(CU, GCDA); uint32_t CfgChecksum = FileChecksums.empty() ? 0 : FileChecksums[i]; Builder.CreateCall(StartFile, {Builder.CreateGlobalStringPtr(FilenameGcda), Index: test/Transforms/GCOVProfiling/three-element-mdnode.ll =================================================================== --- test/Transforms/GCOVProfiling/three-element-mdnode.ll +++ test/Transforms/GCOVProfiling/three-element-mdnode.ll @@ -0,0 +1,27 @@ +; RUN: echo '!9 = !{!"%T/aaa.gcno", !"%T/bbb.gcda", !0}' > %t1 +; RUN: cat %s %t1 > %t2 +; RUN: opt -insert-gcov-profiling -S -o %t3 < %t2 +; RUN: grep _Z3foov %T/aaa.gcno +; RUN: grep bbb.gcda %t3 +; RUN: rm %T/aaa.gcno + +define void @_Z3foov() !dbg !5 { +entry: + ret void, !dbg !8 +} + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!10} +!llvm.gcov = !{!9} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, producer: "clang version 3.3 (trunk 177323)", isOptimized: false, emissionKind: FullDebug, file: !2, enums: !3, retainedTypes: !3, globals: !3, imports: !3) +!1 = !DIFile(filename: "hello.cc", directory: "/home/nlewycky") +!2 = !DIFile(filename: "hello.cc", directory: "/home/nlewycky") +!3 = !{} +!5 = distinct !DISubprogram(name: "foo", linkageName: "_Z3foov", line: 1, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, unit: !0, scopeLine: 1, file: !1, scope: !1, type: !6, variables: !3) +!6 = !DISubroutineType(types: !7) +!7 = !{null} +!8 = !DILocation(line: 1, scope: !5) + + +!10 = !{i32 1, !"Debug Info Version", i32 3}