1238104Sdes//===- JSONCompilationDatabase.h --------------------------------*- C++ -*-===// 2238104Sdes// 3238104Sdes// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4238104Sdes// See https://llvm.org/LICENSE.txt for license information. 5238104Sdes// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6238104Sdes// 7238104Sdes//===----------------------------------------------------------------------===// 8238104Sdes// 9238104Sdes// The JSONCompilationDatabase finds compilation databases supplied as a file 10238104Sdes// 'compile_commands.json'. 11238104Sdes// 12238104Sdes//===----------------------------------------------------------------------===// 13238104Sdes 14238104Sdes#ifndef LLVM_CLANG_TOOLING_JSONCOMPILATIONDATABASE_H 15238104Sdes#define LLVM_CLANG_TOOLING_JSONCOMPILATIONDATABASE_H 16238104Sdes 17238104Sdes#include "clang/Basic/LLVM.h" 18238104Sdes#include "clang/Tooling/CompilationDatabase.h" 19238104Sdes#include "clang/Tooling/FileMatchTrie.h" 20238104Sdes#include "llvm/ADT/ArrayRef.h" 21238104Sdes#include "llvm/ADT/StringMap.h" 22238104Sdes#include "llvm/ADT/StringRef.h" 23238104Sdes#include "llvm/Support/MemoryBuffer.h" 24238104Sdes#include "llvm/Support/SourceMgr.h" 25238104Sdes#include "llvm/Support/YAMLParser.h" 26238104Sdes#include <memory> 27238104Sdes#include <string> 28238104Sdes#include <tuple> 29238104Sdes#include <utility> 30238104Sdes#include <vector> 31238104Sdes 32238104Sdesnamespace clang { 33238104Sdesnamespace tooling { 34238104Sdes 35238104Sdes/// A JSON based compilation database. 36238104Sdes/// 37238104Sdes/// JSON compilation database files must contain a list of JSON objects which 38238104Sdes/// provide the command lines in the attributes 'directory', 'command', 39238104Sdes/// 'arguments' and 'file': 40238104Sdes/// [ 41238104Sdes/// { "directory": "<working directory of the compile>", 42238104Sdes/// "command": "<compile command line>", 43238104Sdes/// "file": "<path to source file>" 44238104Sdes/// }, 45238104Sdes/// { "directory": "<working directory of the compile>", 46238104Sdes/// "arguments": ["<raw>", "<command>" "<line>" "<parameters>"], 47238104Sdes/// "file": "<path to source file>" 48238104Sdes/// }, 49238104Sdes/// ... 50238104Sdes/// ] 51238104Sdes/// Each object entry defines one compile action. The specified file is 52238104Sdes/// considered to be the main source file for the translation unit. 53238104Sdes/// 54238104Sdes/// 'command' is a full command line that will be unescaped. 55238104Sdes/// 56238104Sdes/// 'arguments' is a list of command line arguments that will not be unescaped. 57238104Sdes/// 58238104Sdes/// JSON compilation databases can for example be generated in CMake projects 59238104Sdes/// by setting the flag -DCMAKE_EXPORT_COMPILE_COMMANDS. 60238104Sdesenum class JSONCommandLineSyntax { Windows, Gnu, AutoDetect }; 61238104Sdesclass JSONCompilationDatabase : public CompilationDatabase { 62238104Sdespublic: 63238104Sdes /// Loads a JSON compilation database from the specified file. 64238104Sdes /// 65238104Sdes /// Returns NULL and sets ErrorMessage if the database could not be 66238104Sdes /// loaded from the given file. 67238104Sdes static std::unique_ptr<JSONCompilationDatabase> 68238104Sdes loadFromFile(StringRef FilePath, std::string &ErrorMessage, 69238104Sdes JSONCommandLineSyntax Syntax); 70238104Sdes 71238104Sdes /// Loads a JSON compilation database from a data buffer. 72238104Sdes /// 73238104Sdes /// Returns NULL and sets ErrorMessage if the database could not be loaded. 74238104Sdes static std::unique_ptr<JSONCompilationDatabase> 75238104Sdes loadFromBuffer(StringRef DatabaseString, std::string &ErrorMessage, 76238104Sdes JSONCommandLineSyntax Syntax); 77238104Sdes 78238104Sdes /// Returns all compile commands in which the specified file was 79238104Sdes /// compiled. 80238104Sdes /// 81238104Sdes /// FIXME: Currently FilePath must be an absolute path inside the 82238104Sdes /// source directory which does not have symlinks resolved. 83238104Sdes std::vector<CompileCommand> 84238104Sdes getCompileCommands(StringRef FilePath) const override; 85238104Sdes 86238104Sdes /// Returns the list of all files available in the compilation database. 87238104Sdes /// 88238104Sdes /// These are the 'file' entries of the JSON objects. 89238104Sdes std::vector<std::string> getAllFiles() const override; 90238104Sdes 91238104Sdes /// Returns all compile commands for all the files in the compilation 92238104Sdes /// database. 93238104Sdes std::vector<CompileCommand> getAllCompileCommands() const override; 94238104Sdes 95238104Sdesprivate: 96238104Sdes /// Constructs a JSON compilation database on a memory buffer. 97238104Sdes JSONCompilationDatabase(std::unique_ptr<llvm::MemoryBuffer> Database, 98238104Sdes JSONCommandLineSyntax Syntax) 99238104Sdes : Database(std::move(Database)), Syntax(Syntax), 100238104Sdes YAMLStream(this->Database->getBuffer(), SM) {} 101238104Sdes 102238104Sdes /// Parses the database file and creates the index. 103238104Sdes /// 104238104Sdes /// Returns whether parsing succeeded. Sets ErrorMessage if parsing 105238104Sdes /// failed. 106238104Sdes bool parse(std::string &ErrorMessage); 107238104Sdes 108238104Sdes // Tuple (directory, filename, commandline, output) where 'commandline' 109238104Sdes // points to the corresponding scalar nodes in the YAML stream. 110238104Sdes // If the command line contains a single argument, it is a shell-escaped 111238104Sdes // command line. 112238104Sdes // Otherwise, each entry in the command line vector is a literal 113238104Sdes // argument to the compiler. 114238104Sdes // The output field may be a nullptr. 115238104Sdes using CompileCommandRef = 116238104Sdes std::tuple<llvm::yaml::ScalarNode *, llvm::yaml::ScalarNode *, 117238104Sdes std::vector<llvm::yaml::ScalarNode *>, 118238104Sdes llvm::yaml::ScalarNode *>; 119238104Sdes 120238104Sdes /// Converts the given array of CompileCommandRefs to CompileCommands. 121238104Sdes void getCommands(ArrayRef<CompileCommandRef> CommandsRef, 122238104Sdes std::vector<CompileCommand> &Commands) const; 123238104Sdes 124238104Sdes // Maps file paths to the compile command lines for that file. 125238104Sdes llvm::StringMap<std::vector<CompileCommandRef>> IndexByFile; 126238104Sdes 127238104Sdes /// All the compile commands in the order that they were provided in the 128238104Sdes /// JSON stream. 129238104Sdes std::vector<CompileCommandRef> AllCommands; 130238104Sdes 131238104Sdes FileMatchTrie MatchTrie; 132238104Sdes 133238104Sdes std::unique_ptr<llvm::MemoryBuffer> Database; 134238104Sdes JSONCommandLineSyntax Syntax; 135238104Sdes llvm::SourceMgr SM; 136238104Sdes llvm::yaml::Stream YAMLStream; 137238104Sdes}; 138238104Sdes 139238104Sdes} // namespace tooling 140238104Sdes} // namespace clang 141238104Sdes 142238104Sdes#endif // LLVM_CLANG_TOOLING_JSONCOMPILATIONDATABASE_H 143238104Sdes