diff --git a/src/command_line.cc b/src/command_line.cc index 61430daa..0cff7cd2 100644 --- a/src/command_line.cc +++ b/src/command_line.cc @@ -1,6 +1,5 @@ // TODO: cleanup includes #include "code_completion.h" -#include "compilation_database_loader.h" #include "indexer.h" #include "query.h" #include "language_server_api.h" @@ -323,7 +322,7 @@ void QueryDbMainLoop( Ipc_OpenProject* msg = static_cast(message.get()); std::string path = msg->project_path; - project->entries = LoadCompilationEntriesFromDirectory(path); + project->Load(path); std::cerr << "Loaded compilation entries (" << project->entries.size() << " files)" << std::endl; //for (int i = 0; i < 10; ++i) //std::cerr << project->entries[i].filename << std::endl; diff --git a/src/compilation_database_loader.cc b/src/compilation_database_loader.cc deleted file mode 100644 index 6ad16d9a..00000000 --- a/src/compilation_database_loader.cc +++ /dev/null @@ -1,181 +0,0 @@ -#include "compilation_database_loader.h" - -#include "libclangmm/Utility.h" -#include "platform.h" -#include "utils.h" - -#include - -#include - -std::vector LoadFromDirectoryListing(const std::string& project_directory) { - std::vector result; - - std::vector args; - for (const std::string& line : ReadLines(project_directory + "/clang_args")) { - if (line.empty() || StartsWith(line, "#")) - continue; - std::cerr << "Adding argument " << line << std::endl; - args.push_back(line); - } - - - std::vector files = GetFilesInFolder(project_directory, true /*recursive*/, true /*add_folder_to_path*/); - for (const std::string& file : files) { - if (EndsWith(file, ".cc") || EndsWith(file, ".cpp") || - EndsWith(file, ".c") || EndsWith(file, ".h") || - EndsWith(file, ".hpp")) { - - CompilationEntry entry; - entry.filename = NormalizePath(file); - entry.args = args; - result.push_back(entry); - } - } - - return result; -} - - -// https://github.com/Andersbakken/rtags/blob/6b16b81ea93aeff4a58930b44b2a0a207b456192/src/Source.cpp -static const char *kValueArgs[] = { - "--param", - "-G", - "-I", - "-MF", - "-MQ", - "-MT", - "-T", - "-V", - "-Xanalyzer", - "-Xassembler", - "-Xclang", - "-Xlinker", - "-Xpreprocessor", - "-arch", - "-b", - "-gcc-toolchain", - "-imacros", - "-imultilib", - "-include", - "-iprefix", - "-isysroot", - "-ivfsoverlay", - "-iwithprefix", - "-iwithprefixbefore", - "-o", - "-target", - "-x" -}; -static const char *kBlacklist[] = { - "--param", - "-M", - "-MD", - "-MF", - "-MG", - "-MM", - "-MMD", - "-MP", - "-MQ", - "-MT", - "-Og", - "-Wa,--32", - "-Wa,--64", - "-Wl,--incremental-full", - "-Wl,--incremental-patch,1", - "-Wl,--no-incremental", - "-fbuild-session-file=", - "-fbuild-session-timestamp=", - "-fembed-bitcode", - "-fembed-bitcode-marker", - "-fmodules-validate-once-per-build-session", - "-fno-delete-null-pointer-checks", - "-fno-use-linker-plugin" - "-fno-var-tracking", - "-fno-var-tracking-assignments", - "-fno-enforce-eh-specs", - "-fvar-tracking", - "-fvar-tracking-assignments", - "-fvar-tracking-assignments-toggle", - "-gcc-toolchain", - "-march=", - "-masm=", - "-mcpu=", - "-mfpmath=", - "-mtune=", - "-s", - - //"-B", - //"-f", - //"-pipe", - //"-W", - "/", - "..", -}; - -std::vector LoadCompilationEntriesFromDirectory(const std::string& project_directory) { - CXCompilationDatabase_Error cx_db_load_error; - CXCompilationDatabase cx_db = clang_CompilationDatabase_fromDirectory(project_directory.c_str(), &cx_db_load_error); - if (cx_db_load_error == CXCompilationDatabase_CanNotLoadDatabase) { - std::cerr << "Unable to load compile_commands.json located at \"" << project_directory << "\"; using directory listing instead." << std::endl; - return LoadFromDirectoryListing(project_directory); - } - - CXCompileCommands cx_commands = clang_CompilationDatabase_getAllCompileCommands(cx_db); - - unsigned int num_commands = clang_CompileCommands_getSize(cx_commands); - std::vector result; - for (unsigned int i = 0; i < num_commands; i++) { - CXCompileCommand cx_command = clang_CompileCommands_getCommand(cx_commands, i); - CompilationEntry entry; - - std::string directory = clang::ToString(clang_CompileCommand_getDirectory(cx_command)); - std::string relative_filename = clang::ToString(clang_CompileCommand_getFilename(cx_command)); - std::string absolute_filename = directory + "/" + relative_filename; - entry.filename = NormalizePath(absolute_filename); - - unsigned int num_args = clang_CompileCommand_getNumArgs(cx_command); - entry.args.reserve(num_args); - for (unsigned int j = 0; j < num_args; ++j) { - std::string arg = clang::ToString(clang_CompileCommand_getArg(cx_command, j)); - - - bool bad = false; - for (auto& entry : kValueArgs) { - if (StartsWith(arg, entry)) { - bad = true; - continue; - } - } - if (bad) { - ++j; - continue; - } - - - for (auto& entry : kBlacklist) { - if (StartsWith(arg, entry)) { - bad = true; - continue; - } - } - if (bad) { - continue; - } - - - - entry.args.push_back(arg); - - //if (StartsWith(arg, "-I") || StartsWith(arg, "-D") || StartsWith(arg, "-std")) - } - - - result.push_back(entry); - } - - clang_CompileCommands_dispose(cx_commands); - clang_CompilationDatabase_dispose(cx_db); - - return result; -} diff --git a/src/compilation_database_loader.h b/src/compilation_database_loader.h deleted file mode 100644 index 96d12dde..00000000 --- a/src/compilation_database_loader.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include -#include - -struct CompilationEntry { - std::string filename; - std::vector args; -}; - -// TODO: Add support for loading when there is no compilation_database.json -// file. We will just recursively scan the directory and support a global -// set of defines and include directories. - -std::vector LoadCompilationEntriesFromDirectory(const std::string& project_directory); \ No newline at end of file diff --git a/src/project.cc b/src/project.cc index 26497829..782c269e 100644 --- a/src/project.cc +++ b/src/project.cc @@ -1,5 +1,191 @@ #include "project.h" +#include "libclangmm/Utility.h" +#include "platform.h" +#include "utils.h" + +#include + +#include + +namespace { +std::vector LoadFromDirectoryListing(const std::string& project_directory) { + std::vector result; + + std::vector args; + for (const std::string& line : ReadLines(project_directory + "/clang_args")) { + if (line.empty() || StartsWith(line, "#")) + continue; + std::cerr << "Adding argument " << line << std::endl; + args.push_back(line); + } + + + std::vector files = GetFilesInFolder(project_directory, true /*recursive*/, true /*add_folder_to_path*/); + for (const std::string& file : files) { + if (EndsWith(file, ".cc") || EndsWith(file, ".cpp") || + EndsWith(file, ".c") || EndsWith(file, ".h") || + EndsWith(file, ".hpp")) { + + CompilationEntry entry; + entry.filename = NormalizePath(file); + entry.args = args; + result.push_back(entry); + } + } + + return result; +} + + +// https://github.com/Andersbakken/rtags/blob/6b16b81ea93aeff4a58930b44b2a0a207b456192/src/Source.cpp +static const char *kValueArgs[] = { + "--param", + "-G", + "-I", + "-MF", + "-MQ", + "-MT", + "-T", + "-V", + "-Xanalyzer", + "-Xassembler", + "-Xclang", + "-Xlinker", + "-Xpreprocessor", + "-arch", + "-b", + "-gcc-toolchain", + "-imacros", + "-imultilib", + "-include", + "-iprefix", + "-isysroot", + "-ivfsoverlay", + "-iwithprefix", + "-iwithprefixbefore", + "-o", + "-target", + "-x" +}; +static const char *kBlacklist[] = { + "--param", + "-M", + "-MD", + "-MF", + "-MG", + "-MM", + "-MMD", + "-MP", + "-MQ", + "-MT", + "-Og", + "-Wa,--32", + "-Wa,--64", + "-Wl,--incremental-full", + "-Wl,--incremental-patch,1", + "-Wl,--no-incremental", + "-fbuild-session-file=", + "-fbuild-session-timestamp=", + "-fembed-bitcode", + "-fembed-bitcode-marker", + "-fmodules-validate-once-per-build-session", + "-fno-delete-null-pointer-checks", + "-fno-use-linker-plugin" + "-fno-var-tracking", + "-fno-var-tracking-assignments", + "-fno-enforce-eh-specs", + "-fvar-tracking", + "-fvar-tracking-assignments", + "-fvar-tracking-assignments-toggle", + "-gcc-toolchain", + "-march=", + "-masm=", + "-mcpu=", + "-mfpmath=", + "-mtune=", + "-s", + + //"-B", + //"-f", + //"-pipe", + //"-W", + "/", + "..", +}; + +std::vector LoadCompilationEntriesFromDirectory(const std::string& project_directory) { + CXCompilationDatabase_Error cx_db_load_error; + CXCompilationDatabase cx_db = clang_CompilationDatabase_fromDirectory(project_directory.c_str(), &cx_db_load_error); + if (cx_db_load_error == CXCompilationDatabase_CanNotLoadDatabase) { + std::cerr << "Unable to load compile_commands.json located at \"" << project_directory << "\"; using directory listing instead." << std::endl; + return LoadFromDirectoryListing(project_directory); + } + + CXCompileCommands cx_commands = clang_CompilationDatabase_getAllCompileCommands(cx_db); + + unsigned int num_commands = clang_CompileCommands_getSize(cx_commands); + std::vector result; + for (unsigned int i = 0; i < num_commands; i++) { + CXCompileCommand cx_command = clang_CompileCommands_getCommand(cx_commands, i); + CompilationEntry entry; + + std::string directory = clang::ToString(clang_CompileCommand_getDirectory(cx_command)); + std::string relative_filename = clang::ToString(clang_CompileCommand_getFilename(cx_command)); + std::string absolute_filename = directory + "/" + relative_filename; + entry.filename = NormalizePath(absolute_filename); + + unsigned int num_args = clang_CompileCommand_getNumArgs(cx_command); + entry.args.reserve(num_args); + for (unsigned int j = 0; j < num_args; ++j) { + std::string arg = clang::ToString(clang_CompileCommand_getArg(cx_command, j)); + + + bool bad = false; + for (auto& entry : kValueArgs) { + if (StartsWith(arg, entry)) { + bad = true; + continue; + } + } + if (bad) { + ++j; + continue; + } + + + for (auto& entry : kBlacklist) { + if (StartsWith(arg, entry)) { + bad = true; + continue; + } + } + if (bad) { + continue; + } + + + + entry.args.push_back(arg); + + //if (StartsWith(arg, "-I") || StartsWith(arg, "-D") || StartsWith(arg, "-std")) + } + + + result.push_back(entry); + } + + clang_CompileCommands_dispose(cx_commands); + clang_CompilationDatabase_dispose(cx_db); + + return result; +} +} // namespace + +void Project::Load(const std::string& directory) { + entries = LoadCompilationEntriesFromDirectory(directory); +} + optional Project::FindCompilationEntryForFile(const std::string& filename) { for (auto& entry : entries) { if (filename == entry.filename) diff --git a/src/project.h b/src/project.h index 6eb2045e..6e9ae891 100644 --- a/src/project.h +++ b/src/project.h @@ -1,14 +1,29 @@ #pragma once -#include "compilation_database_loader.h" // TODO: merge compilation_database_loader into this file. - #include +#include +#include using std::experimental::optional; using std::experimental::nullopt; +struct CompilationEntry { + std::string filename; + std::vector args; +}; + struct Project { std::vector entries; + // Loads a project for the given |directory|. + // + // If |directory| contains a compile_commands.json file, that will be used to + // discover all files and args. Otherwise, a recursive directory listing of + // all *.cpp, *.cc, *.h, and *.hpp files will be used. clang arguments can be + // specified in a clang_args file located inside of |directory|. + void Load(const std::string& directory); + + // Lookup the CompilationEntry for |filename|. optional FindCompilationEntryForFile(const std::string& filename); -}; \ No newline at end of file +}; + diff --git a/src/query.cc b/src/query.cc index fe4f0991..9911cb96 100644 --- a/src/query.cc +++ b/src/query.cc @@ -1,6 +1,5 @@ #include "query.h" -#include "compilation_database_loader.h" #include "indexer.h" #include