109467b48Spatrick //===- llvm-cov.cpp - LLVM coverage tool ----------------------------------===//
209467b48Spatrick //
309467b48Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
409467b48Spatrick // See https://llvm.org/LICENSE.txt for license information.
509467b48Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
609467b48Spatrick //
709467b48Spatrick //===----------------------------------------------------------------------===//
809467b48Spatrick //
909467b48Spatrick // llvm-cov is a command line tools to analyze and report coverage information.
1009467b48Spatrick //
1109467b48Spatrick //===----------------------------------------------------------------------===//
1209467b48Spatrick 
1309467b48Spatrick #include "llvm/ADT/StringRef.h"
1409467b48Spatrick #include "llvm/ADT/StringSwitch.h"
1509467b48Spatrick #include "llvm/Support/CommandLine.h"
1609467b48Spatrick #include "llvm/Support/InitLLVM.h"
1709467b48Spatrick #include "llvm/Support/Path.h"
1809467b48Spatrick #include "llvm/Support/Process.h"
1909467b48Spatrick #include "llvm/Support/raw_ostream.h"
2009467b48Spatrick #include <string>
2109467b48Spatrick 
2209467b48Spatrick using namespace llvm;
2309467b48Spatrick 
2409467b48Spatrick /// The main entry point for the 'show' subcommand.
2509467b48Spatrick int showMain(int argc, const char *argv[]);
2609467b48Spatrick 
2709467b48Spatrick /// The main entry point for the 'report' subcommand.
2809467b48Spatrick int reportMain(int argc, const char *argv[]);
2909467b48Spatrick 
3009467b48Spatrick /// The main entry point for the 'export' subcommand.
3109467b48Spatrick int exportMain(int argc, const char *argv[]);
3209467b48Spatrick 
3309467b48Spatrick /// The main entry point for the 'convert-for-testing' subcommand.
3409467b48Spatrick int convertForTestingMain(int argc, const char *argv[]);
3509467b48Spatrick 
3609467b48Spatrick /// The main entry point for the gcov compatible coverage tool.
3709467b48Spatrick int gcovMain(int argc, const char *argv[]);
3809467b48Spatrick 
3909467b48Spatrick /// Top level help.
helpMain(int argc,const char * argv[])4009467b48Spatrick static int helpMain(int argc, const char *argv[]) {
4109467b48Spatrick   errs() << "Usage: llvm-cov {export|gcov|report|show} [OPTION]...\n\n"
4209467b48Spatrick          << "Shows code coverage information.\n\n"
4309467b48Spatrick          << "Subcommands:\n"
4409467b48Spatrick          << "  export: Export instrprof file to structured format.\n"
4509467b48Spatrick          << "  gcov:   Work with the gcov format.\n"
4609467b48Spatrick          << "  report: Summarize instrprof style coverage information.\n"
4709467b48Spatrick          << "  show:   Annotate source files using instrprof style coverage.\n";
4809467b48Spatrick 
4909467b48Spatrick   return 0;
5009467b48Spatrick }
5109467b48Spatrick 
5209467b48Spatrick /// Top level version information.
versionMain(int argc,const char * argv[])5309467b48Spatrick static int versionMain(int argc, const char *argv[]) {
5409467b48Spatrick   cl::PrintVersionMessage();
5509467b48Spatrick   return 0;
5609467b48Spatrick }
5709467b48Spatrick 
main(int argc,const char ** argv)5809467b48Spatrick int main(int argc, const char **argv) {
5909467b48Spatrick   InitLLVM X(argc, argv);
6009467b48Spatrick 
6109467b48Spatrick   // If argv[0] is or ends with 'gcov', always be gcov compatible
62*73471bf0Spatrick   if (sys::path::stem(argv[0]).endswith_insensitive("gcov"))
6309467b48Spatrick     return gcovMain(argc, argv);
6409467b48Spatrick 
6509467b48Spatrick   // Check if we are invoking a specific tool command.
6609467b48Spatrick   if (argc > 1) {
6709467b48Spatrick     typedef int (*MainFunction)(int, const char *[]);
6809467b48Spatrick     MainFunction Func = StringSwitch<MainFunction>(argv[1])
6909467b48Spatrick                             .Case("convert-for-testing", convertForTestingMain)
7009467b48Spatrick                             .Case("export", exportMain)
7109467b48Spatrick                             .Case("gcov", gcovMain)
7209467b48Spatrick                             .Case("report", reportMain)
7309467b48Spatrick                             .Case("show", showMain)
7409467b48Spatrick                             .Cases("-h", "-help", "--help", helpMain)
7509467b48Spatrick                             .Cases("-version", "--version", versionMain)
7609467b48Spatrick                             .Default(nullptr);
7709467b48Spatrick 
7809467b48Spatrick     if (Func) {
7909467b48Spatrick       std::string Invocation = std::string(argv[0]) + " " + argv[1];
8009467b48Spatrick       argv[1] = Invocation.c_str();
8109467b48Spatrick       return Func(argc - 1, argv + 1);
8209467b48Spatrick     }
8309467b48Spatrick   }
8409467b48Spatrick 
8509467b48Spatrick   if (argc > 1) {
8609467b48Spatrick     if (sys::Process::StandardErrHasColors())
8709467b48Spatrick       errs().changeColor(raw_ostream::RED);
8809467b48Spatrick     errs() << "Unrecognized command: " << argv[1] << ".\n\n";
8909467b48Spatrick     if (sys::Process::StandardErrHasColors())
9009467b48Spatrick       errs().resetColor();
9109467b48Spatrick   }
9209467b48Spatrick   helpMain(argc, argv);
9309467b48Spatrick   return 1;
9409467b48Spatrick }
95