Mercurial > hg > CbC > CbC_llvm
comparison tools/llvm-cov/gcov.cpp @ 77:54457678186b LLVM3.6
LLVM 3.6
author | Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp> |
---|---|
date | Mon, 08 Sep 2014 22:06:00 +0900 |
parents | |
children | 60c9769439b8 |
comparison
equal
deleted
inserted
replaced
34:e874dbf0ad9d | 77:54457678186b |
---|---|
1 //===- gcov.cpp - GCOV compatible LLVM coverage tool ----------------------===// | |
2 // | |
3 // The LLVM Compiler Infrastructure | |
4 // | |
5 // This file is distributed under the University of Illinois Open Source | |
6 // License. See LICENSE.TXT for details. | |
7 // | |
8 //===----------------------------------------------------------------------===// | |
9 // | |
10 // llvm-cov is a command line tools to analyze and report coverage information. | |
11 // | |
12 //===----------------------------------------------------------------------===// | |
13 | |
14 #include "llvm/ADT/SmallString.h" | |
15 #include "llvm/Support/CommandLine.h" | |
16 #include "llvm/Support/Errc.h" | |
17 #include "llvm/Support/FileSystem.h" | |
18 #include "llvm/Support/GCOV.h" | |
19 #include "llvm/Support/ManagedStatic.h" | |
20 #include "llvm/Support/MemoryObject.h" | |
21 #include "llvm/Support/Path.h" | |
22 #include "llvm/Support/PrettyStackTrace.h" | |
23 #include "llvm/Support/Signals.h" | |
24 #include <system_error> | |
25 using namespace llvm; | |
26 | |
27 void reportCoverage(StringRef SourceFile, StringRef ObjectDir, | |
28 const std::string &InputGCNO, const std::string &InputGCDA, | |
29 bool DumpGCOV, const GCOVOptions &Options) { | |
30 SmallString<128> CoverageFileStem(ObjectDir); | |
31 if (CoverageFileStem.empty()) { | |
32 // If no directory was specified with -o, look next to the source file. | |
33 CoverageFileStem = sys::path::parent_path(SourceFile); | |
34 sys::path::append(CoverageFileStem, sys::path::stem(SourceFile)); | |
35 } else if (sys::fs::is_directory(ObjectDir)) | |
36 // A directory name was given. Use it and the source file name. | |
37 sys::path::append(CoverageFileStem, sys::path::stem(SourceFile)); | |
38 else | |
39 // A file was given. Ignore the source file and look next to this file. | |
40 sys::path::replace_extension(CoverageFileStem, ""); | |
41 | |
42 std::string GCNO = InputGCNO.empty() | |
43 ? std::string(CoverageFileStem.str()) + ".gcno" | |
44 : InputGCNO; | |
45 std::string GCDA = InputGCDA.empty() | |
46 ? std::string(CoverageFileStem.str()) + ".gcda" | |
47 : InputGCDA; | |
48 GCOVFile GF; | |
49 | |
50 ErrorOr<std::unique_ptr<MemoryBuffer>> GCNO_Buff = | |
51 MemoryBuffer::getFileOrSTDIN(GCNO); | |
52 if (std::error_code EC = GCNO_Buff.getError()) { | |
53 errs() << GCNO << ": " << EC.message() << "\n"; | |
54 return; | |
55 } | |
56 GCOVBuffer GCNO_GB(GCNO_Buff.get().get()); | |
57 if (!GF.readGCNO(GCNO_GB)) { | |
58 errs() << "Invalid .gcno File!\n"; | |
59 return; | |
60 } | |
61 | |
62 ErrorOr<std::unique_ptr<MemoryBuffer>> GCDA_Buff = | |
63 MemoryBuffer::getFileOrSTDIN(GCDA); | |
64 if (std::error_code EC = GCDA_Buff.getError()) { | |
65 if (EC != errc::no_such_file_or_directory) { | |
66 errs() << GCDA << ": " << EC.message() << "\n"; | |
67 return; | |
68 } | |
69 // Clear the filename to make it clear we didn't read anything. | |
70 GCDA = "-"; | |
71 } else { | |
72 GCOVBuffer GCDA_GB(GCDA_Buff.get().get()); | |
73 if (!GF.readGCDA(GCDA_GB)) { | |
74 errs() << "Invalid .gcda File!\n"; | |
75 return; | |
76 } | |
77 } | |
78 | |
79 if (DumpGCOV) | |
80 GF.dump(); | |
81 | |
82 FileInfo FI(Options); | |
83 GF.collectLineCounts(FI); | |
84 FI.print(SourceFile, GCNO, GCDA); | |
85 } | |
86 | |
87 int gcov_main(int argc, const char **argv) { | |
88 // Print a stack trace if we signal out. | |
89 sys::PrintStackTraceOnErrorSignal(); | |
90 PrettyStackTraceProgram X(argc, argv); | |
91 llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. | |
92 | |
93 cl::list<std::string> SourceFiles(cl::Positional, cl::OneOrMore, | |
94 cl::desc("SOURCEFILE")); | |
95 | |
96 cl::opt<bool> AllBlocks("a", cl::Grouping, cl::init(false), | |
97 cl::desc("Display all basic blocks")); | |
98 cl::alias AllBlocksA("all-blocks", cl::aliasopt(AllBlocks)); | |
99 | |
100 cl::opt<bool> BranchProb("b", cl::Grouping, cl::init(false), | |
101 cl::desc("Display branch probabilities")); | |
102 cl::alias BranchProbA("branch-probabilities", cl::aliasopt(BranchProb)); | |
103 | |
104 cl::opt<bool> BranchCount("c", cl::Grouping, cl::init(false), | |
105 cl::desc("Display branch counts instead " | |
106 "of percentages (requires -b)")); | |
107 cl::alias BranchCountA("branch-counts", cl::aliasopt(BranchCount)); | |
108 | |
109 cl::opt<bool> LongNames("l", cl::Grouping, cl::init(false), | |
110 cl::desc("Prefix filenames with the main file")); | |
111 cl::alias LongNamesA("long-file-names", cl::aliasopt(LongNames)); | |
112 | |
113 cl::opt<bool> FuncSummary("f", cl::Grouping, cl::init(false), | |
114 cl::desc("Show coverage for each function")); | |
115 cl::alias FuncSummaryA("function-summaries", cl::aliasopt(FuncSummary)); | |
116 | |
117 cl::opt<bool> NoOutput("n", cl::Grouping, cl::init(false), | |
118 cl::desc("Do not output any .gcov files")); | |
119 cl::alias NoOutputA("no-output", cl::aliasopt(NoOutput)); | |
120 | |
121 cl::opt<std::string> ObjectDir( | |
122 "o", cl::value_desc("DIR|FILE"), cl::init(""), | |
123 cl::desc("Find objects in DIR or based on FILE's path")); | |
124 cl::alias ObjectDirA("object-directory", cl::aliasopt(ObjectDir)); | |
125 cl::alias ObjectDirB("object-file", cl::aliasopt(ObjectDir)); | |
126 | |
127 cl::opt<bool> PreservePaths("p", cl::Grouping, cl::init(false), | |
128 cl::desc("Preserve path components")); | |
129 cl::alias PreservePathsA("preserve-paths", cl::aliasopt(PreservePaths)); | |
130 | |
131 cl::opt<bool> UncondBranch("u", cl::Grouping, cl::init(false), | |
132 cl::desc("Display unconditional branch info " | |
133 "(requires -b)")); | |
134 cl::alias UncondBranchA("unconditional-branches", cl::aliasopt(UncondBranch)); | |
135 | |
136 cl::OptionCategory DebugCat("Internal and debugging options"); | |
137 cl::opt<bool> DumpGCOV("dump", cl::init(false), cl::cat(DebugCat), | |
138 cl::desc("Dump the gcov file to stderr")); | |
139 cl::opt<std::string> InputGCNO("gcno", cl::cat(DebugCat), cl::init(""), | |
140 cl::desc("Override inferred gcno file")); | |
141 cl::opt<std::string> InputGCDA("gcda", cl::cat(DebugCat), cl::init(""), | |
142 cl::desc("Override inferred gcda file")); | |
143 | |
144 cl::ParseCommandLineOptions(argc, argv, "LLVM code coverage tool\n"); | |
145 | |
146 GCOVOptions Options(AllBlocks, BranchProb, BranchCount, FuncSummary, | |
147 PreservePaths, UncondBranch, LongNames, NoOutput); | |
148 | |
149 for (const auto &SourceFile : SourceFiles) | |
150 reportCoverage(SourceFile, ObjectDir, InputGCNO, InputGCDA, DumpGCOV, | |
151 Options); | |
152 return 0; | |
153 } |