Use clangTooling

This commit is contained in:
Fangrui Song 2018-07-13 09:36:02 -07:00
parent b759798e5d
commit aa9cdad54f
3 changed files with 19 additions and 40 deletions

View File

@ -69,6 +69,7 @@ set(_Clang_REQUIRED_VARS Clang_LIBRARY Clang_INCLUDE_DIR Clang_EXECUTABLE
LLVM_INCLUDE_DIR LLVM_BUILD_INCLUDE_DIR) LLVM_INCLUDE_DIR LLVM_BUILD_INCLUDE_DIR)
_Clang_find_library(Clang_LIBRARY clang) _Clang_find_library(Clang_LIBRARY clang)
_Clang_find_add_library(clangTooling)
_Clang_find_add_library(clangIndex) _Clang_find_add_library(clangIndex)
_Clang_find_add_library(clangFrontend) _Clang_find_add_library(clangFrontend)
_Clang_find_add_library(clangParse) _Clang_find_add_library(clangParse)

View File

@ -810,7 +810,7 @@ public:
} }
[[fallthrough]]; [[fallthrough]];
case Decl::Record: { case Decl::Record: {
auto *RD = cast<RecordDecl>(D); auto *RD = cast<RecordDecl>(OrigD);
// spec has no Union, use Class // spec has no Union, use Class
type->def.kind = RD->getTagKind() == TTK_Struct ? lsSymbolKind::Struct type->def.kind = RD->getTagKind() == TTK_Struct ? lsSymbolKind::Struct
: lsSymbolKind::Class; : lsSymbolKind::Class;

View File

@ -16,6 +16,7 @@ using namespace ccls;
#include <clang/Driver/Driver.h> #include <clang/Driver/Driver.h>
#include <clang/Driver/Options.h> #include <clang/Driver/Options.h>
#include <clang/Frontend/CompilerInstance.h> #include <clang/Frontend/CompilerInstance.h>
#include <clang/Tooling/CompilationDatabase.h>
#include <llvm/ADT/ArrayRef.h> #include <llvm/ADT/ArrayRef.h>
#include <llvm/Option/ArgList.h> #include <llvm/Option/ArgList.h>
#include <llvm/Option/OptTable.h> #include <llvm/Option/OptTable.h>
@ -25,7 +26,6 @@ using namespace clang;
using namespace llvm; using namespace llvm;
using namespace llvm::opt; using namespace llvm::opt;
#include <clang-c/CXCompilationDatabase.h>
#include <rapidjson/writer.h> #include <rapidjson/writer.h>
#if defined(__unix__) || defined(__APPLE__) #if defined(__unix__) || defined(__APPLE__)
@ -142,14 +142,14 @@ Project::Entry GetCompilationEntryFromCompileCommandEntry(
return result; return result;
const driver::ArgStringList& CCArgs = Jobs.begin()->getArguments(); const driver::ArgStringList& CCArgs = Jobs.begin()->getArguments();
auto Invocation = std::make_unique<CompilerInvocation>(); auto CI = std::make_unique<CompilerInvocation>();
CompilerInvocation::CreateFromArgs(*Invocation, CCArgs.data(), CompilerInvocation::CreateFromArgs(*CI, CCArgs.data(),
CCArgs.data() + CCArgs.size(), Diags); CCArgs.data() + CCArgs.size(), Diags);
Invocation->getFrontendOpts().DisableFree = false; CI->getFrontendOpts().DisableFree = false;
Invocation->getCodeGenOpts().DisableFree = false; CI->getCodeGenOpts().DisableFree = false;
HeaderSearchOptions& HeaderOpts = Invocation->getHeaderSearchOpts(); HeaderSearchOptions &HeaderOpts = CI->getHeaderSearchOpts();
for (auto& E : HeaderOpts.UserEntries) { for (auto &E : HeaderOpts.UserEntries) {
std::string path = entry.ResolveIfRelative(E.Path); std::string path = entry.ResolveIfRelative(E.Path);
switch (E.Group) { switch (E.Group) {
default: default:
@ -178,7 +178,7 @@ Project::Entry GetCompilationEntryFromCompileCommandEntry(
// if (HeaderOpts.ResourceDir.empty() && HeaderOpts.UseBuiltinIncludes) // if (HeaderOpts.ResourceDir.empty() && HeaderOpts.UseBuiltinIncludes)
args.push_back("-resource-dir=" + g_config->clang.resourceDir); args.push_back("-resource-dir=" + g_config->clang.resourceDir);
// if (Invocation->getFileSystemOpts().WorkingDir.empty()) // if (CI->getFileSystemOpts().WorkingDir.empty())
args.push_back("-working-directory=" + entry.directory); args.push_back("-working-directory=" + entry.directory);
// There could be a clang version mismatch between what the project uses and // There could be a clang version mismatch between what the project uses and
@ -300,9 +300,9 @@ std::vector<Project::Entry> LoadCompilationEntriesFromDirectory(
#endif #endif
} }
CXCompilationDatabase_Error cx_db_load_error; std::string err_msg;
CXCompilationDatabase cx_db = clang_CompilationDatabase_fromDirectory( std::unique_ptr<tooling::CompilationDatabase> CDB =
comp_db_dir.c_str(), &cx_db_load_error); tooling::CompilationDatabase::loadFromDirectory(comp_db_dir, err_msg);
if (!g_config->compilationDatabaseCommand.empty()) { if (!g_config->compilationDatabaseCommand.empty()) {
#ifdef _WIN32 #ifdef _WIN32
// TODO // TODO
@ -311,44 +311,22 @@ std::vector<Project::Entry> LoadCompilationEntriesFromDirectory(
rmdir(comp_db_dir.c_str()); rmdir(comp_db_dir.c_str());
#endif #endif
} }
if (cx_db_load_error == CXCompilationDatabase_CanNotLoadDatabase) { if (!CDB) {
LOG_S(WARNING) << "unable to load " << Path.c_str(); LOG_S(WARNING) << "failed to load " << Path.c_str() << " " << err_msg;
return {}; return {};
} }
LOG_S(INFO) << "loaded " << Path.c_str(); LOG_S(INFO) << "loaded " << Path.c_str();
CXCompileCommands cx_commands =
clang_CompilationDatabase_getAllCompileCommands(cx_db);
unsigned int num_commands = clang_CompileCommands_getSize(cx_commands);
std::vector<Project::Entry> result; std::vector<Project::Entry> result;
for (unsigned int i = 0; i < num_commands; i++) { for (tooling::CompileCommand &Cmd : CDB->getAllCompileCommands()) {
CXCompileCommand cx_command =
clang_CompileCommands_getCommand(cx_commands, i);
std::string directory =
ToString(clang_CompileCommand_getDirectory(cx_command));
std::string relative_filename =
ToString(clang_CompileCommand_getFilename(cx_command));
unsigned num_args = clang_CompileCommand_getNumArgs(cx_command);
CompileCommandsEntry entry; CompileCommandsEntry entry;
entry.args.reserve(num_args); entry.directory = std::move(Cmd.Directory);
for (unsigned j = 0; j < num_args; ++j) { entry.file = entry.ResolveIfRelative(Cmd.Filename);
entry.args.push_back( entry.args = std::move(Cmd.CommandLine);
ToString(clang_CompileCommand_getArg(cx_command, j)));
}
entry.directory = directory;
entry.file = entry.ResolveIfRelative(relative_filename);
result.push_back( result.push_back(
GetCompilationEntryFromCompileCommandEntry(project, entry)); GetCompilationEntryFromCompileCommandEntry(project, entry));
} }
clang_CompileCommands_dispose(cx_commands);
clang_CompilationDatabase_dispose(cx_db);
return result; return result;
} }