Index: lib/Tooling/JSONCompilationDatabase.cpp =================================================================== --- lib/Tooling/JSONCompilationDatabase.cpp +++ lib/Tooling/JSONCompilationDatabase.cpp @@ -20,6 +20,7 @@ #include "llvm/Support/CommandLine.h" #include "llvm/Support/Path.h" #include "llvm/Support/StringSaver.h" +#include #include namespace clang { @@ -251,20 +252,64 @@ return Arguments; } +static std::vector +deduplicateCommandLine(const std::vector &Nodes) { + struct FlagFilter { + private: + int State; + const std::map Flags = { + {"-MD", 0}, {"-MMD", 0}, {"-MG", 0}, {"-MP", 0}, {"-MF", 1}, {"-MT", 1}, {"-MQ", 1} + }; + public: + FlagFilter() : State(0) { } + + bool operator()(const std::string &Current) { + if (State != 0) { + --State; + return false; + } + const auto Check = Flags.find(Current); + if (Check != Flags.end()) { + State = Check->second; + return false; + } + return true; + } + }; + + std::vector Result; + std::copy_if(Nodes.begin(), Nodes.end(), std::back_inserter(Result), FlagFilter()); + return Result; +} + +struct CompareCompileCommand { + bool operator()(const CompileCommand &Lhs, const CompileCommand &Rhs) const { + return (Lhs.Directory == Rhs.Directory) && + (Lhs.Filename == Rhs.Filename) && + (Lhs.CommandLine == Rhs.CommandLine) && + (Lhs.Output == Rhs.Output); + } +}; + void JSONCompilationDatabase::getCommands( ArrayRef CommandsRef, std::vector &Commands) const { + // To filter out duplicate elements put the result first into a set. + std::set Results; 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( + Results.emplace( std::get<0>(CommandsRef[I])->getValue(DirectoryStorage), std::get<1>(CommandsRef[I])->getValue(FilenameStorage), - nodeToCommandLine(Syntax, std::get<2>(CommandsRef[I])), + deduplicateCommandLine( + nodeToCommandLine(Syntax, std::get<2>(CommandsRef[I]))), Output ? Output->getValue(OutputStorage) : ""); } + // Copy the unique elements into the real return value. + std::copy(Results.begin(), Results.end(), std::back_inserter(Commands)); } bool JSONCompilationDatabase::parse(std::string &ErrorMessage) {