1//===- 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/StringRef.h"
15#include "llvm/ADT/StringSwitch.h"
16#include "llvm/Support/CommandLine.h"
17#include "llvm/Support/ManagedStatic.h"
18#include "llvm/Support/Path.h"
19#include "llvm/Support/PrettyStackTrace.h"
20#include "llvm/Support/Process.h"
21#include "llvm/Support/Signals.h"
22#include "llvm/Support/raw_ostream.h"
23#include <string>
24
25using namespace llvm;
26
27/// \brief The main entry point for the 'show' subcommand.
28int showMain(int argc, const char *argv[]);
29
30/// \brief The main entry point for the 'report' subcommand.
31int reportMain(int argc, const char *argv[]);
32
33/// \brief The main entry point for the 'convert-for-testing' subcommand.
34int convertForTestingMain(int argc, const char *argv[]);
35
36/// \brief The main entry point for the gcov compatible coverage tool.
37int gcovMain(int argc, const char *argv[]);
38
39/// \brief Top level help.
40static int helpMain(int argc, const char *argv[]) {
41  errs() << "Usage: llvm-cov {gcov|report|show} [OPTION]...\n\n"
42         << "Shows code coverage information.\n\n"
43         << "Subcommands:\n"
44         << "  gcov:   Work with the gcov format.\n"
45         << "  show:   Annotate source files using instrprof style coverage.\n"
46         << "  report: Summarize instrprof style coverage information.\n";
47  return 0;
48}
49
50/// \brief Top level version information.
51static int versionMain(int argc, const char *argv[]) {
52  cl::PrintVersionMessage();
53  return 0;
54}
55
56int main(int argc, const char **argv) {
57  // Print a stack trace if we signal out.
58  sys::PrintStackTraceOnErrorSignal(argv[0]);
59  PrettyStackTraceProgram X(argc, argv);
60  llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
61
62  // If argv[0] is or ends with 'gcov', always be gcov compatible
63  if (sys::path::stem(argv[0]).endswith_lower("gcov"))
64    return gcovMain(argc, argv);
65
66  // Check if we are invoking a specific tool command.
67  if (argc > 1) {
68    typedef int (*MainFunction)(int, const char *[]);
69    MainFunction Func = StringSwitch<MainFunction>(argv[1])
70                            .Case("convert-for-testing", convertForTestingMain)
71                            .Case("gcov", gcovMain)
72                            .Case("report", reportMain)
73                            .Case("show", showMain)
74                            .Cases("-h", "-help", "--help", helpMain)
75                            .Cases("-version", "--version", versionMain)
76                            .Default(nullptr);
77
78    if (Func) {
79      std::string Invocation = std::string(argv[0]) + " " + argv[1];
80      argv[1] = Invocation.c_str();
81      return Func(argc - 1, argv + 1);
82    }
83  }
84
85  if (argc > 1) {
86    if (sys::Process::StandardErrHasColors())
87      errs().changeColor(raw_ostream::RED);
88    errs() << "Unrecognized command: " << argv[1] << ".\n\n";
89    if (sys::Process::StandardErrHasColors())
90      errs().resetColor();
91  }
92  helpMain(argc, argv);
93  return 1;
94}
95