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