[llvm] r275640 - [llvm-cov] Optionally use a symbol demangler when preparing reports
Vedant Kumar via llvm-commits
llvm-commits at lists.llvm.org
Sun Jul 17 21:50:00 PDT 2016
I'm not sure what the issue is yet, but I'm taking a look.
Sorry for the breakage.
vedant
> On Jul 17, 2016, at 8:11 PM, Reid Kleckner <rnk at google.com> wrote:
>
> This test doesn't pass on Windows:
> http://lab.llvm.org:8011/builders/clang-x86-win2008-selfhost/builds/9141/steps/ninja%20check%201/logs/FAIL%3A%20LLVM%3A%3Ademangle.test
>
> On Fri, Jul 15, 2016 at 3:44 PM, Vedant Kumar via llvm-commits <llvm-commits at lists.llvm.org> wrote:
> Author: vedantk
> Date: Fri Jul 15 17:44:57 2016
> New Revision: 275640
>
> URL: http://llvm.org/viewvc/llvm-project?rev=275640&view=rev
> Log:
> [llvm-cov] Optionally use a symbol demangler when preparing reports
>
> Add an option to specify a symbol demangler (as well as options to the
> demangler). This can be used to make reports more human-readable.
>
> This option is especially useful in -output-dir mode, since it isn't as
> easy to manually pipe reports into a demangler in this mode.
>
> Added:
> llvm/trunk/test/tools/llvm-cov/demangle.test
> Modified:
> llvm/trunk/docs/CommandGuide/llvm-cov.rst
> llvm/trunk/tools/llvm-cov/CodeCoverage.cpp
> llvm/trunk/tools/llvm-cov/CoverageViewOptions.h
>
> Modified: llvm/trunk/docs/CommandGuide/llvm-cov.rst
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/CommandGuide/llvm-cov.rst?rev=275640&r1=275639&r2=275640&view=diff
> ==============================================================================
> --- llvm/trunk/docs/CommandGuide/llvm-cov.rst (original)
> +++ llvm/trunk/docs/CommandGuide/llvm-cov.rst Fri Jul 15 17:44:57 2016
> @@ -248,6 +248,14 @@ OPTIONS
> PATH/functions.EXTENSION. When used in file view mode, a report for each file
> is written to PATH/REL_PATH_TO_FILE.EXTENSION.
>
> +.. option:: -Xdemangler=<TOOL>|<TOOL-OPTION>
> +
> + Specify a symbol demangler. This can be used to make reports more
> + human-readable. This option can be specified multiple times to supply
> + arguments to the demangler (e.g `-Xdemangler c++filt -Xdemangler -n` for C++).
> + The demangler is expected to read a newline-separated list of symbols from
> + stdin and write a newline-separated list of the same length to stdout.
> +
> .. option:: -line-coverage-gt=<N>
>
> Show code coverage only for functions with line coverage greater than the
>
> Added: llvm/trunk/test/tools/llvm-cov/demangle.test
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-cov/demangle.test?rev=275640&view=auto
> ==============================================================================
> --- llvm/trunk/test/tools/llvm-cov/demangle.test (added)
> +++ llvm/trunk/test/tools/llvm-cov/demangle.test Fri Jul 15 17:44:57 2016
> @@ -0,0 +1,4 @@
> +// RUN: llvm-cov show %S/Inputs/templateInstantiations.covmapping -instr-profile %S/Inputs/templateInstantiations.profdata -Xdemangler sed -Xdemangler 's/_/X/g' -filename-equivalence %S/showTemplateInstantiations.cpp | FileCheck %s
> +
> +// CHECK: XZ4funcIbEiTX:
> +// CHECK: XZ4funcIiEiTX:
>
> Modified: llvm/trunk/tools/llvm-cov/CodeCoverage.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-cov/CodeCoverage.cpp?rev=275640&r1=275639&r2=275640&view=diff
> ==============================================================================
> --- llvm/trunk/tools/llvm-cov/CodeCoverage.cpp (original)
> +++ llvm/trunk/tools/llvm-cov/CodeCoverage.cpp Fri Jul 15 17:44:57 2016
> @@ -26,9 +26,12 @@
> #include "llvm/Support/CommandLine.h"
> #include "llvm/Support/FileSystem.h"
> #include "llvm/Support/Format.h"
> +#include "llvm/Support/MemoryBuffer.h"
> #include "llvm/Support/Path.h"
> #include "llvm/Support/Process.h"
> +#include "llvm/Support/Program.h"
> #include "llvm/Support/ThreadPool.h"
> +#include "llvm/Support/ToolOutputFile.h"
> #include <functional>
> #include <system_error>
>
> @@ -81,6 +84,12 @@ public:
> /// \brief Load the coverage mapping data. Return nullptr if an error occured.
> std::unique_ptr<CoverageMapping> load();
>
> + /// \brief If a demangler is available, demangle all symbol names.
> + void demangleSymbols(const CoverageMapping &Coverage);
> +
> + /// \brief Demangle \p Sym if possible. Otherwise, just return \p Sym.
> + StringRef getSymbolForHumans(StringRef Sym) const;
> +
> int run(Command Cmd, int argc, const char **argv);
>
> typedef llvm::function_ref<int(int, const char **)> CommandLineParserType;
> @@ -101,6 +110,9 @@ public:
> std::string CoverageArch;
>
> private:
> + /// A cache for demangled symbol names.
> + StringMap<std::string> DemangledNames;
> +
> /// File paths (absolute, or otherwise) to input source files.
> std::vector<std::string> CollectedPaths;
>
> @@ -205,8 +217,9 @@ CodeCoverageTool::createFunctionView(con
> return nullptr;
>
> auto Expansions = FunctionCoverage.getExpansions();
> - auto View = SourceCoverageView::create(Function.Name, SourceBuffer.get(),
> - ViewOpts, std::move(FunctionCoverage));
> + auto View = SourceCoverageView::create(getSymbolForHumans(Function.Name),
> + SourceBuffer.get(), ViewOpts,
> + std::move(FunctionCoverage));
> attachExpansionSubViews(*View, Expansions, Coverage);
>
> return View;
> @@ -230,9 +243,9 @@ CodeCoverageTool::createSourceFileView(S
> for (const auto *Function : Coverage.getInstantiations(SourceFile)) {
> auto SubViewCoverage = Coverage.getCoverageForFunction(*Function);
> auto SubViewExpansions = SubViewCoverage.getExpansions();
> - auto SubView =
> - SourceCoverageView::create(Function->Name, SourceBuffer.get(), ViewOpts,
> - std::move(SubViewCoverage));
> + auto SubView = SourceCoverageView::create(
> + getSymbolForHumans(Function->Name), SourceBuffer.get(), ViewOpts,
> + std::move(SubViewCoverage));
> attachExpansionSubViews(*SubView, SubViewExpansions, Coverage);
>
> if (SubView) {
> @@ -289,9 +302,91 @@ std::unique_ptr<CoverageMapping> CodeCov
> }
> }
>
> + demangleSymbols(*Coverage);
> +
> return Coverage;
> }
>
> +void CodeCoverageTool::demangleSymbols(const CoverageMapping &Coverage) {
> + if (!ViewOpts.hasDemangler())
> + return;
> +
> + // Pass function names to the demangler in a temporary file.
> + int InputFD;
> + SmallString<256> InputPath;
> + std::error_code EC =
> + sys::fs::createTemporaryFile("demangle-in", "list", InputFD, InputPath);
> + if (EC) {
> + error(InputPath, EC.message());
> + return;
> + }
> + tool_output_file InputTOF{InputPath, InputFD};
> +
> + unsigned NumSymbols = 0;
> + for (const auto &Function : Coverage.getCoveredFunctions()) {
> + InputTOF.os() << Function.Name << '\n';
> + ++NumSymbols;
> + }
> + InputTOF.os().flush();
> +
> + // Use another temporary file to store the demangler's output.
> + int OutputFD;
> + SmallString<256> OutputPath;
> + EC = sys::fs::createTemporaryFile("demangle-out", "list", OutputFD,
> + OutputPath);
> + if (EC) {
> + error(OutputPath, EC.message());
> + return;
> + }
> + tool_output_file OutputTOF{OutputPath, OutputFD};
> +
> + // Invoke the demangler.
> + std::vector<const char *> ArgsV;
> + for (const std::string &Arg : ViewOpts.DemanglerOpts)
> + ArgsV.push_back(Arg.c_str());
> + ArgsV.push_back(nullptr);
> + StringRef InputPathRef{InputPath}, OutputPathRef{OutputPath}, StderrRef;
> + const StringRef *Redirects[] = {&InputPathRef, &OutputPathRef, &StderrRef};
> + std::string ErrMsg;
> + int RC = sys::ExecuteAndWait(ViewOpts.DemanglerOpts[0], ArgsV.data(),
> + /*env=*/nullptr, Redirects, /*secondsToWait=*/0,
> + /*memoryLimit=*/0, &ErrMsg);
> + if (RC) {
> + error(ErrMsg, ViewOpts.DemanglerOpts[0]);
> + return;
> + }
> +
> + // Parse the demangler's output.
> + auto BufOrError = MemoryBuffer::getFile(OutputPath);
> + if (!BufOrError) {
> + error(OutputPath, BufOrError.getError().message());
> + return;
> + }
> +
> + std::unique_ptr<MemoryBuffer> DemanglerBuf = std::move(*BufOrError);
> +
> + SmallVector<StringRef, 8> Symbols;
> + StringRef DemanglerData = DemanglerBuf->getBuffer();
> + DemanglerData.split(Symbols, '\n', /*MaxSplit=*/NumSymbols,
> + /*KeepEmpty=*/false);
> + if (Symbols.size() != NumSymbols) {
> + error("Demangler did not provide expected number of symbols");
> + return;
> + }
> +
> + // Cache the demangled names.
> + unsigned I = 0;
> + for (const auto &Function : Coverage.getCoveredFunctions())
> + DemangledNames[Function.Name] = Symbols[I++];
> +}
> +
> +StringRef CodeCoverageTool::getSymbolForHumans(StringRef Sym) const {
> + const auto DemangledName = DemangledNames.find(Sym);
> + if (DemangledName == DemangledNames.end())
> + return Sym;
> + return DemangledName->getValue();
> +}
> +
> int CodeCoverageTool::run(Command Cmd, int argc, const char **argv) {
> cl::opt<std::string, true> ObjectFilename(
> cl::Positional, cl::Required, cl::location(this->ObjectFilename),
> @@ -366,6 +461,9 @@ int CodeCoverageTool::run(Command Cmd, i
> "use-color", cl::desc("Emit colored output (default=autodetect)"),
> cl::init(cl::BOU_UNSET));
>
> + cl::list<std::string> DemanglerOpts(
> + "Xdemangler", cl::desc("<demangler-path>|<demangler-option>"));
> +
> auto commandLineParser = [&, this](int argc, const char **argv) -> int {
> cl::ParseCommandLineOptions(argc, argv, "LLVM code coverage tool\n");
> ViewOpts.Debug = DebugDump;
> @@ -385,6 +483,18 @@ int CodeCoverageTool::run(Command Cmd, i
> break;
> }
>
> + // If a demangler is supplied, check if it exists and register it.
> + if (DemanglerOpts.size()) {
> + auto DemanglerPathOrErr = sys::findProgramByName(DemanglerOpts[0]);
> + if (!DemanglerPathOrErr) {
> + error("Could not find the demangler!",
> + DemanglerPathOrErr.getError().message());
> + return 1;
> + }
> + DemanglerOpts[0] = *DemanglerPathOrErr;
> + ViewOpts.DemanglerOpts.swap(DemanglerOpts);
> + }
> +
> // Create the function filters
> if (!NameFilters.empty() || !NameRegexFilters.empty()) {
> auto NameFilterer = new CoverageFilters;
>
> Modified: llvm/trunk/tools/llvm-cov/CoverageViewOptions.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-cov/CoverageViewOptions.h?rev=275640&r1=275639&r2=275640&view=diff
> ==============================================================================
> --- llvm/trunk/tools/llvm-cov/CoverageViewOptions.h (original)
> +++ llvm/trunk/tools/llvm-cov/CoverageViewOptions.h Fri Jul 15 17:44:57 2016
> @@ -11,6 +11,7 @@
> #define LLVM_COV_COVERAGEVIEWOPTIONS_H
>
> #include "RenderingSupport.h"
> +#include <vector>
>
> namespace llvm {
>
> @@ -32,6 +33,7 @@ struct CoverageViewOptions {
> bool ShowFullFilenames;
> OutputFormat Format;
> std::string ShowOutputDirectory;
> + std::vector<std::string> DemanglerOpts;
>
> /// \brief Change the output's stream color if the colors are enabled.
> ColoredRawOstream colored_ostream(raw_ostream &OS,
> @@ -41,6 +43,9 @@ struct CoverageViewOptions {
>
> /// \brief Check if an output directory has been specified.
> bool hasOutputDirectory() const { return !ShowOutputDirectory.empty(); }
> +
> + /// \brief Check if a demangler has been specified.
> + bool hasDemangler() const { return !DemanglerOpts.empty(); }
> };
> }
>
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>
More information about the llvm-commits
mailing list