/// \brief Copy \p Path into the list of input source files.
void addCollectedPath(const std::string &Path);
+ /// \brief If \p Path is a regular file, collect the path. If it's a
+ /// directory, recursively collect all of the paths within the directory.
+ void collectPaths(const std::string &Path);
+
/// \brief Return a memory buffer for the given source file.
ErrorOr<const MemoryBuffer &> getSourceFile(StringRef SourceFile);
}
void CodeCoverageTool::addCollectedPath(const std::string &Path) {
- CollectedPaths.push_back(Path);
+ if (CompareFilenamesOnly) {
+ CollectedPaths.push_back(Path);
+ } else {
+ SmallString<128> EffectivePath(Path);
+ if (std::error_code EC = sys::fs::make_absolute(EffectivePath)) {
+ error(EC.message(), Path);
+ return;
+ }
+ sys::path::remove_dots(EffectivePath, /*remove_dot_dots=*/true);
+ CollectedPaths.push_back(EffectivePath.str());
+ }
+
SourceFiles.emplace_back(CollectedPaths.back());
}
+void CodeCoverageTool::collectPaths(const std::string &Path) {
+ llvm::sys::fs::file_status Status;
+ llvm::sys::fs::status(Path, Status);
+ if (!llvm::sys::fs::exists(Status)) {
+ if (CompareFilenamesOnly)
+ addCollectedPath(Path);
+ else
+ error("Missing source file", Path);
+ return;
+ }
+
+ if (llvm::sys::fs::is_regular_file(Status)) {
+ addCollectedPath(Path);
+ return;
+ }
+
+ if (llvm::sys::fs::is_directory(Status)) {
+ std::error_code EC;
+ for (llvm::sys::fs::recursive_directory_iterator F(Path, EC), E;
+ F != E && !EC; F.increment(EC)) {
+ if (llvm::sys::fs::is_regular_file(F->path()))
+ addCollectedPath(F->path());
+ }
+ if (EC)
+ warning(EC.message(), Path);
+ }
+}
+
ErrorOr<const MemoryBuffer &>
CodeCoverageTool::getSourceFile(StringRef SourceFile) {
// If we've remapped filenames, look up the real location for this file.
cl::list<std::string> InputSourceFiles(
cl::Positional, cl::desc("<Source files>"), cl::ZeroOrMore);
+ cl::opt<bool> DebugDumpCollectedPaths(
+ "dump-collected-paths", cl::Optional, cl::Hidden,
+ cl::desc("Show the collected paths to source files"));
+
cl::opt<std::string, true> PGOFilename(
"instr-profile", cl::Required, cl::location(this->PGOFilename),
cl::desc(
}
CoverageArch = Arch;
- for (const auto &File : InputSourceFiles) {
- SmallString<128> Path(File);
- if (!CompareFilenamesOnly) {
- if (std::error_code EC = sys::fs::make_absolute(Path)) {
- error(EC.message(), File);
- return 1;
- }
- }
- addCollectedPath(Path.str());
+ for (const std::string &File : InputSourceFiles)
+ collectPaths(File);
+
+ if (DebugDumpCollectedPaths) {
+ for (StringRef SF : SourceFiles)
+ outs() << SF << '\n';
+ ::exit(0);
}
+
return 0;
};