From: Justin Bogner Date: Tue, 18 Feb 2014 09:19:48 +0000 (+0000) Subject: llvm-cov: Support gcov's extermely lenient treatment of -o X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=257ed1ed698011f1c23f47ca4f1c5f4cf4efbd41;p=oota-llvm.git llvm-cov: Support gcov's extermely lenient treatment of -o In gcov, the -o flag can accept either a directory or a file name. When given a directory, the gcda and gcno files are expected to be in that directory. When given a file, the gcda and gcno files are expected to be named based on the stem of that file. Non-existent paths are treated as files. This implements compatible behaviour. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@201555 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/test/tools/llvm-cov/llvm-cov.test b/test/tools/llvm-cov/llvm-cov.test index c52a9815229..afd657be249 100644 --- a/test/tools/llvm-cov/llvm-cov.test +++ b/test/tools/llvm-cov/llvm-cov.test @@ -21,6 +21,16 @@ RUN: llvm-cov -o objdir test.c | diff -u test_no_options.output - RUN: diff -aub test_objdir.cpp.gcov test.cpp.gcov RUN: diff -aub test_objdir.h.gcov test.h.gcov +# Specifying an object file +RUN: llvm-cov -o objdir/test.o test.c | diff -u test_no_options.output - +RUN: diff -aub test_objdir.cpp.gcov test.cpp.gcov +RUN: diff -aub test_objdir.h.gcov test.h.gcov + +# Specifying an object file that could be ambiguous with a directory +RUN: llvm-cov -o objdir/test test.c | diff -u test_no_options.output - +RUN: diff -aub test_objdir.cpp.gcov test.cpp.gcov +RUN: diff -aub test_objdir.h.gcov test.h.gcov + # Preserve paths. This mangles the output filenames. RUN: mkdir -p %t/srcdir/nested_dir RUN: cp test.cpp test.h %t/srcdir diff --git a/tools/llvm-cov/llvm-cov.cpp b/tools/llvm-cov/llvm-cov.cpp index d7162c46882..ce59694ad29 100644 --- a/tools/llvm-cov/llvm-cov.cpp +++ b/tools/llvm-cov/llvm-cov.cpp @@ -14,6 +14,7 @@ #include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/SmallString.h" #include "llvm/Support/CommandLine.h" +#include "llvm/Support/FileSystem.h" #include "llvm/Support/GCOV.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/MemoryObject.h" @@ -43,9 +44,11 @@ static cl::opt FuncSummary("f", cl::init(false), cl::desc("Show coverage for each function")); static cl::alias FuncSummaryA("function-summaries", cl::aliasopt(FuncSummary)); -static cl::opt ObjectDir("o", cl::value_desc("DIR"), cl::init(""), - cl::desc("Search for objects in DIR")); +static cl::opt +ObjectDir("o", cl::value_desc("DIR|FILE"), cl::init(""), + cl::desc("Find objects in DIR or based on FILE's path")); static cl::alias ObjectDirA("object-directory", cl::aliasopt(ObjectDir)); +static cl::alias ObjectDirB("object-file", cl::aliasopt(ObjectDir)); static cl::opt PreservePaths("p", cl::init(false), cl::desc("Preserve path components")); @@ -75,9 +78,16 @@ int main(int argc, char **argv) { cl::ParseCommandLineOptions(argc, argv, "LLVM code coverage tool\n"); SmallString<128> CoverageFileStem(ObjectDir); - if (CoverageFileStem.empty()) + if (CoverageFileStem.empty()) { + // If no directory was specified with -o, look next to the source file. CoverageFileStem = sys::path::parent_path(SourceFile); - sys::path::append(CoverageFileStem, sys::path::stem(SourceFile)); + sys::path::append(CoverageFileStem, sys::path::stem(SourceFile)); + } else if (sys::fs::is_directory(ObjectDir)) + // A directory name was given. Use it and the source file name. + sys::path::append(CoverageFileStem, sys::path::stem(SourceFile)); + else + // A file was given. Ignore the source file and look next to this file. + sys::path::replace_extension(CoverageFileStem, ""); if (InputGCNO.empty()) InputGCNO = (CoverageFileStem.str() + ".gcno").str();