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