From: Fangrui Song Date: Thu, 17 Sep 2020 06:18:46 +0000 (-0700) Subject: [llvm-cov gcov] Add --demangled-names (-m) X-Git-Tag: llvmorg-13-init~11780 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=c16417f65f9a9eb3718efa3ece63ba910f91f77b;p=platform%2Fupstream%2Fllvm.git [llvm-cov gcov] Add --demangled-names (-m) gcov 4.9 introduced the option. --- diff --git a/llvm/include/llvm/ProfileData/GCOV.h b/llvm/include/llvm/ProfileData/GCOV.h index 452cf45..2766ff5 100644 --- a/llvm/include/llvm/ProfileData/GCOV.h +++ b/llvm/include/llvm/ProfileData/GCOV.h @@ -47,11 +47,11 @@ enum GCOVVersion { V304, V407, V408, V800, V900 }; /// A struct for passing gcov options between functions. struct Options { Options(bool A, bool B, bool C, bool F, bool P, bool U, bool I, bool L, - bool N, bool R, bool T, bool X, std::string SourcePrefix) + bool M, bool N, bool R, bool T, bool X, std::string SourcePrefix) : AllBlocks(A), BranchInfo(B), BranchCount(C), FuncCoverage(F), PreservePaths(P), UncondBranch(U), Intermediate(I), LongFileNames(L), - NoOutput(N), RelativeOnly(R), UseStdout(T), HashFilenames(X), - SourcePrefix(std::move(SourcePrefix)) {} + Demangle(M), NoOutput(N), RelativeOnly(R), UseStdout(T), + HashFilenames(X), SourcePrefix(std::move(SourcePrefix)) {} bool AllBlocks; bool BranchInfo; @@ -61,6 +61,7 @@ struct Options { bool UncondBranch; bool Intermediate; bool LongFileNames; + bool Demangle; bool NoOutput; bool RelativeOnly; bool UseStdout; @@ -232,7 +233,7 @@ public: GCOVFunction(GCOVFile &file) : file(file) {} - StringRef getName() const { return Name; } + StringRef getName(bool demangle) const; StringRef getFilename() const; uint64_t getEntryCount() const; GCOVBlock &getExitBlock() const; @@ -255,6 +256,7 @@ public: uint32_t endColumn = 0; uint8_t artificial = 0; StringRef Name; + mutable SmallString<0> demangled; unsigned srcIdx; SmallVector, 0> blocks; SmallVector, 0> arcs, treeArcs; diff --git a/llvm/lib/ProfileData/GCOV.cpp b/llvm/lib/ProfileData/GCOV.cpp index 0597797..1d8aec0 100644 --- a/llvm/lib/ProfileData/GCOV.cpp +++ b/llvm/lib/ProfileData/GCOV.cpp @@ -14,6 +14,7 @@ #include "llvm/ProfileData/GCOV.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Config/llvm-config.h" +#include "llvm/Demangle/Demangle.h" #include "llvm/Support/Debug.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/Format.h" @@ -316,6 +317,26 @@ bool GCOVArc::onTree() const { return flags & GCOV_ARC_ON_TREE; } //===----------------------------------------------------------------------===// // GCOVFunction implementation. +StringRef GCOVFunction::getName(bool demangle) const { + if (!demangle) + return Name; + if (demangled.empty()) { + do { + if (Name.startswith("_Z")) { + int status = 0; + // Name is guaranteed to be NUL-terminated. + char *res = itaniumDemangle(Name.data(), nullptr, nullptr, &status); + if (status == 0) { + demangled = res; + free(res); + break; + } + } + demangled = Name; + } while (0); + } + return demangled; +} StringRef GCOVFunction::getFilename() const { return file.filenames[srcIdx]; } /// getEntryCount - Get the number of times the function was called by @@ -785,7 +806,7 @@ void Context::printSourceToIntermediate(const SourceInfo &si, for (const auto &fs : si.startLineToFunctions) for (const GCOVFunction *f : fs) os << "function:" << f->startLine << ',' << f->getEntryCount() << ',' - << f->Name << '\n'; + << f->getName(options.Demangle) << '\n'; for (size_t lineNum = 1, size = si.lines.size(); lineNum < size; ++lineNum) { const LineInfo &line = si.lines[lineNum]; if (line.blocks.empty()) @@ -832,7 +853,7 @@ void Context::print(StringRef filename, StringRef gcno, StringRef gcda, raw_ostream &os = llvm::outs(); for (GCOVFunction &f : make_pointee_range(file.functions)) { - Summary summary(f.Name); + Summary summary(f.getName(options.Demangle)); collectFunction(f, summary); if (options.FuncCoverage && !options.UseStdout) { os << "Function '" << summary.Name << "'\n"; @@ -900,8 +921,9 @@ void Context::printFunctionDetails(const GCOVFunction &f, if (b.number != 0 && &b != &exitBlock && b.getCount()) ++blocksExec; - os << "function " << f.getName() << " called " << entryCount << " returned " - << formatPercentage(exitCount, entryCount) << "% blocks executed " + os << "function " << f.getName(options.Demangle) << " called " << entryCount + << " returned " << formatPercentage(exitCount, entryCount) + << "% blocks executed " << formatPercentage(blocksExec, f.blocks.size() - 2) << "%\n"; } diff --git a/llvm/lib/ProfileData/LLVMBuild.txt b/llvm/lib/ProfileData/LLVMBuild.txt index 335c226..2fffab2 100644 --- a/llvm/lib/ProfileData/LLVMBuild.txt +++ b/llvm/lib/ProfileData/LLVMBuild.txt @@ -21,4 +21,4 @@ subdirectories = Coverage type = Library name = ProfileData parent = Libraries -required_libraries = Core Support +required_libraries = Core Support Demangle diff --git a/llvm/test/tools/llvm-cov/gcov/demangled-names.test b/llvm/test/tools/llvm-cov/gcov/demangled-names.test new file mode 100644 index 0000000..31cb05f --- /dev/null +++ b/llvm/test/tools/llvm-cov/gcov/demangled-names.test @@ -0,0 +1,10 @@ +# Test --demangled-names (-m). +RUN: rm -rf %t && mkdir %t && cd %t +RUN: cp %S/Inputs/test.cpp %S/Inputs/test.gcno %S/Inputs/test.gcda . + +RUN: llvm-cov gcov -b -f -m test.gcda | FileCheck %s +RUN: llvm-cov gcov -b -f --demangled-names test.gcda | FileCheck %s +RUN: FileCheck %s --check-prefix=BRANCH < test.cpp.gcov + +CHECK: Function 'A::B()' +BRANCH: function A::B() called diff --git a/llvm/tools/llvm-cov/gcov.cpp b/llvm/tools/llvm-cov/gcov.cpp index 8d2876b..d42e7cd 100644 --- a/llvm/tools/llvm-cov/gcov.cpp +++ b/llvm/tools/llvm-cov/gcov.cpp @@ -115,6 +115,11 @@ int gcovMain(int argc, const char *argv[]) { cl::Grouping, cl::NotHidden, cl::aliasopt(Intermediate)); + cl::opt Demangle("demangled-names", cl::init(false), + cl::desc("Demangle function names")); + cl::alias DemangleA("m", cl::desc("Alias for --demangled-names"), + cl::Grouping, cl::NotHidden, cl::aliasopt(Demangle)); + cl::opt NoOutput("n", cl::Grouping, cl::init(false), cl::desc("Do not output any .gcov files")); cl::alias NoOutputA("no-output", cl::aliasopt(NoOutput)); @@ -163,8 +168,8 @@ int gcovMain(int argc, const char *argv[]) { GCOV::Options Options(AllBlocks, BranchProb, BranchCount, FuncSummary, PreservePaths, UncondBranch, Intermediate, LongNames, - NoOutput, RelativeOnly, UseStdout, HashFilenames, - SourcePrefix); + Demangle, NoOutput, RelativeOnly, UseStdout, + HashFilenames, SourcePrefix); for (const auto &SourceFile : SourceFiles) reportCoverage(SourceFile, ObjectDir, InputGCNO, InputGCDA, DumpGCOV,