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
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