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