[llvm] c16417f - [llvm-cov gcov] Add --demangled-names (-m)

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 16 23:19:13 PDT 2020


Author: Fangrui Song
Date: 2020-09-16T23:18:50-07:00
New Revision: c16417f65f9a9eb3718efa3ece63ba910f91f77b

URL: https://github.com/llvm/llvm-project/commit/c16417f65f9a9eb3718efa3ece63ba910f91f77b
DIFF: https://github.com/llvm/llvm-project/commit/c16417f65f9a9eb3718efa3ece63ba910f91f77b.diff

LOG: [llvm-cov gcov] Add --demangled-names (-m)

gcov 4.9 introduced the option.

Added: 
    llvm/test/tools/llvm-cov/gcov/demangled-names.test

Modified: 
    llvm/include/llvm/ProfileData/GCOV.h
    llvm/lib/ProfileData/GCOV.cpp
    llvm/lib/ProfileData/LLVMBuild.txt
    llvm/tools/llvm-cov/gcov.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/ProfileData/GCOV.h b/llvm/include/llvm/ProfileData/GCOV.h
index 452cf458f4e9..2766ff52e4a0 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 @@ class GCOVFunction {
 
   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 @@ class GCOVFunction {
   uint32_t endColumn = 0;
   uint8_t artificial = 0;
   StringRef Name;
+  mutable SmallString<0> demangled;
   unsigned srcIdx;
   SmallVector<std::unique_ptr<GCOVBlock>, 0> blocks;
   SmallVector<std::unique_ptr<GCOVArc>, 0> arcs, treeArcs;

diff  --git a/llvm/lib/ProfileData/GCOV.cpp b/llvm/lib/ProfileData/GCOV.cpp
index 0597797c6561..1d8aec08c0ee 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 335c2260a002..2fffab24579b 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 000000000000..31cb05fdca57
--- /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 8d2876b6f42e..d42e7cd3b551 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<bool> 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<bool> 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,


        


More information about the llvm-commits mailing list