1*9880d681SAndroid Build Coastguard Worker //===- CodeCoverage.cpp - Coverage tool based on profiling instrumentation-===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // The 'CodeCoverageTool' class implements a command line tool to analyze and
11*9880d681SAndroid Build Coastguard Worker // report coverage information using the profiling instrumentation and code
12*9880d681SAndroid Build Coastguard Worker // coverage mapping.
13*9880d681SAndroid Build Coastguard Worker //
14*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
15*9880d681SAndroid Build Coastguard Worker
16*9880d681SAndroid Build Coastguard Worker #include "CoverageFilters.h"
17*9880d681SAndroid Build Coastguard Worker #include "CoverageReport.h"
18*9880d681SAndroid Build Coastguard Worker #include "CoverageViewOptions.h"
19*9880d681SAndroid Build Coastguard Worker #include "RenderingSupport.h"
20*9880d681SAndroid Build Coastguard Worker #include "SourceCoverageView.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/SmallString.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/StringRef.h"
23*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/Triple.h"
24*9880d681SAndroid Build Coastguard Worker #include "llvm/ProfileData/Coverage/CoverageMapping.h"
25*9880d681SAndroid Build Coastguard Worker #include "llvm/ProfileData/InstrProfReader.h"
26*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/CommandLine.h"
27*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/FileSystem.h"
28*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Format.h"
29*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Path.h"
30*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Process.h"
31*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/ThreadPool.h"
32*9880d681SAndroid Build Coastguard Worker #include <functional>
33*9880d681SAndroid Build Coastguard Worker #include <system_error>
34*9880d681SAndroid Build Coastguard Worker
35*9880d681SAndroid Build Coastguard Worker using namespace llvm;
36*9880d681SAndroid Build Coastguard Worker using namespace coverage;
37*9880d681SAndroid Build Coastguard Worker
38*9880d681SAndroid Build Coastguard Worker namespace {
39*9880d681SAndroid Build Coastguard Worker /// \brief The implementation of the coverage tool.
40*9880d681SAndroid Build Coastguard Worker class CodeCoverageTool {
41*9880d681SAndroid Build Coastguard Worker public:
42*9880d681SAndroid Build Coastguard Worker enum Command {
43*9880d681SAndroid Build Coastguard Worker /// \brief The show command.
44*9880d681SAndroid Build Coastguard Worker Show,
45*9880d681SAndroid Build Coastguard Worker /// \brief The report command.
46*9880d681SAndroid Build Coastguard Worker Report
47*9880d681SAndroid Build Coastguard Worker };
48*9880d681SAndroid Build Coastguard Worker
49*9880d681SAndroid Build Coastguard Worker /// \brief Print the error message to the error output stream.
50*9880d681SAndroid Build Coastguard Worker void error(const Twine &Message, StringRef Whence = "");
51*9880d681SAndroid Build Coastguard Worker
52*9880d681SAndroid Build Coastguard Worker /// \brief Record (but do not print) an error message in a thread-safe way.
53*9880d681SAndroid Build Coastguard Worker void deferError(const Twine &Message, StringRef Whence = "");
54*9880d681SAndroid Build Coastguard Worker
55*9880d681SAndroid Build Coastguard Worker /// \brief Record (but do not print) a warning message in a thread-safe way.
56*9880d681SAndroid Build Coastguard Worker void deferWarning(const Twine &Message, StringRef Whence = "");
57*9880d681SAndroid Build Coastguard Worker
58*9880d681SAndroid Build Coastguard Worker /// \brief Print (and then clear) all deferred error and warning messages.
59*9880d681SAndroid Build Coastguard Worker void consumeDeferredMessages();
60*9880d681SAndroid Build Coastguard Worker
61*9880d681SAndroid Build Coastguard Worker /// \brief Append a reference to a private copy of \p Path into SourceFiles.
62*9880d681SAndroid Build Coastguard Worker void addCollectedPath(const std::string &Path);
63*9880d681SAndroid Build Coastguard Worker
64*9880d681SAndroid Build Coastguard Worker /// \brief Return a memory buffer for the given source file.
65*9880d681SAndroid Build Coastguard Worker ErrorOr<const MemoryBuffer &> getSourceFile(StringRef SourceFile);
66*9880d681SAndroid Build Coastguard Worker
67*9880d681SAndroid Build Coastguard Worker /// \brief Create source views for the expansions of the view.
68*9880d681SAndroid Build Coastguard Worker void attachExpansionSubViews(SourceCoverageView &View,
69*9880d681SAndroid Build Coastguard Worker ArrayRef<ExpansionRecord> Expansions,
70*9880d681SAndroid Build Coastguard Worker CoverageMapping &Coverage);
71*9880d681SAndroid Build Coastguard Worker
72*9880d681SAndroid Build Coastguard Worker /// \brief Create the source view of a particular function.
73*9880d681SAndroid Build Coastguard Worker std::unique_ptr<SourceCoverageView>
74*9880d681SAndroid Build Coastguard Worker createFunctionView(const FunctionRecord &Function, CoverageMapping &Coverage);
75*9880d681SAndroid Build Coastguard Worker
76*9880d681SAndroid Build Coastguard Worker /// \brief Create the main source view of a particular source file.
77*9880d681SAndroid Build Coastguard Worker std::unique_ptr<SourceCoverageView>
78*9880d681SAndroid Build Coastguard Worker createSourceFileView(StringRef SourceFile, CoverageMapping &Coverage);
79*9880d681SAndroid Build Coastguard Worker
80*9880d681SAndroid Build Coastguard Worker /// \brief Load the coverage mapping data. Return true if an error occured.
81*9880d681SAndroid Build Coastguard Worker std::unique_ptr<CoverageMapping> load();
82*9880d681SAndroid Build Coastguard Worker
83*9880d681SAndroid Build Coastguard Worker int run(Command Cmd, int argc, const char **argv);
84*9880d681SAndroid Build Coastguard Worker
85*9880d681SAndroid Build Coastguard Worker typedef llvm::function_ref<int(int, const char **)> CommandLineParserType;
86*9880d681SAndroid Build Coastguard Worker
87*9880d681SAndroid Build Coastguard Worker int show(int argc, const char **argv,
88*9880d681SAndroid Build Coastguard Worker CommandLineParserType commandLineParser);
89*9880d681SAndroid Build Coastguard Worker
90*9880d681SAndroid Build Coastguard Worker int report(int argc, const char **argv,
91*9880d681SAndroid Build Coastguard Worker CommandLineParserType commandLineParser);
92*9880d681SAndroid Build Coastguard Worker
93*9880d681SAndroid Build Coastguard Worker std::string ObjectFilename;
94*9880d681SAndroid Build Coastguard Worker CoverageViewOptions ViewOpts;
95*9880d681SAndroid Build Coastguard Worker std::string PGOFilename;
96*9880d681SAndroid Build Coastguard Worker CoverageFiltersMatchAll Filters;
97*9880d681SAndroid Build Coastguard Worker std::vector<StringRef> SourceFiles;
98*9880d681SAndroid Build Coastguard Worker bool CompareFilenamesOnly;
99*9880d681SAndroid Build Coastguard Worker StringMap<std::string> RemappedFilenames;
100*9880d681SAndroid Build Coastguard Worker std::string CoverageArch;
101*9880d681SAndroid Build Coastguard Worker
102*9880d681SAndroid Build Coastguard Worker private:
103*9880d681SAndroid Build Coastguard Worker std::vector<std::string> CollectedPaths;
104*9880d681SAndroid Build Coastguard Worker
105*9880d681SAndroid Build Coastguard Worker std::mutex DeferredMessagesLock;
106*9880d681SAndroid Build Coastguard Worker std::vector<std::string> DeferredMessages;
107*9880d681SAndroid Build Coastguard Worker
108*9880d681SAndroid Build Coastguard Worker std::mutex LoadedSourceFilesLock;
109*9880d681SAndroid Build Coastguard Worker std::vector<std::pair<std::string, std::unique_ptr<MemoryBuffer>>>
110*9880d681SAndroid Build Coastguard Worker LoadedSourceFiles;
111*9880d681SAndroid Build Coastguard Worker };
112*9880d681SAndroid Build Coastguard Worker }
113*9880d681SAndroid Build Coastguard Worker
getErrorString(const Twine & Message,StringRef Whence,bool Warning)114*9880d681SAndroid Build Coastguard Worker static std::string getErrorString(const Twine &Message, StringRef Whence,
115*9880d681SAndroid Build Coastguard Worker bool Warning) {
116*9880d681SAndroid Build Coastguard Worker std::string Str = (Warning ? "warning" : "error");
117*9880d681SAndroid Build Coastguard Worker Str += ": ";
118*9880d681SAndroid Build Coastguard Worker if (!Whence.empty())
119*9880d681SAndroid Build Coastguard Worker Str += Whence;
120*9880d681SAndroid Build Coastguard Worker Str += Message.str() + "\n";
121*9880d681SAndroid Build Coastguard Worker return Str;
122*9880d681SAndroid Build Coastguard Worker }
123*9880d681SAndroid Build Coastguard Worker
error(const Twine & Message,StringRef Whence)124*9880d681SAndroid Build Coastguard Worker void CodeCoverageTool::error(const Twine &Message, StringRef Whence) {
125*9880d681SAndroid Build Coastguard Worker errs() << getErrorString(Message, Whence, false);
126*9880d681SAndroid Build Coastguard Worker }
127*9880d681SAndroid Build Coastguard Worker
deferError(const Twine & Message,StringRef Whence)128*9880d681SAndroid Build Coastguard Worker void CodeCoverageTool::deferError(const Twine &Message, StringRef Whence) {
129*9880d681SAndroid Build Coastguard Worker std::unique_lock<std::mutex> Guard{DeferredMessagesLock};
130*9880d681SAndroid Build Coastguard Worker DeferredMessages.emplace_back(getErrorString(Message, Whence, false));
131*9880d681SAndroid Build Coastguard Worker }
132*9880d681SAndroid Build Coastguard Worker
deferWarning(const Twine & Message,StringRef Whence)133*9880d681SAndroid Build Coastguard Worker void CodeCoverageTool::deferWarning(const Twine &Message, StringRef Whence) {
134*9880d681SAndroid Build Coastguard Worker std::unique_lock<std::mutex> Guard{DeferredMessagesLock};
135*9880d681SAndroid Build Coastguard Worker DeferredMessages.emplace_back(getErrorString(Message, Whence, true));
136*9880d681SAndroid Build Coastguard Worker }
137*9880d681SAndroid Build Coastguard Worker
consumeDeferredMessages()138*9880d681SAndroid Build Coastguard Worker void CodeCoverageTool::consumeDeferredMessages() {
139*9880d681SAndroid Build Coastguard Worker std::unique_lock<std::mutex> Guard{DeferredMessagesLock};
140*9880d681SAndroid Build Coastguard Worker for (const std::string &Message : DeferredMessages)
141*9880d681SAndroid Build Coastguard Worker ViewOpts.colored_ostream(errs(), raw_ostream::RED) << Message;
142*9880d681SAndroid Build Coastguard Worker DeferredMessages.clear();
143*9880d681SAndroid Build Coastguard Worker }
144*9880d681SAndroid Build Coastguard Worker
addCollectedPath(const std::string & Path)145*9880d681SAndroid Build Coastguard Worker void CodeCoverageTool::addCollectedPath(const std::string &Path) {
146*9880d681SAndroid Build Coastguard Worker CollectedPaths.push_back(Path);
147*9880d681SAndroid Build Coastguard Worker SourceFiles.emplace_back(CollectedPaths.back());
148*9880d681SAndroid Build Coastguard Worker }
149*9880d681SAndroid Build Coastguard Worker
150*9880d681SAndroid Build Coastguard Worker ErrorOr<const MemoryBuffer &>
getSourceFile(StringRef SourceFile)151*9880d681SAndroid Build Coastguard Worker CodeCoverageTool::getSourceFile(StringRef SourceFile) {
152*9880d681SAndroid Build Coastguard Worker // If we've remapped filenames, look up the real location for this file.
153*9880d681SAndroid Build Coastguard Worker if (!RemappedFilenames.empty()) {
154*9880d681SAndroid Build Coastguard Worker auto Loc = RemappedFilenames.find(SourceFile);
155*9880d681SAndroid Build Coastguard Worker if (Loc != RemappedFilenames.end())
156*9880d681SAndroid Build Coastguard Worker SourceFile = Loc->second;
157*9880d681SAndroid Build Coastguard Worker }
158*9880d681SAndroid Build Coastguard Worker for (const auto &Files : LoadedSourceFiles)
159*9880d681SAndroid Build Coastguard Worker if (sys::fs::equivalent(SourceFile, Files.first))
160*9880d681SAndroid Build Coastguard Worker return *Files.second;
161*9880d681SAndroid Build Coastguard Worker auto Buffer = MemoryBuffer::getFile(SourceFile);
162*9880d681SAndroid Build Coastguard Worker if (auto EC = Buffer.getError()) {
163*9880d681SAndroid Build Coastguard Worker deferError(EC.message(), SourceFile);
164*9880d681SAndroid Build Coastguard Worker return EC;
165*9880d681SAndroid Build Coastguard Worker }
166*9880d681SAndroid Build Coastguard Worker std::unique_lock<std::mutex> Guard{LoadedSourceFilesLock};
167*9880d681SAndroid Build Coastguard Worker LoadedSourceFiles.emplace_back(SourceFile, std::move(Buffer.get()));
168*9880d681SAndroid Build Coastguard Worker return *LoadedSourceFiles.back().second;
169*9880d681SAndroid Build Coastguard Worker }
170*9880d681SAndroid Build Coastguard Worker
171*9880d681SAndroid Build Coastguard Worker void
attachExpansionSubViews(SourceCoverageView & View,ArrayRef<ExpansionRecord> Expansions,CoverageMapping & Coverage)172*9880d681SAndroid Build Coastguard Worker CodeCoverageTool::attachExpansionSubViews(SourceCoverageView &View,
173*9880d681SAndroid Build Coastguard Worker ArrayRef<ExpansionRecord> Expansions,
174*9880d681SAndroid Build Coastguard Worker CoverageMapping &Coverage) {
175*9880d681SAndroid Build Coastguard Worker if (!ViewOpts.ShowExpandedRegions)
176*9880d681SAndroid Build Coastguard Worker return;
177*9880d681SAndroid Build Coastguard Worker for (const auto &Expansion : Expansions) {
178*9880d681SAndroid Build Coastguard Worker auto ExpansionCoverage = Coverage.getCoverageForExpansion(Expansion);
179*9880d681SAndroid Build Coastguard Worker if (ExpansionCoverage.empty())
180*9880d681SAndroid Build Coastguard Worker continue;
181*9880d681SAndroid Build Coastguard Worker auto SourceBuffer = getSourceFile(ExpansionCoverage.getFilename());
182*9880d681SAndroid Build Coastguard Worker if (!SourceBuffer)
183*9880d681SAndroid Build Coastguard Worker continue;
184*9880d681SAndroid Build Coastguard Worker
185*9880d681SAndroid Build Coastguard Worker auto SubViewExpansions = ExpansionCoverage.getExpansions();
186*9880d681SAndroid Build Coastguard Worker auto SubView =
187*9880d681SAndroid Build Coastguard Worker SourceCoverageView::create(Expansion.Function.Name, SourceBuffer.get(),
188*9880d681SAndroid Build Coastguard Worker ViewOpts, std::move(ExpansionCoverage));
189*9880d681SAndroid Build Coastguard Worker attachExpansionSubViews(*SubView, SubViewExpansions, Coverage);
190*9880d681SAndroid Build Coastguard Worker View.addExpansion(Expansion.Region, std::move(SubView));
191*9880d681SAndroid Build Coastguard Worker }
192*9880d681SAndroid Build Coastguard Worker }
193*9880d681SAndroid Build Coastguard Worker
194*9880d681SAndroid Build Coastguard Worker std::unique_ptr<SourceCoverageView>
createFunctionView(const FunctionRecord & Function,CoverageMapping & Coverage)195*9880d681SAndroid Build Coastguard Worker CodeCoverageTool::createFunctionView(const FunctionRecord &Function,
196*9880d681SAndroid Build Coastguard Worker CoverageMapping &Coverage) {
197*9880d681SAndroid Build Coastguard Worker auto FunctionCoverage = Coverage.getCoverageForFunction(Function);
198*9880d681SAndroid Build Coastguard Worker if (FunctionCoverage.empty())
199*9880d681SAndroid Build Coastguard Worker return nullptr;
200*9880d681SAndroid Build Coastguard Worker auto SourceBuffer = getSourceFile(FunctionCoverage.getFilename());
201*9880d681SAndroid Build Coastguard Worker if (!SourceBuffer)
202*9880d681SAndroid Build Coastguard Worker return nullptr;
203*9880d681SAndroid Build Coastguard Worker
204*9880d681SAndroid Build Coastguard Worker auto Expansions = FunctionCoverage.getExpansions();
205*9880d681SAndroid Build Coastguard Worker auto View = SourceCoverageView::create(Function.Name, SourceBuffer.get(),
206*9880d681SAndroid Build Coastguard Worker ViewOpts, std::move(FunctionCoverage));
207*9880d681SAndroid Build Coastguard Worker attachExpansionSubViews(*View, Expansions, Coverage);
208*9880d681SAndroid Build Coastguard Worker
209*9880d681SAndroid Build Coastguard Worker return View;
210*9880d681SAndroid Build Coastguard Worker }
211*9880d681SAndroid Build Coastguard Worker
212*9880d681SAndroid Build Coastguard Worker std::unique_ptr<SourceCoverageView>
createSourceFileView(StringRef SourceFile,CoverageMapping & Coverage)213*9880d681SAndroid Build Coastguard Worker CodeCoverageTool::createSourceFileView(StringRef SourceFile,
214*9880d681SAndroid Build Coastguard Worker CoverageMapping &Coverage) {
215*9880d681SAndroid Build Coastguard Worker auto SourceBuffer = getSourceFile(SourceFile);
216*9880d681SAndroid Build Coastguard Worker if (!SourceBuffer)
217*9880d681SAndroid Build Coastguard Worker return nullptr;
218*9880d681SAndroid Build Coastguard Worker auto FileCoverage = Coverage.getCoverageForFile(SourceFile);
219*9880d681SAndroid Build Coastguard Worker if (FileCoverage.empty())
220*9880d681SAndroid Build Coastguard Worker return nullptr;
221*9880d681SAndroid Build Coastguard Worker
222*9880d681SAndroid Build Coastguard Worker auto Expansions = FileCoverage.getExpansions();
223*9880d681SAndroid Build Coastguard Worker auto View = SourceCoverageView::create(SourceFile, SourceBuffer.get(),
224*9880d681SAndroid Build Coastguard Worker ViewOpts, std::move(FileCoverage));
225*9880d681SAndroid Build Coastguard Worker attachExpansionSubViews(*View, Expansions, Coverage);
226*9880d681SAndroid Build Coastguard Worker
227*9880d681SAndroid Build Coastguard Worker for (auto Function : Coverage.getInstantiations(SourceFile)) {
228*9880d681SAndroid Build Coastguard Worker auto SubViewCoverage = Coverage.getCoverageForFunction(*Function);
229*9880d681SAndroid Build Coastguard Worker auto SubViewExpansions = SubViewCoverage.getExpansions();
230*9880d681SAndroid Build Coastguard Worker auto SubView =
231*9880d681SAndroid Build Coastguard Worker SourceCoverageView::create(Function->Name, SourceBuffer.get(), ViewOpts,
232*9880d681SAndroid Build Coastguard Worker std::move(SubViewCoverage));
233*9880d681SAndroid Build Coastguard Worker attachExpansionSubViews(*SubView, SubViewExpansions, Coverage);
234*9880d681SAndroid Build Coastguard Worker
235*9880d681SAndroid Build Coastguard Worker if (SubView) {
236*9880d681SAndroid Build Coastguard Worker unsigned FileID = Function->CountedRegions.front().FileID;
237*9880d681SAndroid Build Coastguard Worker unsigned Line = 0;
238*9880d681SAndroid Build Coastguard Worker for (const auto &CR : Function->CountedRegions)
239*9880d681SAndroid Build Coastguard Worker if (CR.FileID == FileID)
240*9880d681SAndroid Build Coastguard Worker Line = std::max(CR.LineEnd, Line);
241*9880d681SAndroid Build Coastguard Worker View->addInstantiation(Function->Name, Line, std::move(SubView));
242*9880d681SAndroid Build Coastguard Worker }
243*9880d681SAndroid Build Coastguard Worker }
244*9880d681SAndroid Build Coastguard Worker return View;
245*9880d681SAndroid Build Coastguard Worker }
246*9880d681SAndroid Build Coastguard Worker
modifiedTimeGT(StringRef LHS,StringRef RHS)247*9880d681SAndroid Build Coastguard Worker static bool modifiedTimeGT(StringRef LHS, StringRef RHS) {
248*9880d681SAndroid Build Coastguard Worker sys::fs::file_status Status;
249*9880d681SAndroid Build Coastguard Worker if (sys::fs::status(LHS, Status))
250*9880d681SAndroid Build Coastguard Worker return false;
251*9880d681SAndroid Build Coastguard Worker auto LHSTime = Status.getLastModificationTime();
252*9880d681SAndroid Build Coastguard Worker if (sys::fs::status(RHS, Status))
253*9880d681SAndroid Build Coastguard Worker return false;
254*9880d681SAndroid Build Coastguard Worker auto RHSTime = Status.getLastModificationTime();
255*9880d681SAndroid Build Coastguard Worker return LHSTime > RHSTime;
256*9880d681SAndroid Build Coastguard Worker }
257*9880d681SAndroid Build Coastguard Worker
load()258*9880d681SAndroid Build Coastguard Worker std::unique_ptr<CoverageMapping> CodeCoverageTool::load() {
259*9880d681SAndroid Build Coastguard Worker if (modifiedTimeGT(ObjectFilename, PGOFilename))
260*9880d681SAndroid Build Coastguard Worker errs() << "warning: profile data may be out of date - object is newer\n";
261*9880d681SAndroid Build Coastguard Worker auto CoverageOrErr = CoverageMapping::load(ObjectFilename, PGOFilename,
262*9880d681SAndroid Build Coastguard Worker CoverageArch);
263*9880d681SAndroid Build Coastguard Worker if (Error E = CoverageOrErr.takeError()) {
264*9880d681SAndroid Build Coastguard Worker colored_ostream(errs(), raw_ostream::RED)
265*9880d681SAndroid Build Coastguard Worker << "error: Failed to load coverage: " << toString(std::move(E)) << "\n";
266*9880d681SAndroid Build Coastguard Worker return nullptr;
267*9880d681SAndroid Build Coastguard Worker }
268*9880d681SAndroid Build Coastguard Worker auto Coverage = std::move(CoverageOrErr.get());
269*9880d681SAndroid Build Coastguard Worker unsigned Mismatched = Coverage->getMismatchedCount();
270*9880d681SAndroid Build Coastguard Worker if (Mismatched) {
271*9880d681SAndroid Build Coastguard Worker colored_ostream(errs(), raw_ostream::RED)
272*9880d681SAndroid Build Coastguard Worker << "warning: " << Mismatched << " functions have mismatched data. ";
273*9880d681SAndroid Build Coastguard Worker errs() << "\n";
274*9880d681SAndroid Build Coastguard Worker }
275*9880d681SAndroid Build Coastguard Worker
276*9880d681SAndroid Build Coastguard Worker if (CompareFilenamesOnly) {
277*9880d681SAndroid Build Coastguard Worker auto CoveredFiles = Coverage.get()->getUniqueSourceFiles();
278*9880d681SAndroid Build Coastguard Worker for (auto &SF : SourceFiles) {
279*9880d681SAndroid Build Coastguard Worker StringRef SFBase = sys::path::filename(SF);
280*9880d681SAndroid Build Coastguard Worker for (const auto &CF : CoveredFiles)
281*9880d681SAndroid Build Coastguard Worker if (SFBase == sys::path::filename(CF)) {
282*9880d681SAndroid Build Coastguard Worker RemappedFilenames[CF] = SF;
283*9880d681SAndroid Build Coastguard Worker SF = CF;
284*9880d681SAndroid Build Coastguard Worker break;
285*9880d681SAndroid Build Coastguard Worker }
286*9880d681SAndroid Build Coastguard Worker }
287*9880d681SAndroid Build Coastguard Worker }
288*9880d681SAndroid Build Coastguard Worker
289*9880d681SAndroid Build Coastguard Worker return Coverage;
290*9880d681SAndroid Build Coastguard Worker }
291*9880d681SAndroid Build Coastguard Worker
run(Command Cmd,int argc,const char ** argv)292*9880d681SAndroid Build Coastguard Worker int CodeCoverageTool::run(Command Cmd, int argc, const char **argv) {
293*9880d681SAndroid Build Coastguard Worker cl::opt<std::string, true> ObjectFilename(
294*9880d681SAndroid Build Coastguard Worker cl::Positional, cl::Required, cl::location(this->ObjectFilename),
295*9880d681SAndroid Build Coastguard Worker cl::desc("Covered executable or object file."));
296*9880d681SAndroid Build Coastguard Worker
297*9880d681SAndroid Build Coastguard Worker cl::list<std::string> InputSourceFiles(
298*9880d681SAndroid Build Coastguard Worker cl::Positional, cl::desc("<Source files>"), cl::ZeroOrMore);
299*9880d681SAndroid Build Coastguard Worker
300*9880d681SAndroid Build Coastguard Worker cl::opt<std::string, true> PGOFilename(
301*9880d681SAndroid Build Coastguard Worker "instr-profile", cl::Required, cl::location(this->PGOFilename),
302*9880d681SAndroid Build Coastguard Worker cl::desc(
303*9880d681SAndroid Build Coastguard Worker "File with the profile data obtained after an instrumented run"));
304*9880d681SAndroid Build Coastguard Worker
305*9880d681SAndroid Build Coastguard Worker cl::opt<std::string> Arch(
306*9880d681SAndroid Build Coastguard Worker "arch", cl::desc("architecture of the coverage mapping binary"));
307*9880d681SAndroid Build Coastguard Worker
308*9880d681SAndroid Build Coastguard Worker cl::opt<bool> DebugDump("dump", cl::Optional,
309*9880d681SAndroid Build Coastguard Worker cl::desc("Show internal debug dump"));
310*9880d681SAndroid Build Coastguard Worker
311*9880d681SAndroid Build Coastguard Worker cl::opt<CoverageViewOptions::OutputFormat> Format(
312*9880d681SAndroid Build Coastguard Worker "format", cl::desc("Output format for line-based coverage reports"),
313*9880d681SAndroid Build Coastguard Worker cl::values(clEnumValN(CoverageViewOptions::OutputFormat::Text, "text",
314*9880d681SAndroid Build Coastguard Worker "Text output"),
315*9880d681SAndroid Build Coastguard Worker clEnumValN(CoverageViewOptions::OutputFormat::HTML, "html",
316*9880d681SAndroid Build Coastguard Worker "HTML output"),
317*9880d681SAndroid Build Coastguard Worker clEnumValEnd),
318*9880d681SAndroid Build Coastguard Worker cl::init(CoverageViewOptions::OutputFormat::Text));
319*9880d681SAndroid Build Coastguard Worker
320*9880d681SAndroid Build Coastguard Worker cl::opt<bool> FilenameEquivalence(
321*9880d681SAndroid Build Coastguard Worker "filename-equivalence", cl::Optional,
322*9880d681SAndroid Build Coastguard Worker cl::desc("Treat source files as equivalent to paths in the coverage data "
323*9880d681SAndroid Build Coastguard Worker "when the file names match, even if the full paths do not"));
324*9880d681SAndroid Build Coastguard Worker
325*9880d681SAndroid Build Coastguard Worker cl::OptionCategory FilteringCategory("Function filtering options");
326*9880d681SAndroid Build Coastguard Worker
327*9880d681SAndroid Build Coastguard Worker cl::list<std::string> NameFilters(
328*9880d681SAndroid Build Coastguard Worker "name", cl::Optional,
329*9880d681SAndroid Build Coastguard Worker cl::desc("Show code coverage only for functions with the given name"),
330*9880d681SAndroid Build Coastguard Worker cl::ZeroOrMore, cl::cat(FilteringCategory));
331*9880d681SAndroid Build Coastguard Worker
332*9880d681SAndroid Build Coastguard Worker cl::list<std::string> NameRegexFilters(
333*9880d681SAndroid Build Coastguard Worker "name-regex", cl::Optional,
334*9880d681SAndroid Build Coastguard Worker cl::desc("Show code coverage only for functions that match the given "
335*9880d681SAndroid Build Coastguard Worker "regular expression"),
336*9880d681SAndroid Build Coastguard Worker cl::ZeroOrMore, cl::cat(FilteringCategory));
337*9880d681SAndroid Build Coastguard Worker
338*9880d681SAndroid Build Coastguard Worker cl::opt<double> RegionCoverageLtFilter(
339*9880d681SAndroid Build Coastguard Worker "region-coverage-lt", cl::Optional,
340*9880d681SAndroid Build Coastguard Worker cl::desc("Show code coverage only for functions with region coverage "
341*9880d681SAndroid Build Coastguard Worker "less than the given threshold"),
342*9880d681SAndroid Build Coastguard Worker cl::cat(FilteringCategory));
343*9880d681SAndroid Build Coastguard Worker
344*9880d681SAndroid Build Coastguard Worker cl::opt<double> RegionCoverageGtFilter(
345*9880d681SAndroid Build Coastguard Worker "region-coverage-gt", cl::Optional,
346*9880d681SAndroid Build Coastguard Worker cl::desc("Show code coverage only for functions with region coverage "
347*9880d681SAndroid Build Coastguard Worker "greater than the given threshold"),
348*9880d681SAndroid Build Coastguard Worker cl::cat(FilteringCategory));
349*9880d681SAndroid Build Coastguard Worker
350*9880d681SAndroid Build Coastguard Worker cl::opt<double> LineCoverageLtFilter(
351*9880d681SAndroid Build Coastguard Worker "line-coverage-lt", cl::Optional,
352*9880d681SAndroid Build Coastguard Worker cl::desc("Show code coverage only for functions with line coverage less "
353*9880d681SAndroid Build Coastguard Worker "than the given threshold"),
354*9880d681SAndroid Build Coastguard Worker cl::cat(FilteringCategory));
355*9880d681SAndroid Build Coastguard Worker
356*9880d681SAndroid Build Coastguard Worker cl::opt<double> LineCoverageGtFilter(
357*9880d681SAndroid Build Coastguard Worker "line-coverage-gt", cl::Optional,
358*9880d681SAndroid Build Coastguard Worker cl::desc("Show code coverage only for functions with line coverage "
359*9880d681SAndroid Build Coastguard Worker "greater than the given threshold"),
360*9880d681SAndroid Build Coastguard Worker cl::cat(FilteringCategory));
361*9880d681SAndroid Build Coastguard Worker
362*9880d681SAndroid Build Coastguard Worker cl::opt<cl::boolOrDefault> UseColor(
363*9880d681SAndroid Build Coastguard Worker "use-color", cl::desc("Emit colored output (default=autodetect)"),
364*9880d681SAndroid Build Coastguard Worker cl::init(cl::BOU_UNSET));
365*9880d681SAndroid Build Coastguard Worker
366*9880d681SAndroid Build Coastguard Worker auto commandLineParser = [&, this](int argc, const char **argv) -> int {
367*9880d681SAndroid Build Coastguard Worker cl::ParseCommandLineOptions(argc, argv, "LLVM code coverage tool\n");
368*9880d681SAndroid Build Coastguard Worker ViewOpts.Debug = DebugDump;
369*9880d681SAndroid Build Coastguard Worker CompareFilenamesOnly = FilenameEquivalence;
370*9880d681SAndroid Build Coastguard Worker
371*9880d681SAndroid Build Coastguard Worker ViewOpts.Format = Format;
372*9880d681SAndroid Build Coastguard Worker switch (ViewOpts.Format) {
373*9880d681SAndroid Build Coastguard Worker case CoverageViewOptions::OutputFormat::Text:
374*9880d681SAndroid Build Coastguard Worker ViewOpts.Colors = UseColor == cl::BOU_UNSET
375*9880d681SAndroid Build Coastguard Worker ? sys::Process::StandardOutHasColors()
376*9880d681SAndroid Build Coastguard Worker : UseColor == cl::BOU_TRUE;
377*9880d681SAndroid Build Coastguard Worker break;
378*9880d681SAndroid Build Coastguard Worker case CoverageViewOptions::OutputFormat::HTML:
379*9880d681SAndroid Build Coastguard Worker if (UseColor == cl::BOU_FALSE)
380*9880d681SAndroid Build Coastguard Worker error("Color output cannot be disabled when generating html.");
381*9880d681SAndroid Build Coastguard Worker ViewOpts.Colors = true;
382*9880d681SAndroid Build Coastguard Worker break;
383*9880d681SAndroid Build Coastguard Worker }
384*9880d681SAndroid Build Coastguard Worker
385*9880d681SAndroid Build Coastguard Worker // Create the function filters
386*9880d681SAndroid Build Coastguard Worker if (!NameFilters.empty() || !NameRegexFilters.empty()) {
387*9880d681SAndroid Build Coastguard Worker auto NameFilterer = new CoverageFilters;
388*9880d681SAndroid Build Coastguard Worker for (const auto &Name : NameFilters)
389*9880d681SAndroid Build Coastguard Worker NameFilterer->push_back(llvm::make_unique<NameCoverageFilter>(Name));
390*9880d681SAndroid Build Coastguard Worker for (const auto &Regex : NameRegexFilters)
391*9880d681SAndroid Build Coastguard Worker NameFilterer->push_back(
392*9880d681SAndroid Build Coastguard Worker llvm::make_unique<NameRegexCoverageFilter>(Regex));
393*9880d681SAndroid Build Coastguard Worker Filters.push_back(std::unique_ptr<CoverageFilter>(NameFilterer));
394*9880d681SAndroid Build Coastguard Worker }
395*9880d681SAndroid Build Coastguard Worker if (RegionCoverageLtFilter.getNumOccurrences() ||
396*9880d681SAndroid Build Coastguard Worker RegionCoverageGtFilter.getNumOccurrences() ||
397*9880d681SAndroid Build Coastguard Worker LineCoverageLtFilter.getNumOccurrences() ||
398*9880d681SAndroid Build Coastguard Worker LineCoverageGtFilter.getNumOccurrences()) {
399*9880d681SAndroid Build Coastguard Worker auto StatFilterer = new CoverageFilters;
400*9880d681SAndroid Build Coastguard Worker if (RegionCoverageLtFilter.getNumOccurrences())
401*9880d681SAndroid Build Coastguard Worker StatFilterer->push_back(llvm::make_unique<RegionCoverageFilter>(
402*9880d681SAndroid Build Coastguard Worker RegionCoverageFilter::LessThan, RegionCoverageLtFilter));
403*9880d681SAndroid Build Coastguard Worker if (RegionCoverageGtFilter.getNumOccurrences())
404*9880d681SAndroid Build Coastguard Worker StatFilterer->push_back(llvm::make_unique<RegionCoverageFilter>(
405*9880d681SAndroid Build Coastguard Worker RegionCoverageFilter::GreaterThan, RegionCoverageGtFilter));
406*9880d681SAndroid Build Coastguard Worker if (LineCoverageLtFilter.getNumOccurrences())
407*9880d681SAndroid Build Coastguard Worker StatFilterer->push_back(llvm::make_unique<LineCoverageFilter>(
408*9880d681SAndroid Build Coastguard Worker LineCoverageFilter::LessThan, LineCoverageLtFilter));
409*9880d681SAndroid Build Coastguard Worker if (LineCoverageGtFilter.getNumOccurrences())
410*9880d681SAndroid Build Coastguard Worker StatFilterer->push_back(llvm::make_unique<LineCoverageFilter>(
411*9880d681SAndroid Build Coastguard Worker RegionCoverageFilter::GreaterThan, LineCoverageGtFilter));
412*9880d681SAndroid Build Coastguard Worker Filters.push_back(std::unique_ptr<CoverageFilter>(StatFilterer));
413*9880d681SAndroid Build Coastguard Worker }
414*9880d681SAndroid Build Coastguard Worker
415*9880d681SAndroid Build Coastguard Worker if (!Arch.empty() &&
416*9880d681SAndroid Build Coastguard Worker Triple(Arch).getArch() == llvm::Triple::ArchType::UnknownArch) {
417*9880d681SAndroid Build Coastguard Worker errs() << "error: Unknown architecture: " << Arch << "\n";
418*9880d681SAndroid Build Coastguard Worker return 1;
419*9880d681SAndroid Build Coastguard Worker }
420*9880d681SAndroid Build Coastguard Worker CoverageArch = Arch;
421*9880d681SAndroid Build Coastguard Worker
422*9880d681SAndroid Build Coastguard Worker for (const auto &File : InputSourceFiles) {
423*9880d681SAndroid Build Coastguard Worker SmallString<128> Path(File);
424*9880d681SAndroid Build Coastguard Worker if (!CompareFilenamesOnly)
425*9880d681SAndroid Build Coastguard Worker if (std::error_code EC = sys::fs::make_absolute(Path)) {
426*9880d681SAndroid Build Coastguard Worker errs() << "error: " << File << ": " << EC.message();
427*9880d681SAndroid Build Coastguard Worker return 1;
428*9880d681SAndroid Build Coastguard Worker }
429*9880d681SAndroid Build Coastguard Worker addCollectedPath(Path.str());
430*9880d681SAndroid Build Coastguard Worker }
431*9880d681SAndroid Build Coastguard Worker return 0;
432*9880d681SAndroid Build Coastguard Worker };
433*9880d681SAndroid Build Coastguard Worker
434*9880d681SAndroid Build Coastguard Worker switch (Cmd) {
435*9880d681SAndroid Build Coastguard Worker case Show:
436*9880d681SAndroid Build Coastguard Worker return show(argc, argv, commandLineParser);
437*9880d681SAndroid Build Coastguard Worker case Report:
438*9880d681SAndroid Build Coastguard Worker return report(argc, argv, commandLineParser);
439*9880d681SAndroid Build Coastguard Worker }
440*9880d681SAndroid Build Coastguard Worker return 0;
441*9880d681SAndroid Build Coastguard Worker }
442*9880d681SAndroid Build Coastguard Worker
show(int argc,const char ** argv,CommandLineParserType commandLineParser)443*9880d681SAndroid Build Coastguard Worker int CodeCoverageTool::show(int argc, const char **argv,
444*9880d681SAndroid Build Coastguard Worker CommandLineParserType commandLineParser) {
445*9880d681SAndroid Build Coastguard Worker
446*9880d681SAndroid Build Coastguard Worker cl::OptionCategory ViewCategory("Viewing options");
447*9880d681SAndroid Build Coastguard Worker
448*9880d681SAndroid Build Coastguard Worker cl::opt<bool> ShowLineExecutionCounts(
449*9880d681SAndroid Build Coastguard Worker "show-line-counts", cl::Optional,
450*9880d681SAndroid Build Coastguard Worker cl::desc("Show the execution counts for each line"), cl::init(true),
451*9880d681SAndroid Build Coastguard Worker cl::cat(ViewCategory));
452*9880d681SAndroid Build Coastguard Worker
453*9880d681SAndroid Build Coastguard Worker cl::opt<bool> ShowRegions(
454*9880d681SAndroid Build Coastguard Worker "show-regions", cl::Optional,
455*9880d681SAndroid Build Coastguard Worker cl::desc("Show the execution counts for each region"),
456*9880d681SAndroid Build Coastguard Worker cl::cat(ViewCategory));
457*9880d681SAndroid Build Coastguard Worker
458*9880d681SAndroid Build Coastguard Worker cl::opt<bool> ShowBestLineRegionsCounts(
459*9880d681SAndroid Build Coastguard Worker "show-line-counts-or-regions", cl::Optional,
460*9880d681SAndroid Build Coastguard Worker cl::desc("Show the execution counts for each line, or the execution "
461*9880d681SAndroid Build Coastguard Worker "counts for each region on lines that have multiple regions"),
462*9880d681SAndroid Build Coastguard Worker cl::cat(ViewCategory));
463*9880d681SAndroid Build Coastguard Worker
464*9880d681SAndroid Build Coastguard Worker cl::opt<bool> ShowExpansions("show-expansions", cl::Optional,
465*9880d681SAndroid Build Coastguard Worker cl::desc("Show expanded source regions"),
466*9880d681SAndroid Build Coastguard Worker cl::cat(ViewCategory));
467*9880d681SAndroid Build Coastguard Worker
468*9880d681SAndroid Build Coastguard Worker cl::opt<bool> ShowInstantiations("show-instantiations", cl::Optional,
469*9880d681SAndroid Build Coastguard Worker cl::desc("Show function instantiations"),
470*9880d681SAndroid Build Coastguard Worker cl::cat(ViewCategory));
471*9880d681SAndroid Build Coastguard Worker
472*9880d681SAndroid Build Coastguard Worker cl::opt<std::string> ShowOutputDirectory(
473*9880d681SAndroid Build Coastguard Worker "output-dir", cl::init(""),
474*9880d681SAndroid Build Coastguard Worker cl::desc("Directory in which coverage information is written out"));
475*9880d681SAndroid Build Coastguard Worker cl::alias ShowOutputDirectoryA("o", cl::desc("Alias for --output-dir"),
476*9880d681SAndroid Build Coastguard Worker cl::aliasopt(ShowOutputDirectory));
477*9880d681SAndroid Build Coastguard Worker
478*9880d681SAndroid Build Coastguard Worker auto Err = commandLineParser(argc, argv);
479*9880d681SAndroid Build Coastguard Worker if (Err)
480*9880d681SAndroid Build Coastguard Worker return Err;
481*9880d681SAndroid Build Coastguard Worker
482*9880d681SAndroid Build Coastguard Worker ViewOpts.ShowLineNumbers = true;
483*9880d681SAndroid Build Coastguard Worker ViewOpts.ShowLineStats = ShowLineExecutionCounts.getNumOccurrences() != 0 ||
484*9880d681SAndroid Build Coastguard Worker !ShowRegions || ShowBestLineRegionsCounts;
485*9880d681SAndroid Build Coastguard Worker ViewOpts.ShowRegionMarkers = ShowRegions || ShowBestLineRegionsCounts;
486*9880d681SAndroid Build Coastguard Worker ViewOpts.ShowLineStatsOrRegionMarkers = ShowBestLineRegionsCounts;
487*9880d681SAndroid Build Coastguard Worker ViewOpts.ShowExpandedRegions = ShowExpansions;
488*9880d681SAndroid Build Coastguard Worker ViewOpts.ShowFunctionInstantiations = ShowInstantiations;
489*9880d681SAndroid Build Coastguard Worker ViewOpts.ShowOutputDirectory = ShowOutputDirectory;
490*9880d681SAndroid Build Coastguard Worker
491*9880d681SAndroid Build Coastguard Worker if (ViewOpts.hasOutputDirectory()) {
492*9880d681SAndroid Build Coastguard Worker if (auto E = sys::fs::create_directories(ViewOpts.ShowOutputDirectory)) {
493*9880d681SAndroid Build Coastguard Worker error("Could not create output directory!", E.message());
494*9880d681SAndroid Build Coastguard Worker return 1;
495*9880d681SAndroid Build Coastguard Worker }
496*9880d681SAndroid Build Coastguard Worker }
497*9880d681SAndroid Build Coastguard Worker
498*9880d681SAndroid Build Coastguard Worker auto Coverage = load();
499*9880d681SAndroid Build Coastguard Worker if (!Coverage)
500*9880d681SAndroid Build Coastguard Worker return 1;
501*9880d681SAndroid Build Coastguard Worker
502*9880d681SAndroid Build Coastguard Worker auto Printer = CoveragePrinter::create(ViewOpts);
503*9880d681SAndroid Build Coastguard Worker
504*9880d681SAndroid Build Coastguard Worker if (!Filters.empty()) {
505*9880d681SAndroid Build Coastguard Worker auto OSOrErr = Printer->createViewFile("functions", /*InToplevel=*/true);
506*9880d681SAndroid Build Coastguard Worker if (Error E = OSOrErr.takeError()) {
507*9880d681SAndroid Build Coastguard Worker error(toString(std::move(E)));
508*9880d681SAndroid Build Coastguard Worker return 1;
509*9880d681SAndroid Build Coastguard Worker }
510*9880d681SAndroid Build Coastguard Worker auto OS = std::move(OSOrErr.get());
511*9880d681SAndroid Build Coastguard Worker
512*9880d681SAndroid Build Coastguard Worker // Show functions.
513*9880d681SAndroid Build Coastguard Worker for (const auto &Function : Coverage->getCoveredFunctions()) {
514*9880d681SAndroid Build Coastguard Worker if (!Filters.matches(Function))
515*9880d681SAndroid Build Coastguard Worker continue;
516*9880d681SAndroid Build Coastguard Worker
517*9880d681SAndroid Build Coastguard Worker auto mainView = createFunctionView(Function, *Coverage);
518*9880d681SAndroid Build Coastguard Worker if (!mainView) {
519*9880d681SAndroid Build Coastguard Worker ViewOpts.colored_ostream(errs(), raw_ostream::RED)
520*9880d681SAndroid Build Coastguard Worker << "warning: Could not read coverage for '" << Function.Name << "'."
521*9880d681SAndroid Build Coastguard Worker << "\n";
522*9880d681SAndroid Build Coastguard Worker continue;
523*9880d681SAndroid Build Coastguard Worker }
524*9880d681SAndroid Build Coastguard Worker
525*9880d681SAndroid Build Coastguard Worker mainView->print(*OS.get(), /*WholeFile=*/false, /*ShowSourceName=*/true);
526*9880d681SAndroid Build Coastguard Worker }
527*9880d681SAndroid Build Coastguard Worker
528*9880d681SAndroid Build Coastguard Worker Printer->closeViewFile(std::move(OS));
529*9880d681SAndroid Build Coastguard Worker return 0;
530*9880d681SAndroid Build Coastguard Worker }
531*9880d681SAndroid Build Coastguard Worker
532*9880d681SAndroid Build Coastguard Worker // Show files
533*9880d681SAndroid Build Coastguard Worker bool ShowFilenames = SourceFiles.size() != 1;
534*9880d681SAndroid Build Coastguard Worker
535*9880d681SAndroid Build Coastguard Worker if (SourceFiles.empty())
536*9880d681SAndroid Build Coastguard Worker // Get the source files from the function coverage mapping.
537*9880d681SAndroid Build Coastguard Worker for (StringRef Filename : Coverage->getUniqueSourceFiles())
538*9880d681SAndroid Build Coastguard Worker SourceFiles.push_back(Filename);
539*9880d681SAndroid Build Coastguard Worker
540*9880d681SAndroid Build Coastguard Worker // Create an index out of the source files.
541*9880d681SAndroid Build Coastguard Worker if (ViewOpts.hasOutputDirectory()) {
542*9880d681SAndroid Build Coastguard Worker if (Error E = Printer->createIndexFile(SourceFiles)) {
543*9880d681SAndroid Build Coastguard Worker error(toString(std::move(E)));
544*9880d681SAndroid Build Coastguard Worker return 1;
545*9880d681SAndroid Build Coastguard Worker }
546*9880d681SAndroid Build Coastguard Worker }
547*9880d681SAndroid Build Coastguard Worker
548*9880d681SAndroid Build Coastguard Worker // In -output-dir mode, it's safe to use multiple threads to print files.
549*9880d681SAndroid Build Coastguard Worker unsigned ThreadCount = 1;
550*9880d681SAndroid Build Coastguard Worker if (ViewOpts.hasOutputDirectory())
551*9880d681SAndroid Build Coastguard Worker ThreadCount = std::thread::hardware_concurrency();
552*9880d681SAndroid Build Coastguard Worker ThreadPool Pool(ThreadCount);
553*9880d681SAndroid Build Coastguard Worker
554*9880d681SAndroid Build Coastguard Worker for (StringRef &SourceFile : SourceFiles) {
555*9880d681SAndroid Build Coastguard Worker Pool.async([this, &SourceFile, &Coverage, &Printer, ShowFilenames] {
556*9880d681SAndroid Build Coastguard Worker auto View = createSourceFileView(SourceFile, *Coverage);
557*9880d681SAndroid Build Coastguard Worker if (!View) {
558*9880d681SAndroid Build Coastguard Worker deferWarning("The file '" + SourceFile.str() + "' isn't covered.");
559*9880d681SAndroid Build Coastguard Worker return;
560*9880d681SAndroid Build Coastguard Worker }
561*9880d681SAndroid Build Coastguard Worker
562*9880d681SAndroid Build Coastguard Worker auto OSOrErr = Printer->createViewFile(SourceFile, /*InToplevel=*/false);
563*9880d681SAndroid Build Coastguard Worker if (Error E = OSOrErr.takeError()) {
564*9880d681SAndroid Build Coastguard Worker deferError(toString(std::move(E)));
565*9880d681SAndroid Build Coastguard Worker return;
566*9880d681SAndroid Build Coastguard Worker }
567*9880d681SAndroid Build Coastguard Worker auto OS = std::move(OSOrErr.get());
568*9880d681SAndroid Build Coastguard Worker
569*9880d681SAndroid Build Coastguard Worker View->print(*OS.get(), /*Wholefile=*/true,
570*9880d681SAndroid Build Coastguard Worker /*ShowSourceName=*/ShowFilenames);
571*9880d681SAndroid Build Coastguard Worker Printer->closeViewFile(std::move(OS));
572*9880d681SAndroid Build Coastguard Worker });
573*9880d681SAndroid Build Coastguard Worker }
574*9880d681SAndroid Build Coastguard Worker
575*9880d681SAndroid Build Coastguard Worker Pool.wait();
576*9880d681SAndroid Build Coastguard Worker
577*9880d681SAndroid Build Coastguard Worker consumeDeferredMessages();
578*9880d681SAndroid Build Coastguard Worker
579*9880d681SAndroid Build Coastguard Worker return 0;
580*9880d681SAndroid Build Coastguard Worker }
581*9880d681SAndroid Build Coastguard Worker
report(int argc,const char ** argv,CommandLineParserType commandLineParser)582*9880d681SAndroid Build Coastguard Worker int CodeCoverageTool::report(int argc, const char **argv,
583*9880d681SAndroid Build Coastguard Worker CommandLineParserType commandLineParser) {
584*9880d681SAndroid Build Coastguard Worker auto Err = commandLineParser(argc, argv);
585*9880d681SAndroid Build Coastguard Worker if (Err)
586*9880d681SAndroid Build Coastguard Worker return Err;
587*9880d681SAndroid Build Coastguard Worker
588*9880d681SAndroid Build Coastguard Worker if (ViewOpts.Format == CoverageViewOptions::OutputFormat::HTML)
589*9880d681SAndroid Build Coastguard Worker error("HTML output for summary reports is not yet supported.");
590*9880d681SAndroid Build Coastguard Worker
591*9880d681SAndroid Build Coastguard Worker auto Coverage = load();
592*9880d681SAndroid Build Coastguard Worker if (!Coverage)
593*9880d681SAndroid Build Coastguard Worker return 1;
594*9880d681SAndroid Build Coastguard Worker
595*9880d681SAndroid Build Coastguard Worker CoverageReport Report(ViewOpts, std::move(Coverage));
596*9880d681SAndroid Build Coastguard Worker if (SourceFiles.empty())
597*9880d681SAndroid Build Coastguard Worker Report.renderFileReports(llvm::outs());
598*9880d681SAndroid Build Coastguard Worker else
599*9880d681SAndroid Build Coastguard Worker Report.renderFunctionReports(SourceFiles, llvm::outs());
600*9880d681SAndroid Build Coastguard Worker return 0;
601*9880d681SAndroid Build Coastguard Worker }
602*9880d681SAndroid Build Coastguard Worker
showMain(int argc,const char * argv[])603*9880d681SAndroid Build Coastguard Worker int showMain(int argc, const char *argv[]) {
604*9880d681SAndroid Build Coastguard Worker CodeCoverageTool Tool;
605*9880d681SAndroid Build Coastguard Worker return Tool.run(CodeCoverageTool::Show, argc, argv);
606*9880d681SAndroid Build Coastguard Worker }
607*9880d681SAndroid Build Coastguard Worker
reportMain(int argc,const char * argv[])608*9880d681SAndroid Build Coastguard Worker int reportMain(int argc, const char *argv[]) {
609*9880d681SAndroid Build Coastguard Worker CodeCoverageTool Tool;
610*9880d681SAndroid Build Coastguard Worker return Tool.run(CodeCoverageTool::Report, argc, argv);
611*9880d681SAndroid Build Coastguard Worker }
612