diff options
Diffstat (limited to 'llvm/tools/llvm-cov/CodeCoverage.cpp')
| -rw-r--r-- | llvm/tools/llvm-cov/CodeCoverage.cpp | 42 |
1 files changed, 39 insertions, 3 deletions
diff --git a/llvm/tools/llvm-cov/CodeCoverage.cpp b/llvm/tools/llvm-cov/CodeCoverage.cpp index baa968820b63..02c0106cbc29 100644 --- a/llvm/tools/llvm-cov/CodeCoverage.cpp +++ b/llvm/tools/llvm-cov/CodeCoverage.cpp @@ -80,6 +80,12 @@ private: /// directory, recursively collect all of the paths within the directory. void collectPaths(const std::string &Path); + /// Check if the two given files are the same file. + bool isEquivalentFile(StringRef FilePath1, StringRef FilePath2); + + /// Retrieve a file status with a cache. + Optional<sys::fs::file_status> getFileStatus(StringRef FilePath); + /// Return a memory buffer for the given source file. ErrorOr<const MemoryBuffer &> getSourceFile(StringRef SourceFile); @@ -153,6 +159,9 @@ private: /// remapped to, when using -path-equivalence. Optional<std::pair<std::string, std::string>> PathRemapping; + /// File status cache used when finding the same file. + StringMap<Optional<sys::fs::file_status>> FileStatusCache; + /// The architecture the coverage mapping data targets. std::vector<StringRef> CoverageArches; @@ -239,6 +248,27 @@ void CodeCoverageTool::collectPaths(const std::string &Path) { } } +Optional<sys::fs::file_status> +CodeCoverageTool::getFileStatus(StringRef FilePath) { + auto It = FileStatusCache.try_emplace(FilePath); + auto &CachedStatus = It.first->getValue(); + if (!It.second) + return CachedStatus; + + sys::fs::file_status Status; + if (!sys::fs::status(FilePath, Status)) + CachedStatus = Status; + return CachedStatus; +} + +bool CodeCoverageTool::isEquivalentFile(StringRef FilePath1, + StringRef FilePath2) { + auto Status1 = getFileStatus(FilePath1); + auto Status2 = getFileStatus(FilePath2); + return Status1.hasValue() && Status2.hasValue() && + sys::fs::equivalent(Status1.getValue(), Status2.getValue()); +} + ErrorOr<const MemoryBuffer &> CodeCoverageTool::getSourceFile(StringRef SourceFile) { // If we've remapped filenames, look up the real location for this file. @@ -249,7 +279,7 @@ CodeCoverageTool::getSourceFile(StringRef SourceFile) { SourceFile = Loc->second; } for (const auto &Files : LoadedSourceFiles) - if (sys::fs::equivalent(SourceFile, Files.first)) + if (isEquivalentFile(SourceFile, Files.first)) return *Files.second; auto Buffer = MemoryBuffer::getFile(SourceFile); if (auto EC = Buffer.getError()) { @@ -404,7 +434,8 @@ std::unique_ptr<CoverageMapping> CodeCoverageTool::load() { warning("profile data may be out of date - object is newer", ObjectFilename); auto CoverageOrErr = - CoverageMapping::load(ObjectFilenames, PGOFilename, CoverageArches); + CoverageMapping::load(ObjectFilenames, PGOFilename, CoverageArches, + ViewOpts.CompilationDirectory); if (Error E = CoverageOrErr.takeError()) { error("Failed to load coverage: " + toString(std::move(E)), join(ObjectFilenames.begin(), ObjectFilenames.end(), ", ")); @@ -445,7 +476,7 @@ void CodeCoverageTool::remapPathNames(const CoverageMapping &Coverage) { SmallString<128> NativePath; sys::path::native(Path, NativePath); sys::path::remove_dots(NativePath, true); - if (!sys::path::is_separator(NativePath.back())) + if (!NativePath.empty() && !sys::path::is_separator(NativePath.back())) NativePath += sys::path::get_separator(); return NativePath.c_str(); }; @@ -709,6 +740,10 @@ int CodeCoverageTool::run(Command Cmd, int argc, const char **argv) { cl::alias NumThreadsA("j", cl::desc("Alias for --num-threads"), cl::aliasopt(NumThreads)); + cl::opt<std::string> CompilationDirectory( + "compilation-dir", cl::init(""), + cl::desc("Directory used as a base for relative coverage mapping paths")); + auto commandLineParser = [&, this](int argc, const char **argv) -> int { cl::ParseCommandLineOptions(argc, argv, "LLVM code coverage tool\n"); ViewOpts.Debug = DebugDump; @@ -843,6 +878,7 @@ int CodeCoverageTool::run(Command Cmd, int argc, const char **argv) { ViewOpts.ShowInstantiationSummary = InstantiationSummary; ViewOpts.ExportSummaryOnly = SummaryOnly; ViewOpts.NumThreads = NumThreads; + ViewOpts.CompilationDirectory = CompilationDirectory; return 0; }; |
