3535#include " llvm/Support/FileSystem.h"
3636#include " llvm/Support/Path.h"
3737#include " llvm/Support/Regex.h"
38+ #include " llvm/Support/VirtualFileSystem.h"
3839#include " llvm/Support/raw_ostream.h"
3940#include " llvm/Transforms/Instrumentation/CFGMST.h"
4041#include " llvm/Transforms/Instrumentation/GCOVProfiler.h"
@@ -92,8 +93,10 @@ class GCOVFunction;
9293
9394class GCOVProfiler {
9495public:
95- GCOVProfiler () : GCOVProfiler(GCOVOptions::getDefault()) {}
96- GCOVProfiler (const GCOVOptions &Opts) : Options(Opts) {}
96+ GCOVProfiler ()
97+ : GCOVProfiler(GCOVOptions::getDefault(), *vfs::getRealFileSystem ()) {}
98+ GCOVProfiler (const GCOVOptions &Opts, vfs::FileSystem &VFS)
99+ : Options(Opts), VFS(VFS) {}
97100 bool
98101 runOnModule (Module &M, function_ref<BlockFrequencyInfo *(Function &F)> GetBFI,
99102 function_ref<BranchProbabilityInfo *(Function &F)> GetBPI,
@@ -110,6 +113,7 @@ class GCOVProfiler {
110113 os->write_zeros (4 - s.size () % 4 );
111114 }
112115 void writeBytes (const char *Bytes, int Size) { os->write (Bytes, Size); }
116+ vfs::FileSystem &getVirtualFileSystem () const { return VFS; }
113117
114118private:
115119 // Create the .gcno files for the Module based on DebugInfo.
@@ -166,6 +170,7 @@ class GCOVProfiler {
166170 std::vector<Regex> ExcludeRe;
167171 DenseSet<const BasicBlock *> ExecBlocks;
168172 StringMap<bool > InstrumentedFiles;
173+ vfs::FileSystem &VFS;
169174};
170175
171176struct BBInfo {
@@ -214,10 +219,10 @@ static StringRef getFunctionName(const DISubprogram *SP) {
214219// / Prefer relative paths in the coverage notes. Clang also may split
215220// / up absolute paths into a directory and filename component. When
216221// / the relative path doesn't exist, reconstruct the absolute path.
217- static SmallString<128 > getFilename (const DIScope *SP) {
222+ static SmallString<128 > getFilename (const DIScope *SP, vfs::FileSystem &VFS ) {
218223 SmallString<128 > Path;
219224 StringRef RelPath = SP->getFilename ();
220- if (sys::fs:: exists (RelPath))
225+ if (VFS. exists (RelPath))
221226 Path = RelPath;
222227 else
223228 sys::path::append (Path, SP->getDirectory (), SP->getFilename ());
@@ -357,7 +362,7 @@ namespace {
357362
358363 void writeOut (uint32_t CfgChecksum) {
359364 write (GCOV_TAG_FUNCTION);
360- SmallString<128 > Filename = getFilename (SP);
365+ SmallString<128 > Filename = getFilename (SP, P-> getVirtualFileSystem () );
361366 uint32_t BlockLen = 3 + wordsOfString (getFunctionName (SP));
362367 BlockLen += 1 + wordsOfString (Filename) + 4 ;
363368
@@ -455,7 +460,7 @@ bool GCOVProfiler::isFunctionInstrumented(const Function &F) {
455460 if (FilterRe.empty () && ExcludeRe.empty ()) {
456461 return true ;
457462 }
458- SmallString<128 > Filename = getFilename (F.getSubprogram ());
463+ SmallString<128 > Filename = getFilename (F.getSubprogram (), VFS );
459464 auto It = InstrumentedFiles.find (Filename);
460465 if (It != InstrumentedFiles.end ()) {
461466 return It->second ;
@@ -467,7 +472,7 @@ bool GCOVProfiler::isFunctionInstrumented(const Function &F) {
467472 // Path can be
468473 // /usr/lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/*.h so for
469474 // such a case we must get the real_path.
470- if (sys::fs::real_path (Filename, RealPath)) {
475+ if (VFS. getRealPath (Filename, RealPath)) {
471476 // real_path can fail with path like "foo.c".
472477 RealFilename = Filename;
473478 } else {
@@ -524,9 +529,10 @@ std::string GCOVProfiler::mangleName(const DICompileUnit *CU,
524529 SmallString<128 > Filename = CU->getFilename ();
525530 sys::path::replace_extension (Filename, Notes ? " gcno" : " gcda" );
526531 StringRef FName = sys::path::filename (Filename);
527- SmallString< 128 > CurPath ;
528- if (sys::fs::current_path (CurPath) )
532+ ErrorOr<std::string> CWD = VFS. getCurrentWorkingDirectory () ;
533+ if (!CWD )
529534 return std::string (FName);
535+ SmallString<128 > CurPath{*CWD};
530536 sys::path::append (CurPath, FName);
531537 return std::string (CurPath);
532538}
@@ -554,7 +560,7 @@ bool GCOVProfiler::runOnModule(
554560PreservedAnalyses GCOVProfilerPass::run (Module &M,
555561 ModuleAnalysisManager &AM) {
556562
557- GCOVProfiler Profiler (GCOVOpts);
563+ GCOVProfiler Profiler (GCOVOpts, *VFS );
558564 FunctionAnalysisManager &FAM =
559565 AM.getResult <FunctionAnalysisManagerModuleProxy>(M).getManager ();
560566
@@ -789,7 +795,7 @@ bool GCOVProfiler::emitProfileNotes(
789795 // Add the function line number to the lines of the entry block
790796 // to have a counter for the function definition.
791797 uint32_t Line = SP->getLine ();
792- auto Filename = getFilename (SP);
798+ auto Filename = getFilename (SP, VFS );
793799
794800 BranchProbabilityInfo *BPI = GetBPI (F);
795801 BlockFrequencyInfo *BFI = GetBFI (F);
@@ -881,7 +887,7 @@ bool GCOVProfiler::emitProfileNotes(
881887 if (SP != getDISubprogram (Scope))
882888 continue ;
883889
884- GCOVLines &Lines = Block.getFile (getFilename (Loc->getScope ()));
890+ GCOVLines &Lines = Block.getFile (getFilename (Loc->getScope (), VFS ));
885891 Lines.addLine (Loc.getLine ());
886892 }
887893 Line = 0 ;
0 commit comments