xref: /freebsd-src/contrib/llvm-project/llvm/tools/llvm-cov/llvm-cov.cpp (revision 0b57cec536236d46e3dba9bd041533462f33dbb7)
1*0b57cec5SDimitry Andric //===- llvm-cov.cpp - LLVM coverage tool ----------------------------------===//
2*0b57cec5SDimitry Andric //
3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*0b57cec5SDimitry Andric //
7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
8*0b57cec5SDimitry Andric //
9*0b57cec5SDimitry Andric // llvm-cov is a command line tools to analyze and report coverage information.
10*0b57cec5SDimitry Andric //
11*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
12*0b57cec5SDimitry Andric 
13*0b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h"
14*0b57cec5SDimitry Andric #include "llvm/ADT/StringSwitch.h"
15*0b57cec5SDimitry Andric #include "llvm/Support/CommandLine.h"
16*0b57cec5SDimitry Andric #include "llvm/Support/InitLLVM.h"
17*0b57cec5SDimitry Andric #include "llvm/Support/ManagedStatic.h"
18*0b57cec5SDimitry Andric #include "llvm/Support/Path.h"
19*0b57cec5SDimitry Andric #include "llvm/Support/Process.h"
20*0b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
21*0b57cec5SDimitry Andric #include <string>
22*0b57cec5SDimitry Andric 
23*0b57cec5SDimitry Andric using namespace llvm;
24*0b57cec5SDimitry Andric 
25*0b57cec5SDimitry Andric /// The main entry point for the 'show' subcommand.
26*0b57cec5SDimitry Andric int showMain(int argc, const char *argv[]);
27*0b57cec5SDimitry Andric 
28*0b57cec5SDimitry Andric /// The main entry point for the 'report' subcommand.
29*0b57cec5SDimitry Andric int reportMain(int argc, const char *argv[]);
30*0b57cec5SDimitry Andric 
31*0b57cec5SDimitry Andric /// The main entry point for the 'export' subcommand.
32*0b57cec5SDimitry Andric int exportMain(int argc, const char *argv[]);
33*0b57cec5SDimitry Andric 
34*0b57cec5SDimitry Andric /// The main entry point for the 'convert-for-testing' subcommand.
35*0b57cec5SDimitry Andric int convertForTestingMain(int argc, const char *argv[]);
36*0b57cec5SDimitry Andric 
37*0b57cec5SDimitry Andric /// The main entry point for the gcov compatible coverage tool.
38*0b57cec5SDimitry Andric int gcovMain(int argc, const char *argv[]);
39*0b57cec5SDimitry Andric 
40*0b57cec5SDimitry Andric /// Top level help.
41*0b57cec5SDimitry Andric static int helpMain(int argc, const char *argv[]) {
42*0b57cec5SDimitry Andric   errs() << "Usage: llvm-cov {export|gcov|report|show} [OPTION]...\n\n"
43*0b57cec5SDimitry Andric          << "Shows code coverage information.\n\n"
44*0b57cec5SDimitry Andric          << "Subcommands:\n"
45*0b57cec5SDimitry Andric          << "  export: Export instrprof file to structured format.\n"
46*0b57cec5SDimitry Andric          << "  gcov:   Work with the gcov format.\n"
47*0b57cec5SDimitry Andric          << "  report: Summarize instrprof style coverage information.\n"
48*0b57cec5SDimitry Andric          << "  show:   Annotate source files using instrprof style coverage.\n";
49*0b57cec5SDimitry Andric 
50*0b57cec5SDimitry Andric   return 0;
51*0b57cec5SDimitry Andric }
52*0b57cec5SDimitry Andric 
53*0b57cec5SDimitry Andric /// Top level version information.
54*0b57cec5SDimitry Andric static int versionMain(int argc, const char *argv[]) {
55*0b57cec5SDimitry Andric   cl::PrintVersionMessage();
56*0b57cec5SDimitry Andric   return 0;
57*0b57cec5SDimitry Andric }
58*0b57cec5SDimitry Andric 
59*0b57cec5SDimitry Andric int main(int argc, const char **argv) {
60*0b57cec5SDimitry Andric   InitLLVM X(argc, argv);
61*0b57cec5SDimitry Andric 
62*0b57cec5SDimitry Andric   // If argv[0] is or ends with 'gcov', always be gcov compatible
63*0b57cec5SDimitry Andric   if (sys::path::stem(argv[0]).endswith_lower("gcov"))
64*0b57cec5SDimitry Andric     return gcovMain(argc, argv);
65*0b57cec5SDimitry Andric 
66*0b57cec5SDimitry Andric   // Check if we are invoking a specific tool command.
67*0b57cec5SDimitry Andric   if (argc > 1) {
68*0b57cec5SDimitry Andric     typedef int (*MainFunction)(int, const char *[]);
69*0b57cec5SDimitry Andric     MainFunction Func = StringSwitch<MainFunction>(argv[1])
70*0b57cec5SDimitry Andric                             .Case("convert-for-testing", convertForTestingMain)
71*0b57cec5SDimitry Andric                             .Case("export", exportMain)
72*0b57cec5SDimitry Andric                             .Case("gcov", gcovMain)
73*0b57cec5SDimitry Andric                             .Case("report", reportMain)
74*0b57cec5SDimitry Andric                             .Case("show", showMain)
75*0b57cec5SDimitry Andric                             .Cases("-h", "-help", "--help", helpMain)
76*0b57cec5SDimitry Andric                             .Cases("-version", "--version", versionMain)
77*0b57cec5SDimitry Andric                             .Default(nullptr);
78*0b57cec5SDimitry Andric 
79*0b57cec5SDimitry Andric     if (Func) {
80*0b57cec5SDimitry Andric       std::string Invocation = std::string(argv[0]) + " " + argv[1];
81*0b57cec5SDimitry Andric       argv[1] = Invocation.c_str();
82*0b57cec5SDimitry Andric       return Func(argc - 1, argv + 1);
83*0b57cec5SDimitry Andric     }
84*0b57cec5SDimitry Andric   }
85*0b57cec5SDimitry Andric 
86*0b57cec5SDimitry Andric   if (argc > 1) {
87*0b57cec5SDimitry Andric     if (sys::Process::StandardErrHasColors())
88*0b57cec5SDimitry Andric       errs().changeColor(raw_ostream::RED);
89*0b57cec5SDimitry Andric     errs() << "Unrecognized command: " << argv[1] << ".\n\n";
90*0b57cec5SDimitry Andric     if (sys::Process::StandardErrHasColors())
91*0b57cec5SDimitry Andric       errs().resetColor();
92*0b57cec5SDimitry Andric   }
93*0b57cec5SDimitry Andric   helpMain(argc, argv);
94*0b57cec5SDimitry Andric   return 1;
95*0b57cec5SDimitry Andric }
96