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