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

gcov 4.9 introduced the option.
This commit is contained in:
Fangrui Song 2020-09-16 23:18:46 -07:00
parent 4ce84b0e70
commit c16417f65f
5 changed files with 50 additions and 11 deletions

View File

@ -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<std::unique_ptr<GCOVBlock>, 0> blocks;
SmallVector<std::unique_ptr<GCOVArc>, 0> arcs, treeArcs;

View File

@ -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";
}

View File

@ -21,4 +21,4 @@ subdirectories = Coverage
type = Library
name = ProfileData
parent = Libraries
required_libraries = Core Support
required_libraries = Core Support Demangle

View File

@ -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

View File

@ -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,