18277737b6a9618637c6e31479fad4fe548f0c64
[oota-llvm.git] / tools / llvm-cov / llvm-cov.cpp
1 //===- tools/llvm-cov/llvm-cov.cpp - 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/OwningPtr.h"
15 #include "llvm/Support/CommandLine.h"
16 #include "llvm/Support/GCOV.h"
17 #include "llvm/Support/ManagedStatic.h"
18 #include "llvm/Support/MemoryObject.h"
19 #include "llvm/Support/PrettyStackTrace.h"
20 #include "llvm/Support/raw_ostream.h"
21 #include "llvm/Support/Signals.h"
22 #include "llvm/Support/system_error.h"
23 #include <unistd.h>
24 using namespace llvm;
25
26 static cl::opt<bool>
27 DumpGCOV("dump", cl::init(false), cl::desc("dump gcov file"));
28
29 static cl::opt<std::string>
30 InputGCNO("gcno", cl::desc("<input gcno file>"), cl::init(""));
31
32 static cl::opt<std::string>
33 InputGCDA("gcda", cl::desc("<input gcda file>"), cl::init(""));
34
35 static cl::opt<std::string>
36 OutputFile("o", cl::desc("<output llvm-cov file>"), cl::init("-"));
37
38 static cl::opt<std::string>
39 WorkingDir("C", cl::desc("change path of working directory"),
40            cl::init(""));
41
42 //===----------------------------------------------------------------------===//
43 int main(int argc, char **argv) {
44   // Print a stack trace if we signal out.
45   sys::PrintStackTraceOnErrorSignal();
46   PrettyStackTraceProgram X(argc, argv);
47   llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.
48
49   cl::ParseCommandLineOptions(argc, argv, "llvm coverage tool\n");
50
51   if (!WorkingDir.empty()) {
52     if (chdir(WorkingDir.c_str()) == -1) {
53       errs() << "Cannot change to directory: " << WorkingDir << ".\n";
54       return 1;
55     }
56   }
57
58   std::string ErrorInfo;
59   raw_fd_ostream OS(OutputFile.c_str(), ErrorInfo);
60   if (!ErrorInfo.empty())
61     errs() << ErrorInfo << "\n";
62
63   GCOVFile GF;
64   if (InputGCNO.empty())
65     errs() << " " << argv[0] << ": No gcov input file!\n";
66
67   OwningPtr<MemoryBuffer> GCNO_Buff;
68   if (error_code ec = MemoryBuffer::getFileOrSTDIN(InputGCNO, GCNO_Buff)) {
69     errs() << InputGCNO << ": " << ec.message() << "\n";
70     return 1;
71   }
72   GCOVBuffer GCNO_GB(GCNO_Buff.take());
73   if (!GF.read(GCNO_GB)) {
74     errs() << "Invalid .gcno File!\n";
75     return 1;
76   }
77
78   if (!InputGCDA.empty()) {
79     OwningPtr<MemoryBuffer> GCDA_Buff;
80     if (error_code ec = MemoryBuffer::getFileOrSTDIN(InputGCDA, GCDA_Buff)) {
81       errs() << InputGCDA << ": " << ec.message() << "\n";
82       return 1;
83     }
84     GCOVBuffer GCDA_GB(GCDA_Buff.take());
85     if (!GF.read(GCDA_GB)) {
86       errs() << "Invalid .gcda File!\n";
87       return 1;
88     }
89   }
90
91   if (DumpGCOV)
92     GF.dump();
93
94   FileInfo FI;
95   GF.collectLineCounts(FI);
96   FI.print(OS, InputGCNO, InputGCDA);
97   return 0;
98 }