From 3ecd8c0aabd30107d4fff8fdd9547f77b3b66d1a Mon Sep 17 00:00:00 2001 From: Manuel Klimek Date: Tue, 8 Sep 2015 15:14:06 +0000 Subject: Fix performance regression when running clang tools. Brings tool start time for a large synthetic test case down from (on my machine) 4 seconds to 0.5 seconds. llvm-svn: 247018 --- clang/lib/Tooling/JSONCompilationDatabase.cpp | 52 +++++++++++++++------------ 1 file changed, 30 insertions(+), 22 deletions(-) (limited to 'clang/lib/Tooling/JSONCompilationDatabase.cpp') diff --git a/clang/lib/Tooling/JSONCompilationDatabase.cpp b/clang/lib/Tooling/JSONCompilationDatabase.cpp index 421651c..3ac6f69 100644 --- a/clang/lib/Tooling/JSONCompilationDatabase.cpp +++ b/clang/lib/Tooling/JSONCompilationDatabase.cpp @@ -214,15 +214,26 @@ JSONCompilationDatabase::getAllCompileCommands() const { return Commands; } +static std::vector +nodeToCommandLine(const std::vector &Nodes) { + SmallString<1024> Storage; + if (Nodes.size() == 1) { + return unescapeCommandLine(Nodes[0]->getValue(Storage)); + } + std::vector Arguments; + for (auto *Node : Nodes) { + Arguments.push_back(Node->getValue(Storage)); + } + return Arguments; +} + void JSONCompilationDatabase::getCommands( - ArrayRef CommandsRef, - std::vector &Commands) const { + ArrayRef CommandsRef, + std::vector &Commands) const { for (int I = 0, E = CommandsRef.size(); I != E; ++I) { SmallString<8> DirectoryStorage; - SmallString<1024> CommandStorage; - Commands.emplace_back( - CommandsRef[I].first->getValue(DirectoryStorage), - CommandsRef[I].second); + Commands.emplace_back(CommandsRef[I].first->getValue(DirectoryStorage), + nodeToCommandLine(CommandsRef[I].second)); } } @@ -249,11 +260,8 @@ bool JSONCompilationDatabase::parse(std::string &ErrorMessage) { return false; } llvm::yaml::ScalarNode *Directory = nullptr; - std::vector Arguments; - std::vector Command; + llvm::Optional> Command; llvm::yaml::ScalarNode *File = nullptr; - bool ArgumentsFound = false; - bool CommandFound = false; for (auto& NextKeyValue : *Object) { llvm::yaml::ScalarNode *KeyString = dyn_cast(NextKeyValue.getKey()); @@ -282,18 +290,18 @@ bool JSONCompilationDatabase::parse(std::string &ErrorMessage) { if (KeyValue == "directory") { Directory = ValueString; } else if (KeyValue == "arguments") { - for (auto& NextArgument : *SequenceString) { - SmallString<128> CommandStorage; - auto ValueString = dyn_cast(&NextArgument); - - Arguments.push_back(ValueString->getValue(CommandStorage)); + Command = std::vector(); + for (auto &Argument : *SequenceString) { + auto Scalar = dyn_cast(&Argument); + if (!Scalar) { + ErrorMessage = "Only strings are allowed in 'arguments'."; + return false; + } + Command->push_back(Scalar); } - ArgumentsFound = true; } else if (KeyValue == "command") { - SmallString<1024> CommandStorage; - // FIXME: Escape correctly: - Command = unescapeCommandLine(ValueString->getValue(CommandStorage)); - CommandFound = true; + if (!Command) + Command = std::vector(1, ValueString); } else if (KeyValue == "file") { File = ValueString; } else { @@ -306,7 +314,7 @@ bool JSONCompilationDatabase::parse(std::string &ErrorMessage) { ErrorMessage = "Missing key: \"file\"."; return false; } - if (!ArgumentsFound && !CommandFound) { + if (!Command) { ErrorMessage = "Missing key: \"command\" or \"arguments\"."; return false; } @@ -327,7 +335,7 @@ bool JSONCompilationDatabase::parse(std::string &ErrorMessage) { llvm::sys::path::native(FileName, NativeFilePath); } IndexByFile[NativeFilePath].push_back( - CompileCommandRef(Directory, ArgumentsFound ? Arguments : Command)); + CompileCommandRef(Directory, *Command)); MatchTrie.insert(NativeFilePath); } return true; -- cgit v1.1