comparison tools/llvm-cov/CodeCoverage.cpp @ 95:afa8332a0e37 LLVM3.8

LLVM 3.8
author Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
date Tue, 13 Oct 2015 17:48:58 +0900
parents 60c9769439b8
children 1172e4bd9c6f
comparison
equal deleted inserted replaced
84:f3e34b893a5f 95:afa8332a0e37
18 #include "CoverageReport.h" 18 #include "CoverageReport.h"
19 #include "CoverageViewOptions.h" 19 #include "CoverageViewOptions.h"
20 #include "SourceCoverageView.h" 20 #include "SourceCoverageView.h"
21 #include "llvm/ADT/SmallString.h" 21 #include "llvm/ADT/SmallString.h"
22 #include "llvm/ADT/StringRef.h" 22 #include "llvm/ADT/StringRef.h"
23 #include "llvm/ADT/Triple.h"
23 #include "llvm/ProfileData/CoverageMapping.h" 24 #include "llvm/ProfileData/CoverageMapping.h"
24 #include "llvm/ProfileData/InstrProfReader.h" 25 #include "llvm/ProfileData/InstrProfReader.h"
25 #include "llvm/Support/CommandLine.h" 26 #include "llvm/Support/CommandLine.h"
26 #include "llvm/Support/FileSystem.h" 27 #include "llvm/Support/FileSystem.h"
27 #include "llvm/Support/Format.h" 28 #include "llvm/Support/Format.h"
28 #include "llvm/Support/ManagedStatic.h" 29 #include "llvm/Support/ManagedStatic.h"
29 #include "llvm/Support/Path.h" 30 #include "llvm/Support/Path.h"
30 #include "llvm/Support/PrettyStackTrace.h" 31 #include "llvm/Support/PrettyStackTrace.h"
32 #include "llvm/Support/Process.h"
31 #include "llvm/Support/Signals.h" 33 #include "llvm/Support/Signals.h"
32 #include <functional> 34 #include <functional>
33 #include <system_error> 35 #include <system_error>
34 36
35 using namespace llvm; 37 using namespace llvm;
85 std::vector<std::string> SourceFiles; 87 std::vector<std::string> SourceFiles;
86 std::vector<std::pair<std::string, std::unique_ptr<MemoryBuffer>>> 88 std::vector<std::pair<std::string, std::unique_ptr<MemoryBuffer>>>
87 LoadedSourceFiles; 89 LoadedSourceFiles;
88 bool CompareFilenamesOnly; 90 bool CompareFilenamesOnly;
89 StringMap<std::string> RemappedFilenames; 91 StringMap<std::string> RemappedFilenames;
92 std::string CoverageArch;
90 }; 93 };
91 } 94 }
92 95
93 void CodeCoverageTool::error(const Twine &Message, StringRef Whence) { 96 void CodeCoverageTool::error(const Twine &Message, StringRef Whence) {
94 errs() << "error: "; 97 errs() << "error: ";
111 auto Buffer = MemoryBuffer::getFile(SourceFile); 114 auto Buffer = MemoryBuffer::getFile(SourceFile);
112 if (auto EC = Buffer.getError()) { 115 if (auto EC = Buffer.getError()) {
113 error(EC.message(), SourceFile); 116 error(EC.message(), SourceFile);
114 return EC; 117 return EC;
115 } 118 }
116 LoadedSourceFiles.push_back( 119 LoadedSourceFiles.emplace_back(SourceFile, std::move(Buffer.get()));
117 std::make_pair(SourceFile, std::move(Buffer.get())));
118 return *LoadedSourceFiles.back().second; 120 return *LoadedSourceFiles.back().second;
119 } 121 }
120 122
121 void 123 void
122 CodeCoverageTool::attachExpansionSubViews(SourceCoverageView &View, 124 CodeCoverageTool::attachExpansionSubViews(SourceCoverageView &View,
190 } 192 }
191 } 193 }
192 return View; 194 return View;
193 } 195 }
194 196
197 static bool modifiedTimeGT(StringRef LHS, StringRef RHS) {
198 sys::fs::file_status Status;
199 if (sys::fs::status(LHS, Status))
200 return false;
201 auto LHSTime = Status.getLastModificationTime();
202 if (sys::fs::status(RHS, Status))
203 return false;
204 auto RHSTime = Status.getLastModificationTime();
205 return LHSTime > RHSTime;
206 }
207
195 std::unique_ptr<CoverageMapping> CodeCoverageTool::load() { 208 std::unique_ptr<CoverageMapping> CodeCoverageTool::load() {
196 auto CoverageOrErr = CoverageMapping::load(ObjectFilename, PGOFilename); 209 if (modifiedTimeGT(ObjectFilename, PGOFilename))
210 errs() << "warning: profile data may be out of date - object is newer\n";
211 auto CoverageOrErr = CoverageMapping::load(ObjectFilename, PGOFilename,
212 CoverageArch);
197 if (std::error_code EC = CoverageOrErr.getError()) { 213 if (std::error_code EC = CoverageOrErr.getError()) {
198 colored_ostream(errs(), raw_ostream::RED) 214 colored_ostream(errs(), raw_ostream::RED)
199 << "error: Failed to load coverage: " << EC.message(); 215 << "error: Failed to load coverage: " << EC.message();
200 errs() << "\n"; 216 errs() << "\n";
201 return nullptr; 217 return nullptr;
240 cl::opt<std::string, true> PGOFilename( 256 cl::opt<std::string, true> PGOFilename(
241 "instr-profile", cl::Required, cl::location(this->PGOFilename), 257 "instr-profile", cl::Required, cl::location(this->PGOFilename),
242 cl::desc( 258 cl::desc(
243 "File with the profile data obtained after an instrumented run")); 259 "File with the profile data obtained after an instrumented run"));
244 260
261 cl::opt<std::string> Arch(
262 "arch", cl::desc("architecture of the coverage mapping binary"));
263
245 cl::opt<bool> DebugDump("dump", cl::Optional, 264 cl::opt<bool> DebugDump("dump", cl::Optional,
246 cl::desc("Show internal debug dump")); 265 cl::desc("Show internal debug dump"));
247 266
248 cl::opt<bool> FilenameEquivalence( 267 cl::opt<bool> FilenameEquivalence(
249 "filename-equivalence", cl::Optional, 268 "filename-equivalence", cl::Optional,
285 "line-coverage-gt", cl::Optional, 304 "line-coverage-gt", cl::Optional,
286 cl::desc("Show code coverage only for functions with line coverage " 305 cl::desc("Show code coverage only for functions with line coverage "
287 "greater than the given threshold"), 306 "greater than the given threshold"),
288 cl::cat(FilteringCategory)); 307 cl::cat(FilteringCategory));
289 308
309 cl::opt<cl::boolOrDefault> UseColor(
310 "use-color", cl::desc("Emit colored output (default=autodetect)"),
311 cl::init(cl::BOU_UNSET));
312
290 auto commandLineParser = [&, this](int argc, const char **argv) -> int { 313 auto commandLineParser = [&, this](int argc, const char **argv) -> int {
291 cl::ParseCommandLineOptions(argc, argv, "LLVM code coverage tool\n"); 314 cl::ParseCommandLineOptions(argc, argv, "LLVM code coverage tool\n");
292 ViewOpts.Debug = DebugDump; 315 ViewOpts.Debug = DebugDump;
293 CompareFilenamesOnly = FilenameEquivalence; 316 CompareFilenamesOnly = FilenameEquivalence;
317
318 ViewOpts.Colors = UseColor == cl::BOU_UNSET
319 ? sys::Process::StandardOutHasColors()
320 : UseColor == cl::BOU_TRUE;
294 321
295 // Create the function filters 322 // Create the function filters
296 if (!NameFilters.empty() || !NameRegexFilters.empty()) { 323 if (!NameFilters.empty() || !NameRegexFilters.empty()) {
297 auto NameFilterer = new CoverageFilters; 324 auto NameFilterer = new CoverageFilters;
298 for (const auto &Name : NameFilters) 325 for (const auto &Name : NameFilters)
320 StatFilterer->push_back(llvm::make_unique<LineCoverageFilter>( 347 StatFilterer->push_back(llvm::make_unique<LineCoverageFilter>(
321 RegionCoverageFilter::GreaterThan, LineCoverageGtFilter)); 348 RegionCoverageFilter::GreaterThan, LineCoverageGtFilter));
322 Filters.push_back(std::unique_ptr<CoverageFilter>(StatFilterer)); 349 Filters.push_back(std::unique_ptr<CoverageFilter>(StatFilterer));
323 } 350 }
324 351
352 if (!Arch.empty() &&
353 Triple(Arch).getArch() == llvm::Triple::ArchType::UnknownArch) {
354 errs() << "error: Unknown architecture: " << Arch << "\n";
355 return 1;
356 }
357 CoverageArch = Arch;
358
325 for (const auto &File : InputSourceFiles) { 359 for (const auto &File : InputSourceFiles) {
326 SmallString<128> Path(File); 360 SmallString<128> Path(File);
327 if (!CompareFilenamesOnly) 361 if (!CompareFilenamesOnly)
328 if (std::error_code EC = sys::fs::make_absolute(Path)) { 362 if (std::error_code EC = sys::fs::make_absolute(Path)) {
329 errs() << "error: " << File << ": " << EC.message(); 363 errs() << "error: " << File << ": " << EC.message();
370 404
371 cl::opt<bool> ShowInstantiations("show-instantiations", cl::Optional, 405 cl::opt<bool> ShowInstantiations("show-instantiations", cl::Optional,
372 cl::desc("Show function instantiations"), 406 cl::desc("Show function instantiations"),
373 cl::cat(ViewCategory)); 407 cl::cat(ViewCategory));
374 408
375 cl::opt<bool> NoColors("no-colors", cl::Optional,
376 cl::desc("Don't show text colors"), cl::init(false),
377 cl::cat(ViewCategory));
378
379 auto Err = commandLineParser(argc, argv); 409 auto Err = commandLineParser(argc, argv);
380 if (Err) 410 if (Err)
381 return Err; 411 return Err;
382 412
383 ViewOpts.Colors = !NoColors;
384 ViewOpts.ShowLineNumbers = true; 413 ViewOpts.ShowLineNumbers = true;
385 ViewOpts.ShowLineStats = ShowLineExecutionCounts.getNumOccurrences() != 0 || 414 ViewOpts.ShowLineStats = ShowLineExecutionCounts.getNumOccurrences() != 0 ||
386 !ShowRegions || ShowBestLineRegionsCounts; 415 !ShowRegions || ShowBestLineRegionsCounts;
387 ViewOpts.ShowRegionMarkers = ShowRegions || ShowBestLineRegionsCounts; 416 ViewOpts.ShowRegionMarkers = ShowRegions || ShowBestLineRegionsCounts;
388 ViewOpts.ShowLineStatsOrRegionMarkers = ShowBestLineRegionsCounts; 417 ViewOpts.ShowLineStatsOrRegionMarkers = ShowBestLineRegionsCounts;
444 return 0; 473 return 0;
445 } 474 }
446 475
447 int CodeCoverageTool::report(int argc, const char **argv, 476 int CodeCoverageTool::report(int argc, const char **argv,
448 CommandLineParserType commandLineParser) { 477 CommandLineParserType commandLineParser) {
449 cl::opt<bool> NoColors("no-colors", cl::Optional,
450 cl::desc("Don't show text colors"), cl::init(false));
451
452 auto Err = commandLineParser(argc, argv); 478 auto Err = commandLineParser(argc, argv);
453 if (Err) 479 if (Err)
454 return Err; 480 return Err;
455
456 ViewOpts.Colors = !NoColors;
457 481
458 auto Coverage = load(); 482 auto Coverage = load();
459 if (!Coverage) 483 if (!Coverage)
460 return 1; 484 return 1;
461 485