Home | History | Annotate | Download | only in Tooling
      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