xref: /freebsd-src/contrib/llvm-project/llvm/tools/llvm-cov/llvm-cov.cpp (revision 06c3fb2749bda94cb5201f81ffdb8fa6c3161b2e)
10b57cec5SDimitry Andric //===- llvm-cov.cpp - LLVM coverage tool ----------------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // llvm-cov is a command line tools to analyze and report coverage information.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h"
140b57cec5SDimitry Andric #include "llvm/ADT/StringSwitch.h"
150b57cec5SDimitry Andric #include "llvm/Support/CommandLine.h"
160b57cec5SDimitry Andric #include "llvm/Support/InitLLVM.h"
170b57cec5SDimitry Andric #include "llvm/Support/Path.h"
180b57cec5SDimitry Andric #include "llvm/Support/Process.h"
190b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
200b57cec5SDimitry Andric #include <string>
210b57cec5SDimitry Andric 
220b57cec5SDimitry Andric using namespace llvm;
230b57cec5SDimitry Andric 
240b57cec5SDimitry Andric /// The main entry point for the 'show' subcommand.
250b57cec5SDimitry Andric int showMain(int argc, const char *argv[]);
260b57cec5SDimitry Andric 
270b57cec5SDimitry Andric /// The main entry point for the 'report' subcommand.
280b57cec5SDimitry Andric int reportMain(int argc, const char *argv[]);
290b57cec5SDimitry Andric 
300b57cec5SDimitry Andric /// The main entry point for the 'export' subcommand.
310b57cec5SDimitry Andric int exportMain(int argc, const char *argv[]);
320b57cec5SDimitry Andric 
330b57cec5SDimitry Andric /// The main entry point for the 'convert-for-testing' subcommand.
340b57cec5SDimitry Andric int convertForTestingMain(int argc, const char *argv[]);
350b57cec5SDimitry Andric 
360b57cec5SDimitry Andric /// The main entry point for the gcov compatible coverage tool.
370b57cec5SDimitry Andric int gcovMain(int argc, const char *argv[]);
380b57cec5SDimitry Andric 
390b57cec5SDimitry Andric /// Top level help.
helpMain(int argc,const char * argv[])400b57cec5SDimitry Andric static int helpMain(int argc, const char *argv[]) {
410b57cec5SDimitry Andric   errs() << "Usage: llvm-cov {export|gcov|report|show} [OPTION]...\n\n"
420b57cec5SDimitry Andric          << "Shows code coverage information.\n\n"
430b57cec5SDimitry Andric          << "Subcommands:\n"
440b57cec5SDimitry Andric          << "  export: Export instrprof file to structured format.\n"
450b57cec5SDimitry Andric          << "  gcov:   Work with the gcov format.\n"
460b57cec5SDimitry Andric          << "  report: Summarize instrprof style coverage information.\n"
470b57cec5SDimitry Andric          << "  show:   Annotate source files using instrprof style coverage.\n";
480b57cec5SDimitry Andric 
490b57cec5SDimitry Andric   return 0;
500b57cec5SDimitry Andric }
510b57cec5SDimitry Andric 
520b57cec5SDimitry Andric /// Top level version information.
versionMain(int argc,const char * argv[])530b57cec5SDimitry Andric static int versionMain(int argc, const char *argv[]) {
540b57cec5SDimitry Andric   cl::PrintVersionMessage();
550b57cec5SDimitry Andric   return 0;
560b57cec5SDimitry Andric }
570b57cec5SDimitry Andric 
main(int argc,const char ** argv)580b57cec5SDimitry Andric int main(int argc, const char **argv) {
590b57cec5SDimitry Andric   InitLLVM X(argc, argv);
600b57cec5SDimitry Andric 
610b57cec5SDimitry Andric   // If argv[0] is or ends with 'gcov', always be gcov compatible
62*06c3fb27SDimitry Andric   if (sys::path::stem(argv[0]).ends_with_insensitive("gcov"))
630b57cec5SDimitry Andric     return gcovMain(argc, argv);
640b57cec5SDimitry Andric 
650b57cec5SDimitry Andric   // Check if we are invoking a specific tool command.
660b57cec5SDimitry Andric   if (argc > 1) {
670b57cec5SDimitry Andric     typedef int (*MainFunction)(int, const char *[]);
680b57cec5SDimitry Andric     MainFunction Func = StringSwitch<MainFunction>(argv[1])
690b57cec5SDimitry Andric                             .Case("convert-for-testing", convertForTestingMain)
700b57cec5SDimitry Andric                             .Case("export", exportMain)
710b57cec5SDimitry Andric                             .Case("gcov", gcovMain)
720b57cec5SDimitry Andric                             .Case("report", reportMain)
730b57cec5SDimitry Andric                             .Case("show", showMain)
740b57cec5SDimitry Andric                             .Cases("-h", "-help", "--help", helpMain)
750b57cec5SDimitry Andric                             .Cases("-version", "--version", versionMain)
760b57cec5SDimitry Andric                             .Default(nullptr);
770b57cec5SDimitry Andric 
780b57cec5SDimitry Andric     if (Func) {
790b57cec5SDimitry Andric       std::string Invocation = std::string(argv[0]) + " " + argv[1];
800b57cec5SDimitry Andric       argv[1] = Invocation.c_str();
810b57cec5SDimitry Andric       return Func(argc - 1, argv + 1);
820b57cec5SDimitry Andric     }
830b57cec5SDimitry Andric   }
840b57cec5SDimitry Andric 
850b57cec5SDimitry Andric   if (argc > 1) {
860b57cec5SDimitry Andric     if (sys::Process::StandardErrHasColors())
870b57cec5SDimitry Andric       errs().changeColor(raw_ostream::RED);
880b57cec5SDimitry Andric     errs() << "Unrecognized command: " << argv[1] << ".\n\n";
890b57cec5SDimitry Andric     if (sys::Process::StandardErrHasColors())
900b57cec5SDimitry Andric       errs().resetColor();
910b57cec5SDimitry Andric   }
920b57cec5SDimitry Andric   helpMain(argc, argv);
930b57cec5SDimitry Andric   return 1;
940b57cec5SDimitry Andric }
95