diff --git a/clang/include/clang/Tooling/CompilationDatabasePluginRegistry.h b/clang/include/clang/Tooling/CompilationDatabasePluginRegistry.h --- a/clang/include/clang/Tooling/CompilationDatabasePluginRegistry.h +++ b/clang/include/clang/Tooling/CompilationDatabasePluginRegistry.h @@ -34,6 +34,10 @@ /// \see CompilationDatabase::loadFromDirectory(). virtual std::unique_ptr loadFromDirectory(StringRef Directory, std::string &ErrorMessage) = 0; + + /// Used to sort the plugins before attempting to load. Plugins with a lower + /// value here will run over a directory first. + virtual unsigned getPriority() const = 0; }; using CompilationDatabasePluginRegistry = diff --git a/clang/lib/Tooling/CompilationDatabase.cpp b/clang/lib/Tooling/CompilationDatabase.cpp --- a/clang/lib/Tooling/CompilationDatabase.cpp +++ b/clang/lib/Tooling/CompilationDatabase.cpp @@ -64,14 +64,26 @@ CompilationDatabase::loadFromDirectory(StringRef BuildDirectory, std::string &ErrorMessage) { llvm::raw_string_ostream ErrorStream(ErrorMessage); + using NameAndPlugin = + std::pair>; + llvm::SmallVector Plugins; + for (const CompilationDatabasePluginRegistry::entry &Database : CompilationDatabasePluginRegistry::entries()) { + Plugins.emplace_back(Database.getName(), Database.instantiate()); + } + llvm::sort(Plugins, [](const NameAndPlugin &LHS, const NameAndPlugin &RHS) { + assert(LHS.second->getPriority() != RHS.second->getPriority() && + "Undeterministic priority"); + return LHS.second->getPriority() < RHS.second->getPriority(); + }); + for (auto &Plugin : Plugins) { std::string DatabaseErrorMessage; - std::unique_ptr Plugin(Database.instantiate()); if (std::unique_ptr DB = - Plugin->loadFromDirectory(BuildDirectory, DatabaseErrorMessage)) + Plugin.second->loadFromDirectory(BuildDirectory, + DatabaseErrorMessage)) return DB; - ErrorStream << Database.getName() << ": " << DatabaseErrorMessage << "\n"; + ErrorStream << Plugin.first << ": " << DatabaseErrorMessage << "\n"; } return nullptr; } @@ -405,6 +417,12 @@ llvm::sys::path::append(DatabasePath, "compile_flags.txt"); return FixedCompilationDatabase::loadFromFile(DatabasePath, ErrorMessage); } + + unsigned int getPriority() const override { + // Give this a high value as it should be the fallback and any other Plugin + // should be used first. + return 100; + } }; } // namespace diff --git a/clang/lib/Tooling/JSONCompilationDatabase.cpp b/clang/lib/Tooling/JSONCompilationDatabase.cpp --- a/clang/lib/Tooling/JSONCompilationDatabase.cpp +++ b/clang/lib/Tooling/JSONCompilationDatabase.cpp @@ -173,6 +173,13 @@ std::move(Base), llvm::vfs::getRealFileSystem()))) : nullptr; } + + unsigned int getPriority() const override { + // Pretty arbitrary. However we want to leave room for database sources + // which could have a higher priority, like directly supporting ninja or + // make files. + return 50; + } }; } // namespace