diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Tooling/JSONCompilationDatabase.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/Tooling/JSONCompilationDatabase.cpp | 60 |
1 files changed, 47 insertions, 13 deletions
diff --git a/contrib/llvm/tools/clang/lib/Tooling/JSONCompilationDatabase.cpp b/contrib/llvm/tools/clang/lib/Tooling/JSONCompilationDatabase.cpp index 299fbdc..738e610 100644 --- a/contrib/llvm/tools/clang/lib/Tooling/JSONCompilationDatabase.cpp +++ b/contrib/llvm/tools/clang/lib/Tooling/JSONCompilationDatabase.cpp @@ -16,7 +16,10 @@ #include "clang/Tooling/CompilationDatabasePluginRegistry.h" #include "clang/Tooling/Tooling.h" #include "llvm/ADT/SmallString.h" +#include "llvm/Support/Allocator.h" +#include "llvm/Support/CommandLine.h" #include "llvm/Support/Path.h" +#include "llvm/Support/StringSaver.h" #include <system_error> namespace clang { @@ -111,8 +114,29 @@ class CommandLineArgumentParser { std::vector<std::string> CommandLine; }; -std::vector<std::string> unescapeCommandLine( - StringRef EscapedCommandLine) { +std::vector<std::string> unescapeCommandLine(JSONCommandLineSyntax Syntax, + StringRef EscapedCommandLine) { + if (Syntax == JSONCommandLineSyntax::AutoDetect) { + Syntax = JSONCommandLineSyntax::Gnu; + llvm::Triple Triple(llvm::sys::getProcessTriple()); + if (Triple.getOS() == llvm::Triple::OSType::Win32) { + // Assume Windows command line parsing on Win32 unless the triple + // explicitly tells us otherwise. + if (!Triple.hasEnvironment() || + Triple.getEnvironment() == llvm::Triple::EnvironmentType::MSVC) + Syntax = JSONCommandLineSyntax::Windows; + } + } + + if (Syntax == JSONCommandLineSyntax::Windows) { + llvm::BumpPtrAllocator Alloc; + llvm::StringSaver Saver(Alloc); + llvm::SmallVector<const char *, 64> T; + llvm::cl::TokenizeWindowsCommandLine(EscapedCommandLine, Saver, T); + std::vector<std::string> Result(T.begin(), T.end()); + return Result; + } + assert(Syntax == JSONCommandLineSyntax::Gnu); CommandLineArgumentParser parser(EscapedCommandLine); return parser.parse(); } @@ -123,7 +147,8 @@ class JSONCompilationDatabasePlugin : public CompilationDatabasePlugin { SmallString<1024> JSONDatabasePath(Directory); llvm::sys::path::append(JSONDatabasePath, "compile_commands.json"); std::unique_ptr<CompilationDatabase> Database( - JSONCompilationDatabase::loadFromFile(JSONDatabasePath, ErrorMessage)); + JSONCompilationDatabase::loadFromFile( + JSONDatabasePath, ErrorMessage, JSONCommandLineSyntax::AutoDetect)); if (!Database) return nullptr; return Database; @@ -143,7 +168,8 @@ volatile int JSONAnchorSource = 0; std::unique_ptr<JSONCompilationDatabase> JSONCompilationDatabase::loadFromFile(StringRef FilePath, - std::string &ErrorMessage) { + std::string &ErrorMessage, + JSONCommandLineSyntax Syntax) { llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> DatabaseBuffer = llvm::MemoryBuffer::getFile(FilePath); if (std::error_code Result = DatabaseBuffer.getError()) { @@ -151,7 +177,7 @@ JSONCompilationDatabase::loadFromFile(StringRef FilePath, return nullptr; } std::unique_ptr<JSONCompilationDatabase> Database( - new JSONCompilationDatabase(std::move(*DatabaseBuffer))); + new JSONCompilationDatabase(std::move(*DatabaseBuffer), Syntax)); if (!Database->parse(ErrorMessage)) return nullptr; return Database; @@ -159,11 +185,12 @@ JSONCompilationDatabase::loadFromFile(StringRef FilePath, std::unique_ptr<JSONCompilationDatabase> JSONCompilationDatabase::loadFromBuffer(StringRef DatabaseString, - std::string &ErrorMessage) { + std::string &ErrorMessage, + JSONCommandLineSyntax Syntax) { std::unique_ptr<llvm::MemoryBuffer> DatabaseBuffer( llvm::MemoryBuffer::getMemBuffer(DatabaseString)); std::unique_ptr<JSONCompilationDatabase> Database( - new JSONCompilationDatabase(std::move(DatabaseBuffer))); + new JSONCompilationDatabase(std::move(DatabaseBuffer), Syntax)); if (!Database->parse(ErrorMessage)) return nullptr; return Database; @@ -211,10 +238,11 @@ JSONCompilationDatabase::getAllCompileCommands() const { } static std::vector<std::string> -nodeToCommandLine(const std::vector<llvm::yaml::ScalarNode *> &Nodes) { +nodeToCommandLine(JSONCommandLineSyntax Syntax, + const std::vector<llvm::yaml::ScalarNode *> &Nodes) { SmallString<1024> Storage; if (Nodes.size() == 1) { - return unescapeCommandLine(Nodes[0]->getValue(Storage)); + return unescapeCommandLine(Syntax, Nodes[0]->getValue(Storage)); } std::vector<std::string> Arguments; for (auto *Node : Nodes) { @@ -229,10 +257,13 @@ void JSONCompilationDatabase::getCommands( for (int I = 0, E = CommandsRef.size(); I != E; ++I) { SmallString<8> DirectoryStorage; SmallString<32> FilenameStorage; + SmallString<32> OutputStorage; + auto Output = std::get<3>(CommandsRef[I]); Commands.emplace_back( - std::get<0>(CommandsRef[I])->getValue(DirectoryStorage), - std::get<1>(CommandsRef[I])->getValue(FilenameStorage), - nodeToCommandLine(std::get<2>(CommandsRef[I]))); + std::get<0>(CommandsRef[I])->getValue(DirectoryStorage), + std::get<1>(CommandsRef[I])->getValue(FilenameStorage), + nodeToCommandLine(Syntax, std::get<2>(CommandsRef[I])), + Output ? Output->getValue(OutputStorage) : ""); } } @@ -261,6 +292,7 @@ bool JSONCompilationDatabase::parse(std::string &ErrorMessage) { llvm::yaml::ScalarNode *Directory = nullptr; llvm::Optional<std::vector<llvm::yaml::ScalarNode *>> Command; llvm::yaml::ScalarNode *File = nullptr; + llvm::yaml::ScalarNode *Output = nullptr; for (auto& NextKeyValue : *Object) { llvm::yaml::ScalarNode *KeyString = dyn_cast<llvm::yaml::ScalarNode>(NextKeyValue.getKey()); @@ -303,6 +335,8 @@ bool JSONCompilationDatabase::parse(std::string &ErrorMessage) { Command = std::vector<llvm::yaml::ScalarNode *>(1, ValueString); } else if (KeyValue == "file") { File = ValueString; + } else if (KeyValue == "output") { + Output = ValueString; } else { ErrorMessage = ("Unknown key: \"" + KeyString->getRawValue() + "\"").str(); @@ -333,7 +367,7 @@ bool JSONCompilationDatabase::parse(std::string &ErrorMessage) { } else { llvm::sys::path::native(FileName, NativeFilePath); } - auto Cmd = CompileCommandRef(Directory, File, *Command); + auto Cmd = CompileCommandRef(Directory, File, *Command, Output); IndexByFile[NativeFilePath].push_back(Cmd); AllCommands.push_back(Cmd); MatchTrie.insert(NativeFilePath); |