1 //===- JSONCompilationDatabase.h --------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // The JSONCompilationDatabase finds compilation databases supplied as a file 11 // 'compile_commands.json'. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #ifndef LLVM_CLANG_TOOLING_JSONCOMPILATIONDATABASE_H 16 #define LLVM_CLANG_TOOLING_JSONCOMPILATIONDATABASE_H 17 18 #include "clang/Basic/LLVM.h" 19 #include "clang/Tooling/CompilationDatabase.h" 20 #include "clang/Tooling/FileMatchTrie.h" 21 #include "llvm/ADT/ArrayRef.h" 22 #include "llvm/ADT/StringMap.h" 23 #include "llvm/ADT/StringRef.h" 24 #include "llvm/Support/MemoryBuffer.h" 25 #include "llvm/Support/SourceMgr.h" 26 #include "llvm/Support/YAMLParser.h" 27 #include <memory> 28 #include <string> 29 #include <tuple> 30 #include <utility> 31 #include <vector> 32 33 namespace clang { 34 namespace tooling { 35 36 /// A JSON based compilation database. 37 /// 38 /// JSON compilation database files must contain a list of JSON objects which 39 /// provide the command lines in the attributes 'directory', 'command', 40 /// 'arguments' and 'file': 41 /// [ 42 /// { "directory": "<working directory of the compile>", 43 /// "command": "<compile command line>", 44 /// "file": "<path to source file>" 45 /// }, 46 /// { "directory": "<working directory of the compile>", 47 /// "arguments": ["<raw>", "<command>" "<line>" "<parameters>"], 48 /// "file": "<path to source file>" 49 /// }, 50 /// ... 51 /// ] 52 /// Each object entry defines one compile action. The specified file is 53 /// considered to be the main source file for the translation unit. 54 /// 55 /// 'command' is a full command line that will be unescaped. 56 /// 57 /// 'arguments' is a list of command line arguments that will not be unescaped. 58 /// 59 /// JSON compilation databases can for example be generated in CMake projects 60 /// by setting the flag -DCMAKE_EXPORT_COMPILE_COMMANDS. 61 enum class JSONCommandLineSyntax { Windows, Gnu, AutoDetect }; 62 class JSONCompilationDatabase : public CompilationDatabase { 63 public: 64 /// Loads a JSON compilation database from the specified file. 65 /// 66 /// Returns NULL and sets ErrorMessage if the database could not be 67 /// loaded from the given file. 68 static std::unique_ptr<JSONCompilationDatabase> 69 loadFromFile(StringRef FilePath, std::string &ErrorMessage, 70 JSONCommandLineSyntax Syntax); 71 72 /// Loads a JSON compilation database from a data buffer. 73 /// 74 /// Returns NULL and sets ErrorMessage if the database could not be loaded. 75 static std::unique_ptr<JSONCompilationDatabase> 76 loadFromBuffer(StringRef DatabaseString, std::string &ErrorMessage, 77 JSONCommandLineSyntax Syntax); 78 79 /// Returns all compile commands in which the specified file was 80 /// compiled. 81 /// 82 /// FIXME: Currently FilePath must be an absolute path inside the 83 /// source directory which does not have symlinks resolved. 84 std::vector<CompileCommand> 85 getCompileCommands(StringRef FilePath) const override; 86 87 /// Returns the list of all files available in the compilation database. 88 /// 89 /// These are the 'file' entries of the JSON objects. 90 std::vector<std::string> getAllFiles() const override; 91 92 /// Returns all compile commands for all the files in the compilation 93 /// database. 94 std::vector<CompileCommand> getAllCompileCommands() const override; 95 96 private: 97 /// Constructs a JSON compilation database on a memory buffer. JSONCompilationDatabase(std::unique_ptr<llvm::MemoryBuffer> Database,JSONCommandLineSyntax Syntax)98 JSONCompilationDatabase(std::unique_ptr<llvm::MemoryBuffer> Database, 99 JSONCommandLineSyntax Syntax) 100 : Database(std::move(Database)), Syntax(Syntax), 101 YAMLStream(this->Database->getBuffer(), SM) {} 102 103 /// Parses the database file and creates the index. 104 /// 105 /// Returns whether parsing succeeded. Sets ErrorMessage if parsing 106 /// failed. 107 bool parse(std::string &ErrorMessage); 108 109 // Tuple (directory, filename, commandline, output) where 'commandline' 110 // points to the corresponding scalar nodes in the YAML stream. 111 // If the command line contains a single argument, it is a shell-escaped 112 // command line. 113 // Otherwise, each entry in the command line vector is a literal 114 // argument to the compiler. 115 // The output field may be a nullptr. 116 using CompileCommandRef = 117 std::tuple<llvm::yaml::ScalarNode *, llvm::yaml::ScalarNode *, 118 std::vector<llvm::yaml::ScalarNode *>, 119 llvm::yaml::ScalarNode *>; 120 121 /// Converts the given array of CompileCommandRefs to CompileCommands. 122 void getCommands(ArrayRef<CompileCommandRef> CommandsRef, 123 std::vector<CompileCommand> &Commands) const; 124 125 // Maps file paths to the compile command lines for that file. 126 llvm::StringMap<std::vector<CompileCommandRef>> IndexByFile; 127 128 /// All the compile commands in the order that they were provided in the 129 /// JSON stream. 130 std::vector<CompileCommandRef> AllCommands; 131 132 FileMatchTrie MatchTrie; 133 134 std::unique_ptr<llvm::MemoryBuffer> Database; 135 JSONCommandLineSyntax Syntax; 136 llvm::SourceMgr SM; 137 llvm::yaml::Stream YAMLStream; 138 }; 139 140 } // namespace tooling 141 } // namespace clang 142 143 #endif // LLVM_CLANG_TOOLING_JSONCOMPILATIONDATABASE_H 144