clang API Documentation
00001 //===--- CommonOptionsParser.cpp - common options for clang tools ---------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file implements the CommonOptionsParser class used to parse common 00011 // command-line options for clang tools, so that they can be run as separate 00012 // command-line applications with a consistent common interface for handling 00013 // compilation database and input files. 00014 // 00015 // It provides a common subset of command-line options, common algorithm 00016 // for locating a compilation database and source files, and help messages 00017 // for the basic command-line interface. 00018 // 00019 // It creates a CompilationDatabase and reads common command-line options. 00020 // 00021 // This class uses the Clang Tooling infrastructure, see 00022 // http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html 00023 // for details on setting it up with LLVM source tree. 00024 // 00025 //===----------------------------------------------------------------------===// 00026 00027 #include "llvm/Support/CommandLine.h" 00028 #include "clang/Tooling/ArgumentsAdjusters.h" 00029 #include "clang/Tooling/CommonOptionsParser.h" 00030 #include "clang/Tooling/Tooling.h" 00031 00032 using namespace clang::tooling; 00033 using namespace llvm; 00034 00035 const char *const CommonOptionsParser::HelpMessage = 00036 "\n" 00037 "-p <build-path> is used to read a compile command database.\n" 00038 "\n" 00039 "\tFor example, it can be a CMake build directory in which a file named\n" 00040 "\tcompile_commands.json exists (use -DCMAKE_EXPORT_COMPILE_COMMANDS=ON\n" 00041 "\tCMake option to get this output). When no build path is specified,\n" 00042 "\ta search for compile_commands.json will be attempted through all\n" 00043 "\tparent paths of the first input file . See:\n" 00044 "\thttp://clang.llvm.org/docs/HowToSetupToolingForLLVM.html for an\n" 00045 "\texample of setting up Clang Tooling on a source tree.\n" 00046 "\n" 00047 "<source0> ... specify the paths of source files. These paths are\n" 00048 "\tlooked up in the compile command database. If the path of a file is\n" 00049 "\tabsolute, it needs to point into CMake's source tree. If the path is\n" 00050 "\trelative, the current working directory needs to be in the CMake\n" 00051 "\tsource tree and the file must be in a subdirectory of the current\n" 00052 "\tworking directory. \"./\" prefixes in the relative files will be\n" 00053 "\tautomatically removed, but the rest of a relative path must be a\n" 00054 "\tsuffix of a path in the compile command database.\n" 00055 "\n"; 00056 00057 class ArgumentsAdjustingCompilations : public CompilationDatabase { 00058 public: 00059 ArgumentsAdjustingCompilations( 00060 std::unique_ptr<CompilationDatabase> Compilations) 00061 : Compilations(std::move(Compilations)) {} 00062 00063 void appendArgumentsAdjuster(std::unique_ptr<ArgumentsAdjuster> Adjuster) { 00064 Adjusters.push_back(std::move(Adjuster)); 00065 } 00066 00067 std::vector<CompileCommand> 00068 getCompileCommands(StringRef FilePath) const override { 00069 return adjustCommands(Compilations->getCompileCommands(FilePath)); 00070 } 00071 00072 std::vector<std::string> getAllFiles() const override { 00073 return Compilations->getAllFiles(); 00074 } 00075 00076 std::vector<CompileCommand> getAllCompileCommands() const override { 00077 return adjustCommands(Compilations->getAllCompileCommands()); 00078 } 00079 00080 private: 00081 std::unique_ptr<CompilationDatabase> Compilations; 00082 std::vector<std::unique_ptr<ArgumentsAdjuster>> Adjusters; 00083 00084 std::vector<CompileCommand> 00085 adjustCommands(std::vector<CompileCommand> Commands) const { 00086 for (CompileCommand &Command : Commands) 00087 for (const auto &Adjuster : Adjusters) 00088 Command.CommandLine = Adjuster->Adjust(Command.CommandLine); 00089 return Commands; 00090 } 00091 }; 00092 00093 CommonOptionsParser::CommonOptionsParser(int &argc, const char **argv, 00094 cl::OptionCategory &Category, 00095 const char *Overview) { 00096 static cl::opt<bool> Help("h", cl::desc("Alias for -help"), cl::Hidden); 00097 00098 static cl::opt<std::string> BuildPath("p", cl::desc("Build path"), 00099 cl::Optional, cl::cat(Category)); 00100 00101 static cl::list<std::string> SourcePaths( 00102 cl::Positional, cl::desc("<source0> [... <sourceN>]"), cl::OneOrMore, 00103 cl::cat(Category)); 00104 00105 static cl::list<std::string> ArgsAfter( 00106 "extra-arg", 00107 cl::desc("Additional argument to append to the compiler command line"), 00108 cl::cat(Category)); 00109 00110 static cl::list<std::string> ArgsBefore( 00111 "extra-arg-before", 00112 cl::desc("Additional argument to prepend to the compiler command line"), 00113 cl::cat(Category)); 00114 00115 // Hide unrelated options. 00116 StringMap<cl::Option*> Options; 00117 cl::getRegisteredOptions(Options); 00118 for (StringMap<cl::Option *>::iterator I = Options.begin(), E = Options.end(); 00119 I != E; ++I) { 00120 if (I->second->Category != &Category && I->first() != "help" && 00121 I->first() != "version") 00122 I->second->setHiddenFlag(cl::ReallyHidden); 00123 } 00124 00125 Compilations.reset(FixedCompilationDatabase::loadFromCommandLine(argc, 00126 argv)); 00127 cl::ParseCommandLineOptions(argc, argv, Overview); 00128 SourcePathList = SourcePaths; 00129 if (!Compilations) { 00130 std::string ErrorMessage; 00131 if (!BuildPath.empty()) { 00132 Compilations = 00133 CompilationDatabase::autoDetectFromDirectory(BuildPath, ErrorMessage); 00134 } else { 00135 Compilations = CompilationDatabase::autoDetectFromSource(SourcePaths[0], 00136 ErrorMessage); 00137 } 00138 if (!Compilations) 00139 llvm::report_fatal_error(ErrorMessage); 00140 } 00141 auto AdjustingCompilations = 00142 llvm::make_unique<ArgumentsAdjustingCompilations>( 00143 std::move(Compilations)); 00144 AdjustingCompilations->appendArgumentsAdjuster( 00145 llvm::make_unique<InsertArgumentAdjuster>(ArgsBefore, 00146 InsertArgumentAdjuster::BEGIN)); 00147 AdjustingCompilations->appendArgumentsAdjuster( 00148 llvm::make_unique<InsertArgumentAdjuster>(ArgsAfter, 00149 InsertArgumentAdjuster::END)); 00150 Compilations = std::move(AdjustingCompilations); 00151 }