compile commands of the database and expose it via the libclang API.
llvm-svn: 169226
const char *CompleteFileName);
/**
+ * \brief Get all the compile commands in the given compilation database.
+ */
+CINDEX_LINKAGE CXCompileCommands
+clang_CompilationDatabase_getAllCompileCommands(CXCompilationDatabase);
+
+/**
* \brief Free the given CompileCommands
*/
CINDEX_LINKAGE void clang_CompileCommands_dispose(CXCompileCommands);
* compatible, thus CINDEX_VERSION_MAJOR is expected to remain stable.
*/
#define CINDEX_VERSION_MAJOR 0
-#define CINDEX_VERSION_MINOR 6
+#define CINDEX_VERSION_MINOR 7
#define CINDEX_VERSION_ENCODE(major, minor) ( \
((major) * 10000) \
/// \brief Returns the list of all files available in the compilation database.
virtual std::vector<std::string> getAllFiles() const = 0;
+
+ /// \brief Returns all compile commands for all the files in the compilation
+ /// database.
+ virtual std::vector<CompileCommand> getAllCompileCommands() const = 0;
};
/// \brief Interface for compilation database plugins.
/// Note: This is always an empty list for the fixed compilation database.
virtual std::vector<std::string> getAllFiles() const;
+ /// \brief Returns all compile commands for all the files in the compilation
+ /// database.
+ ///
+ /// Note: This is always an empty list for the fixed compilation database.
+ virtual std::vector<CompileCommand> getAllCompileCommands() const;
+
private:
/// This is built up to contain a single entry vector to be returned from
/// getCompileCommands after adding the positional argument.
/// These are the 'file' entries of the JSON objects.
virtual std::vector<std::string> getAllFiles() const;
+ /// \brief Returns all compile commands for all the files in the compilation
+ /// database.
+ virtual std::vector<CompileCommand> getAllCompileCommands() const;
+
private:
/// \brief Constructs a JSON compilation database on a memory buffer.
JSONCompilationDatabase(llvm::MemoryBuffer *Database)
typedef std::pair<llvm::yaml::ScalarNode*,
llvm::yaml::ScalarNode*> CompileCommandRef;
+ /// \brief Converts the given array of CompileCommandRefs to CompileCommands.
+ void getCommands(ArrayRef<CompileCommandRef> CommandsRef,
+ std::vector<CompileCommand> &Commands) const;
+
// Maps file paths to the compile command lines for that file.
llvm::StringMap< std::vector<CompileCommandRef> > IndexByFile;
return std::vector<std::string>();
}
+std::vector<CompileCommand>
+FixedCompilationDatabase::getAllCompileCommands() const {
+ return std::vector<CompileCommand>();
+}
+
// This anchor is used to force the linker to link in the generated object file
// and thus register the JSONCompilationDatabasePlugin.
extern volatile int JSONAnchorSource;
CommandsRefI = IndexByFile.find(Match);
if (CommandsRefI == IndexByFile.end())
return std::vector<CompileCommand>();
- const std::vector<CompileCommandRef> &CommandsRef = CommandsRefI->getValue();
std::vector<CompileCommand> Commands;
- for (int I = 0, E = CommandsRef.size(); I != E; ++I) {
- llvm::SmallString<8> DirectoryStorage;
- llvm::SmallString<1024> CommandStorage;
- Commands.push_back(CompileCommand(
- // FIXME: Escape correctly:
- CommandsRef[I].first->getValue(DirectoryStorage),
- unescapeCommandLine(CommandsRef[I].second->getValue(CommandStorage))));
- }
+ getCommands(CommandsRefI->getValue(), Commands);
return Commands;
}
return Result;
}
+std::vector<CompileCommand>
+JSONCompilationDatabase::getAllCompileCommands() const {
+ std::vector<CompileCommand> Commands;
+ for (llvm::StringMap< std::vector<CompileCommandRef> >::const_iterator
+ CommandsRefI = IndexByFile.begin(), CommandsRefEnd = IndexByFile.end();
+ CommandsRefI != CommandsRefEnd; ++CommandsRefI) {
+ getCommands(CommandsRefI->getValue(), Commands);
+ }
+ return Commands;
+}
+
+void JSONCompilationDatabase::getCommands(
+ ArrayRef<CompileCommandRef> CommandsRef,
+ std::vector<CompileCommand> &Commands) const {
+ for (int I = 0, E = CommandsRef.size(); I != E; ++I) {
+ llvm::SmallString<8> DirectoryStorage;
+ llvm::SmallString<1024> CommandStorage;
+ Commands.push_back(CompileCommand(
+ // FIXME: Escape correctly:
+ CommandsRef[I].first->getValue(DirectoryStorage),
+ unescapeCommandLine(CommandsRef[I].second->getValue(CommandStorage))));
+ }
+}
+
bool JSONCompilationDatabase::parse(std::string &ErrorMessage) {
llvm::yaml::document_iterator I = YAMLStream.begin();
if (I == YAMLStream.end()) {
return 0;
}
+CXCompileCommands
+clang_CompilationDatabase_getAllCompileCommands(CXCompilationDatabase CDb) {
+ if (CompilationDatabase *db = static_cast<CompilationDatabase *>(CDb)) {
+ const std::vector<CompileCommand> CCmd(db->getAllCompileCommands());
+ if (!CCmd.empty())
+ return new AllocatedCXCompileCommands( CCmd );
+ }
+
+ return 0;
+}
+
void
clang_CompileCommands_dispose(CXCompileCommands Cmds)
{
clang_CompilationDatabase_fromDirectory
clang_CompilationDatabase_dispose
clang_CompilationDatabase_getCompileCommands
+clang_CompilationDatabase_getAllCompileCommands
clang_CompileCommands_dispose
clang_CompileCommands_getSize
clang_CompileCommands_getCommand
return Database->getAllFiles();
}
+static std::vector<CompileCommand> getAllCompileCommands(StringRef JSONDatabase,
+ std::string &ErrorMessage) {
+ llvm::OwningPtr<CompilationDatabase> Database(
+ JSONCompilationDatabase::loadFromBuffer(JSONDatabase, ErrorMessage));
+ if (!Database) {
+ ADD_FAILURE() << ErrorMessage;
+ return std::vector<CompileCommand>();
+ }
+ return Database->getAllCompileCommands();
+}
+
TEST(JSONCompilationDatabase, GetAllFiles) {
std::string ErrorMessage;
EXPECT_EQ(std::vector<std::string>(),
ErrorMessage)) << ErrorMessage;
}
+TEST(JSONCompilationDatabase, GetAllCompileCommands) {
+ std::string ErrorMessage;
+ EXPECT_EQ(0u,
+ getAllCompileCommands("[]", ErrorMessage).size()) << ErrorMessage;
+
+ StringRef Directory1("//net/dir1");
+ StringRef FileName1("file1");
+ StringRef Command1("command1");
+ StringRef Directory2("//net/dir2");
+ StringRef FileName2("file1");
+ StringRef Command2("command1");
+
+ std::vector<CompileCommand> Commands = getAllCompileCommands(
+ ("[{\"directory\":\"" + Directory1 + "\"," +
+ "\"command\":\"" + Command1 + "\","
+ "\"file\":\"" + FileName1 + "\"},"
+ " {\"directory\":\"" + Directory2 + "\"," +
+ "\"command\":\"" + Command2 + "\","
+ "\"file\":\"" + FileName2 + "\"}]").str(),
+ ErrorMessage);
+ EXPECT_EQ(2U, Commands.size()) << ErrorMessage;
+ EXPECT_EQ(Directory1, Commands[0].Directory) << ErrorMessage;
+ ASSERT_EQ(1u, Commands[0].CommandLine.size());
+ EXPECT_EQ(Command1, Commands[0].CommandLine[0]) << ErrorMessage;
+ EXPECT_EQ(Directory2, Commands[1].Directory) << ErrorMessage;
+ ASSERT_EQ(1u, Commands[1].CommandLine.size());
+ EXPECT_EQ(Command2, Commands[1].CommandLine[0]) << ErrorMessage;
+}
+
static CompileCommand findCompileArgsInJsonDatabase(StringRef FileName,
StringRef JSONDatabase,
std::string &ErrorMessage) {
EXPECT_EQ(0ul, Database.getAllFiles().size());
}
+TEST(FixedCompilationDatabase, GetAllCompileCommands) {
+ std::vector<std::string> CommandLine;
+ CommandLine.push_back("one");
+ CommandLine.push_back("two");
+ FixedCompilationDatabase Database(".", CommandLine);
+
+ EXPECT_EQ(0ul, Database.getAllCompileCommands().size());
+}
+
TEST(ParseFixedCompilationDatabase, ReturnsNullOnEmptyArgumentList) {
int Argc = 0;
llvm::OwningPtr<FixedCompilationDatabase> Database(