experimental/filesystem -> LLVM/Support/FileSystem.h; sparsepp -> DenseMap

This commit is contained in:
Fangrui Song 2018-05-13 13:30:24 -07:00
parent c81ca26a2e
commit 36729818c3
15 changed files with 116 additions and 110 deletions

3
.gitmodules vendored
View File

@ -4,9 +4,6 @@
[submodule "third_party/doctest"] [submodule "third_party/doctest"]
path = third_party/doctest path = third_party/doctest
url = https://github.com/onqtam/doctest url = https://github.com/onqtam/doctest
[submodule "third_party/sparsepp"]
path = third_party/sparsepp
url = https://github.com/greg7mdp/sparsepp
[submodule "third_party/loguru"] [submodule "third_party/loguru"]
path = third_party/loguru path = third_party/loguru
url = https://github.com/emilk/loguru url = https://github.com/emilk/loguru

View File

@ -91,10 +91,9 @@ if(NOT SYSTEM_CLANG)
target_compile_options(ccls PRIVATE -nostdinc++ -cxx-isystem ${CLANG_ROOT}/include/c++/v1) target_compile_options(ccls PRIVATE -nostdinc++ -cxx-isystem ${CLANG_ROOT}/include/c++/v1)
if(${CMAKE_SYSTEM_NAME} STREQUAL Linux) if(${CMAKE_SYSTEM_NAME} STREQUAL Linux)
# Don't use -stdlib=libc++ because while ccls is linked with libc++, bundled clang+llvm require libstdc++ # Don't use -stdlib=libc++ because while ccls is linked with libc++, bundled clang+llvm require libstdc++
target_link_libraries(ccls PRIVATE -L${CLANG_ROOT}/lib c++ c++experimental c++abi) target_link_libraries(ccls PRIVATE -L${CLANG_ROOT}/lib c++ c++abi)
else()
# FreeBSD uses system libcxxrt.a and does not need libc++abi. # FreeBSD defaults to -stdlib=libc++ and uses system libcxxrt.a
target_link_libraries(ccls PRIVATE -stdlib=libc++ -L${CLANG_ROOT}/lib c++experimental)
endif() endif()
endif() endif()
@ -121,25 +120,17 @@ if(${CMAKE_SYSTEM_NAME} STREQUAL Darwin)
target_link_libraries(ccls PRIVATE -lc++experimental) target_link_libraries(ccls PRIVATE -lc++experimental)
elseif(${CMAKE_SYSTEM_NAME} STREQUAL Linux) elseif(${CMAKE_SYSTEM_NAME} STREQUAL Linux)
if(NOT CLANG_USE_BUNDLED_LIBC++)
target_link_libraries(ccls PRIVATE -lstdc++fs)
endif()
# loguru calls dladdr # loguru calls dladdr
target_link_libraries(ccls PRIVATE ${CMAKE_DL_LIBS}) target_link_libraries(ccls PRIVATE ${CMAKE_DL_LIBS})
elseif(${CMAKE_SYSTEM_NAME} STREQUAL FreeBSD) elseif(${CMAKE_SYSTEM_NAME} STREQUAL FreeBSD)
# loguru::stacktrace_as_stdstring calls backtrace_symbols # loguru::stacktrace_as_stdstring calls backtrace_symbols
# sparsepp/spp_memory.h uses libkvm
# src/platform_posix.cc uses libthr # src/platform_posix.cc uses libthr
find_package(Backtrace REQUIRED) find_package(Backtrace REQUIRED)
target_link_libraries(ccls PRIVATE ${Backtrace_LIBRARIES} kvm thr) target_link_libraries(ccls PRIVATE ${Backtrace_LIBRARIES} thr)
if(SYSTEM_CLANG) if(SYSTEM_CLANG)
target_link_libraries(ccls PRIVATE c++experimental) target_link_libraries(ccls PRIVATE c++experimental)
endif() endif()
elseif(${CMAKE_SYSTEM_NAME} STREQUAL Windows)
# sparsepp/spp_memory.h uses LibPsapi
target_link_libraries(ccls PRIVATE Psapi)
endif() endif()
### Definitions ### Definitions
@ -156,7 +147,6 @@ target_include_directories(ccls PRIVATE
src src
third_party third_party
third_party/rapidjson/include third_party/rapidjson/include
third_party/sparsepp
third_party/loguru third_party/loguru
third_party/doctest) third_party/doctest)

View File

@ -70,6 +70,7 @@ set(_Clang_REQUIRED_VARS Clang_LIBRARY Clang_INCLUDE_DIR Clang_EXECUTABLE
_Clang_find_library(Clang_LIBRARY clang) _Clang_find_library(Clang_LIBRARY clang)
_Clang_find_add_library(clangDriver) _Clang_find_add_library(clangDriver)
_Clang_find_add_library(clangBasic)
_Clang_find_add_library(LLVMOption) _Clang_find_add_library(LLVMOption)
_Clang_find_add_library(LLVMSupport) _Clang_find_add_library(LLVMSupport)
_Clang_find_add_library(LLVMDemangle) _Clang_find_add_library(LLVMDemangle)

View File

@ -1,10 +1,12 @@
#include "clang_complete.h" #include "clang_complete.h"
#include "clang_utils.h" #include "clang_utils.h"
#include "filesystem.hh"
#include "platform.h" #include "platform.h"
#include "timer.h" #include "timer.h"
#include "filesystem.hh"
using namespace llvm;
#include <loguru.hpp> #include <loguru.hpp>
#include <algorithm> #include <algorithm>
@ -29,8 +31,9 @@ unsigned Flags() {
} }
std::string StripFileType(const std::string& path) { std::string StripFileType(const std::string& path) {
fs::path p(path); SmallString<128> Ret;
return p.parent_path() / p.stem(); sys::path::append(Ret, sys::path::parent_path(path), sys::path::stem(path));
return Ret.str();
} }
unsigned GetCompletionPriority(const CXCompletionString& str, unsigned GetCompletionPriority(const CXCompletionString& str,

View File

@ -1,8 +1,10 @@
#include "clang_utils.h" #include "clang_utils.h"
#include "filesystem.hh"
#include "platform.h" #include "platform.h"
#include "filesystem.hh"
using namespace llvm;
namespace { namespace {
lsRange GetLsRangeForFixIt(const CXSourceRange& range) { lsRange GetLsRangeForFixIt(const CXSourceRange& range) {
@ -115,8 +117,11 @@ std::string FileName(CXFile file) {
// clang_getFileName return values may contain .. // clang_getFileName return values may contain ..
ret = NormalizePath(ToString(clang_getFileName(file))); ret = NormalizePath(ToString(clang_getFileName(file)));
// Resolve /usr/include/c++/7.3.0 symlink. // Resolve /usr/include/c++/7.3.0 symlink.
if (!StartsWith(ret, g_config->projectRoot)) if (!StartsWith(ret, g_config->projectRoot)) {
ret = fs::canonical(ret); SmallString<256> dest;
sys::fs::real_path(ret, dest);
ret = dest.str();
}
return ret; return ret;
} }

View File

@ -1,8 +1,8 @@
#include "filesystem.hh" #include "filesystem.hh"
using namespace llvm;
#include "utils.h" #include "utils.h"
#include <queue>
#include <utility> #include <utility>
static void GetFilesInFolderHelper( static void GetFilesInFolderHelper(
@ -10,31 +10,33 @@ static void GetFilesInFolderHelper(
bool recursive, bool recursive,
std::string output_prefix, std::string output_prefix,
const std::function<void(const std::string&)>& handler) { const std::function<void(const std::string&)>& handler) {
std::queue<std::pair<fs::path, fs::path>> q; std::error_code ec;
q.emplace(fs::path(folder), fs::path(output_prefix)); if (recursive)
while (!q.empty()) { for (sys::fs::recursive_directory_iterator I(folder, ec), E; I != E && !ec;
try { I.increment(ec)) {
for (auto it = fs::directory_iterator(q.front().first); std::string path = I->path(), filename = sys::path::filename(path);
it != fs::directory_iterator(); ++it) { if (filename[0] != '.' || filename == ".ccls") {
auto path = it->path(); SmallString<256> Path;
std::string filename = path.filename(); if (output_prefix.size()) {
if (filename[0] != '.' || filename == ".ccls") { sys::path::append(Path, output_prefix, path);
fs::file_status status = it->symlink_status(); handler(Path.str());
if (fs::is_regular_file(status)) } else
handler(q.front().second / filename); handler(path);
else if (fs::is_directory(status) || fs::is_symlink(status)) { }
if (recursive) { }
std::string child_dir = q.front().second / filename; else
if (fs::is_directory(status)) for (sys::fs::directory_iterator I(folder, ec), E; I != E && !ec;
q.push(make_pair(path, child_dir)); I.increment(ec)) {
} std::string path = I->path(), filename = sys::path::filename(path);
} if (filename[0] != '.' || filename == ".ccls") {
} SmallString<256> Path;
if (output_prefix.size()) {
sys::path::append(Path, output_prefix, path);
handler(Path.str());
} else
handler(path);
} }
} catch (fs::filesystem_error&) {
} }
q.pop();
}
} }
void GetFilesInFolder(std::string folder, void GetFilesInFolder(std::string folder,

View File

@ -1,11 +1,11 @@
#pragma once #pragma once
#include <experimental/filesystem> #include <llvm/Support/FileSystem.h>
#include <llvm/Support/Path.h>
#include <functional> #include <functional>
#include <string> #include <string>
namespace fs = std::experimental::filesystem;
void GetFilesInFolder(std::string folder, void GetFilesInFolder(std::string folder,
bool recursive, bool recursive,
bool add_folder_to_path, bool add_folder_to_path,

View File

@ -1,6 +1,5 @@
#include "cache_manager.h" #include "cache_manager.h"
#include "diagnostics_engine.h" #include "diagnostics_engine.h"
#include "filesystem.hh"
#include "import_pipeline.h" #include "import_pipeline.h"
#include "include_complete.h" #include "include_complete.h"
#include "message_handler.h" #include "message_handler.h"
@ -11,6 +10,9 @@
#include "timer.h" #include "timer.h"
#include "working_files.h" #include "working_files.h"
#include "filesystem.hh"
using namespace llvm;
#include <loguru.hpp> #include <loguru.hpp>
#include <iostream> #include <iostream>
@ -492,10 +494,10 @@ struct Handler_Initialize : BaseMessageHandler<In_InitializeRequest> {
config->projectRoot = project_path; config->projectRoot = project_path;
// Create two cache directories for files inside and outside of the // Create two cache directories for files inside and outside of the
// project. // project.
fs::create_directories(config->cacheDirectory + sys::fs::create_directories(config->cacheDirectory +
EscapeFileName(config->projectRoot)); EscapeFileName(config->projectRoot));
fs::create_directories(config->cacheDirectory + '@' + sys::fs::create_directories(config->cacheDirectory + '@' +
EscapeFileName(config->projectRoot)); EscapeFileName(config->projectRoot));
g_config = std::move(config); g_config = std::move(config);
Timer time; Timer time;

View File

@ -35,15 +35,17 @@ using namespace llvm::opt;
#include <vector> #include <vector>
struct CompileCommandsEntry { struct CompileCommandsEntry {
fs::path directory; std::string directory;
std::string file; std::string file;
std::string command; std::string command;
std::vector<std::string> args; std::vector<std::string> args;
fs::path ResolveIfRelative(fs::path path) const { std::string ResolveIfRelative(std::string path) const {
if (path.is_absolute()) if (sys::path::is_absolute(path))
return path; return path;
return directory / path; SmallString<256> Ret;
sys::path::append(Ret, directory, path);
return Ret.str();
} }
}; };
MAKE_REFLECT_STRUCT(CompileCommandsEntry, directory, file, command, args); MAKE_REFLECT_STRUCT(CompileCommandsEntry, directory, file, command, args);
@ -56,7 +58,7 @@ struct ProjectConfig {
std::unordered_set<std::string> quote_dirs; std::unordered_set<std::string> quote_dirs;
std::unordered_set<std::string> angle_dirs; std::unordered_set<std::string> angle_dirs;
std::vector<std::string> extra_flags; std::vector<std::string> extra_flags;
fs::path project_dir; std::string project_dir;
ProjectMode mode = ProjectMode::CompileCommandsJson; ProjectMode mode = ProjectMode::CompileCommandsJson;
}; };
@ -72,7 +74,7 @@ Project::Entry GetCompilationEntryFromCompileCommandEntry(
const CompileCommandsEntry& entry) { const CompileCommandsEntry& entry) {
Project::Entry result; Project::Entry result;
result.filename = entry.file; result.filename = entry.file;
const std::string base_name = fs::path(entry.file).filename(); const std::string base_name = sys::path::filename(entry.file);
// Expand %c %cpp %clang // Expand %c %cpp %clang
std::vector<std::string> args; std::vector<std::string> args;
@ -145,7 +147,7 @@ Project::Entry GetCompilationEntryFromCompileCommandEntry(
if (!Args.hasArg(OPT_resource_dir)) if (!Args.hasArg(OPT_resource_dir))
args.push_back("-resource-dir=" + g_config->clang.resourceDir); args.push_back("-resource-dir=" + g_config->clang.resourceDir);
if (!Args.hasArg(OPT_working_directory)) if (!Args.hasArg(OPT_working_directory))
args.push_back("-working-directory=" + entry.directory.string()); 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
// what ccls uses. Make sure we do not emit warnings for mismatched options. // what ccls uses. Make sure we do not emit warnings for mismatched options.
@ -176,10 +178,11 @@ std::vector<std::string> ReadCompilerArgumentsFromFile(
std::vector<Project::Entry> LoadFromDirectoryListing(ProjectConfig* config) { std::vector<Project::Entry> LoadFromDirectoryListing(ProjectConfig* config) {
std::vector<Project::Entry> result; std::vector<Project::Entry> result;
config->mode = ProjectMode::DotCcls; config->mode = ProjectMode::DotCcls;
LOG_IF_S(WARNING, !fs::exists(config->project_dir / ".ccls") && SmallString<256> Path;
config->extra_flags.empty()) sys::path::append(Path, config->project_dir, ".ccls");
<< "ccls has no clang arguments. Considering adding either a " LOG_IF_S(WARNING, !sys::fs::exists(Path) && config->extra_flags.empty())
"compile_commands.json or .ccls file. See the ccls README for " << "ccls has no clang arguments. Use either "
"compile_commands.json or .ccls, See ccls README for "
"more information."; "more information.";
std::unordered_map<std::string, std::vector<std::string>> folder_args; std::unordered_map<std::string, std::vector<std::string>> folder_args;
@ -190,21 +193,20 @@ std::vector<Project::Entry> LoadFromDirectoryListing(ProjectConfig* config) {
[&folder_args, &files](const std::string& path) { [&folder_args, &files](const std::string& path) {
if (SourceFileLanguage(path) != LanguageId::Unknown) { if (SourceFileLanguage(path) != LanguageId::Unknown) {
files.push_back(path); files.push_back(path);
} else if (fs::path(path).filename() == ".ccls") { } else if (sys::path::filename(path) == ".ccls") {
LOG_S(INFO) << "Using .ccls arguments from " << path; LOG_S(INFO) << "Using .ccls arguments from " << path;
folder_args.emplace( folder_args.emplace(sys::path::parent_path(path),
fs::path(path).parent_path().string(), ReadCompilerArgumentsFromFile(path));
ReadCompilerArgumentsFromFile(path));
} }
}); });
const std::string project_dir = config->project_dir.string(); const std::string& project_dir = config->project_dir;
const auto& project_dir_args = folder_args[project_dir]; const auto& project_dir_args = folder_args[project_dir];
LOG_IF_S(INFO, !project_dir_args.empty()) LOG_IF_S(INFO, !project_dir_args.empty())
<< "Using .ccls arguments " << StringJoin(project_dir_args); << "Using .ccls arguments " << StringJoin(project_dir_args);
auto GetCompilerArgumentForFile = [&project_dir, &folder_args](fs::path cur) { auto GetCompilerArgumentForFile = [&project_dir, &folder_args](std::string cur) {
while (!(cur = cur.parent_path()).empty()) { while (!(cur = sys::path::parent_path(cur)).empty()) {
auto it = folder_args.find(cur); auto it = folder_args.find(cur);
if (it != folder_args.end()) if (it != folder_args.end())
return it->second; return it->second;
@ -235,16 +237,20 @@ std::vector<Project::Entry> LoadCompilationEntriesFromDirectory(
ProjectConfig* project, ProjectConfig* project,
const std::string& opt_compilation_db_dir) { const std::string& opt_compilation_db_dir) {
// If there is a .ccls file always load using directory listing. // If there is a .ccls file always load using directory listing.
if (fs::exists(project->project_dir / ".ccls")) SmallString<256> Path;
sys::path::append(Path, project->project_dir, ".ccls");
if (sys::fs::exists(Path))
return LoadFromDirectoryListing(project); return LoadFromDirectoryListing(project);
// If |compilationDatabaseCommand| is specified, execute it to get the compdb. // If |compilationDatabaseCommand| is specified, execute it to get the compdb.
fs::path comp_db_dir; std::string comp_db_dir;
Path.clear();
if (g_config->compilationDatabaseCommand.empty()) { if (g_config->compilationDatabaseCommand.empty()) {
project->mode = ProjectMode::CompileCommandsJson; project->mode = ProjectMode::CompileCommandsJson;
// Try to load compile_commands.json, but fallback to a project listing. // Try to load compile_commands.json, but fallback to a project listing.
comp_db_dir = opt_compilation_db_dir.empty() ? project->project_dir.string() comp_db_dir = opt_compilation_db_dir.empty() ? project->project_dir
: opt_compilation_db_dir; : opt_compilation_db_dir;
sys::path::append(Path, comp_db_dir, "compile_commands.json");
} else { } else {
project->mode = ProjectMode::ExternalCommand; project->mode = ProjectMode::ExternalCommand;
#ifdef _WIN32 #ifdef _WIN32
@ -254,6 +260,7 @@ std::vector<Project::Entry> LoadCompilationEntriesFromDirectory(
if (!mkdtemp(tmpdir)) if (!mkdtemp(tmpdir))
return {}; return {};
comp_db_dir = tmpdir; comp_db_dir = tmpdir;
sys::path::append(Path, comp_db_dir, "compile_commands.json");
rapidjson::StringBuffer input; rapidjson::StringBuffer input;
rapidjson::Writer<rapidjson::StringBuffer> writer(input); rapidjson::Writer<rapidjson::StringBuffer> writer(input);
JsonWriter json_writer(&writer); JsonWriter json_writer(&writer);
@ -262,14 +269,12 @@ std::vector<Project::Entry> LoadCompilationEntriesFromDirectory(
std::vector<std::string>{g_config->compilationDatabaseCommand, std::vector<std::string>{g_config->compilationDatabaseCommand,
project->project_dir}, project->project_dir},
input.GetString()); input.GetString());
FILE* fout = fopen((comp_db_dir / "compile_commands.json").c_str(), "wb"); FILE* fout = fopen(Path.c_str(), "wb");
fwrite(contents.c_str(), contents.size(), 1, fout); fwrite(contents.c_str(), contents.size(), 1, fout);
fclose(fout); fclose(fout);
#endif #endif
} }
fs::path comp_db_path = comp_db_dir / "compile_commands.json";
LOG_S(INFO) << "Trying to load " << comp_db_path.string();
CXCompilationDatabase_Error cx_db_load_error; CXCompilationDatabase_Error cx_db_load_error;
CXCompilationDatabase cx_db = clang_CompilationDatabase_fromDirectory( CXCompilationDatabase cx_db = clang_CompilationDatabase_fromDirectory(
comp_db_dir.c_str(), &cx_db_load_error); comp_db_dir.c_str(), &cx_db_load_error);
@ -277,17 +282,18 @@ std::vector<Project::Entry> LoadCompilationEntriesFromDirectory(
#ifdef _WIN32 #ifdef _WIN32
// TODO // TODO
#else #else
unlink(comp_db_path.c_str()); unlink(Path.c_str());
rmdir(comp_db_dir.c_str()); rmdir(comp_db_dir.c_str());
#endif #endif
} }
if (cx_db_load_error == CXCompilationDatabase_CanNotLoadDatabase) { if (cx_db_load_error == CXCompilationDatabase_CanNotLoadDatabase) {
LOG_S(INFO) << "Unable to load " << comp_db_path.string() LOG_S(INFO) << "unable to load " << Path.c_str()
<< "; using directory listing instead."; << "; using directory listing instead.";
return LoadFromDirectoryListing(project); return LoadFromDirectoryListing(project);
} }
LOG_S(INFO) << "loaded " << Path.c_str();
Timer clang_time; Timer clang_time;
Timer our_time; Timer our_time;
clang_time.Pause(); clang_time.Pause();
@ -437,13 +443,12 @@ Project::Entry Project::FindCompilationEntryForFile(
// |best_entry| probably has its own path in the arguments. We need to remap // |best_entry| probably has its own path in the arguments. We need to remap
// that path to the new filename. // that path to the new filename.
fs::path best_entry_base_name = fs::path(best_entry->filename).filename(); std::string best_entry_base_name = sys::path::filename(best_entry->filename);
for (std::string& arg : result.args) { for (std::string& arg : result.args) {
try { try {
if (arg == best_entry->filename || if (arg == best_entry->filename ||
fs::path(arg).filename() == best_entry_base_name) { sys::path::filename(arg) == best_entry_base_name)
arg = filename; arg = filename;
}
} catch (...) { } catch (...) {
} }
} }

View File

@ -154,7 +154,7 @@ QueryFile::DefUpdate BuildFileDefUpdate(const IndexFile& indexed) {
// Returns true if an element with the same file is found. // Returns true if an element with the same file is found.
template <typename Q> template <typename Q>
bool TryReplaceDef(std::forward_list<Q>& def_list, Q&& def) { bool TryReplaceDef(llvm::SmallVectorImpl<Q>& def_list, Q&& def) {
for (auto& def1 : def_list) for (auto& def1 : def_list)
if (def1.spell->file_id == def.spell->file_id) { if (def1.spell->file_id == def.spell->file_id) {
def1 = std::move(def); def1 = std::move(def);
@ -262,18 +262,22 @@ void QueryDatabase::RemoveUsrs(
case SymbolKind::Func: { case SymbolKind::Func: {
for (auto usr : to_remove) { for (auto usr : to_remove) {
QueryFunc& func = Func(usr); QueryFunc& func = Func(usr);
func.def.remove_if([=](const QueryFunc::Def& def) { auto it = llvm::find_if(func.def, [=](const QueryFunc::Def& def) {
return def.spell->file_id == file_id; return def.spell->file_id == file_id;
}); });
if (it != func.def.end())
func.def.erase(it);
} }
break; break;
} }
case SymbolKind::Var: { case SymbolKind::Var: {
for (auto usr : to_remove) { for (auto usr : to_remove) {
QueryVar& var = Var(usr); QueryVar& var = Var(usr);
var.def.remove_if([=](const QueryVar::Def& def) { auto it = llvm::find_if(var.def, [=](const QueryVar::Def& def) {
return def.spell->file_id == file_id; return def.spell->file_id == file_id;
}); });
if (it != var.def.end())
var.def.erase(it);
} }
break; break;
} }
@ -348,7 +352,7 @@ void QueryDatabase::Update(int file_id,
QueryFunc& existing = Func(u.first); QueryFunc& existing = Func(u.first);
existing.usr = u.first; existing.usr = u.first;
if (!TryReplaceDef(existing.def, std::move(def))) { if (!TryReplaceDef(existing.def, std::move(def))) {
existing.def.push_front(std::move(def)); existing.def.push_back(std::move(def));
UpdateSymbols(&existing.symbol_idx, SymbolKind::Func, u.first); UpdateSymbols(&existing.symbol_idx, SymbolKind::Func, u.first);
} }
} }
@ -364,7 +368,7 @@ void QueryDatabase::Update(int file_id,
QueryType& existing = Type(u.first); QueryType& existing = Type(u.first);
existing.usr = u.first; existing.usr = u.first;
if (!TryReplaceDef(existing.def, std::move(def))) { if (!TryReplaceDef(existing.def, std::move(def))) {
existing.def.push_front(std::move(def)); existing.def.push_back(std::move(def));
UpdateSymbols(&existing.symbol_idx, SymbolKind::Type, u.first); UpdateSymbols(&existing.symbol_idx, SymbolKind::Type, u.first);
} }
} }
@ -380,7 +384,7 @@ void QueryDatabase::Update(int file_id,
QueryVar& existing = Var(u.first); QueryVar& existing = Var(u.first);
existing.usr = u.first; existing.usr = u.first;
if (!TryReplaceDef(existing.def, std::move(def))) { if (!TryReplaceDef(existing.def, std::move(def))) {
existing.def.push_front(std::move(def)); existing.def.push_back(std::move(def));
if (!existing.def.front().is_local()) if (!existing.def.front().is_local())
UpdateSymbols(&existing.symbol_idx, SymbolKind::Var, u.first); UpdateSymbols(&existing.symbol_idx, SymbolKind::Var, u.first);
} }

View File

@ -3,9 +3,8 @@
#include "indexer.h" #include "indexer.h"
#include "serializer.h" #include "serializer.h"
#include <sparsepp/spp.h> #include <llvm/ADT/DenseMap.h>
#include <llvm/ADT/SmallVector.h>
#include <forward_list>
struct QueryFile; struct QueryFile;
struct QueryType; struct QueryType;
@ -69,7 +68,7 @@ using UsrUpdate =
struct QueryFunc : QueryEntity<QueryFunc, FuncDef> { struct QueryFunc : QueryEntity<QueryFunc, FuncDef> {
Usr usr; Usr usr;
int symbol_idx = -1; int symbol_idx = -1;
std::forward_list<Def> def; llvm::SmallVector<Def, 1> def;
std::vector<Use> declarations; std::vector<Use> declarations;
std::vector<Use> uses; std::vector<Use> uses;
std::vector<Usr> derived; std::vector<Usr> derived;
@ -78,7 +77,7 @@ struct QueryFunc : QueryEntity<QueryFunc, FuncDef> {
struct QueryType : QueryEntity<QueryType, TypeDef> { struct QueryType : QueryEntity<QueryType, TypeDef> {
Usr usr; Usr usr;
int symbol_idx = -1; int symbol_idx = -1;
std::forward_list<Def> def; llvm::SmallVector<Def, 1> def;
std::vector<Use> declarations; std::vector<Use> declarations;
std::vector<Use> uses; std::vector<Use> uses;
std::vector<Usr> derived; std::vector<Usr> derived;
@ -88,7 +87,7 @@ struct QueryType : QueryEntity<QueryType, TypeDef> {
struct QueryVar : QueryEntity<QueryVar, VarDef> { struct QueryVar : QueryEntity<QueryVar, VarDef> {
Usr usr; Usr usr;
int symbol_idx = -1; int symbol_idx = -1;
std::forward_list<Def> def; llvm::SmallVector<Def, 1> def;
std::vector<Use> declarations; std::vector<Use> declarations;
std::vector<Use> uses; std::vector<Use> uses;
}; };
@ -138,9 +137,9 @@ struct QueryDatabase {
std::vector<QueryFile> files; std::vector<QueryFile> files;
std::unordered_map<std::string, int> name2file_id; std::unordered_map<std::string, int> name2file_id;
spp::sparse_hash_map<Usr, QueryFunc> usr2func; llvm::DenseMap<Usr, QueryFunc> usr2func;
spp::sparse_hash_map<Usr, QueryType> usr2type; llvm::DenseMap<Usr, QueryType> usr2type;
spp::sparse_hash_map<Usr, QueryVar> usr2var; llvm::DenseMap<Usr, QueryVar> usr2var;
// Marks the given Usrs as invalid. // Marks the given Usrs as invalid.
void RemoveUsrs(SymbolKind usr_kind, const std::vector<Usr>& to_remove); void RemoveUsrs(SymbolKind usr_kind, const std::vector<Usr>& to_remove);

View File

@ -11,7 +11,7 @@ Maybe<Use> GetDefinitionExtent(QueryDatabase* db, SymbolIdx sym);
// Get defining declaration (if exists) or an arbitrary declaration (otherwise) // Get defining declaration (if exists) or an arbitrary declaration (otherwise)
// for each id. // for each id.
template <typename Q> template <typename Q>
std::vector<Use> GetDeclarations(spp::sparse_hash_map<Usr, Q>& usr2entity, std::vector<Use> GetDeclarations(llvm::DenseMap<Usr, Q>& usr2entity,
const std::vector<Usr>& usrs) { const std::vector<Usr>& usrs) {
std::vector<Use> ret; std::vector<Use> ret;
ret.reserve(usrs.size()); ret.reserve(usrs.size());
@ -135,7 +135,7 @@ void EachOccurrenceWithParent(QueryDatabase* db,
} }
template <typename Q, typename Fn> template <typename Q, typename Fn>
void EachDefinedEntity(spp::sparse_hash_map<Usr, Q>& collection, void EachDefinedEntity(llvm::DenseMap<Usr, Q>& collection,
const std::vector<Usr>& usrs, const std::vector<Usr>& usrs,
Fn&& fn) { Fn&& fn) {
for (Usr usr : usrs) { for (Usr usr : usrs) {

View File

@ -160,7 +160,7 @@ void Reflect(Writer& visitor, IndexInclude& value) {
REFLECT_MEMBER_START(); REFLECT_MEMBER_START();
REFLECT_MEMBER(line); REFLECT_MEMBER(line);
if (gTestOutputMode) { if (gTestOutputMode) {
std::string basename = fs::path(value.resolved_path).filename(); std::string basename = llvm::sys::path::filename(value.resolved_path);
if (!StartsWith(value.resolved_path, "&")) if (!StartsWith(value.resolved_path, "&"))
basename = "&" + basename; basename = "&" + basename;
REFLECT_MEMBER2("resolved_path", basename); REFLECT_MEMBER2("resolved_path", basename);

View File

@ -1,6 +1,7 @@
#include "utils.h" #include "utils.h"
#include "filesystem.hh" #include "filesystem.hh"
using namespace llvm;
#include "platform.h" #include "platform.h"
#include <doctest/doctest.h> #include <doctest/doctest.h>
@ -137,12 +138,10 @@ void WriteToFile(const std::string& filename, const std::string& content) {
} }
std::optional<int64_t> LastWriteTime(const std::string& filename) { std::optional<int64_t> LastWriteTime(const std::string& filename) {
std::error_code ec; sys::fs::file_status Status;
auto ftime = fs::last_write_time(filename, ec); if (sys::fs::status(filename, Status))
if (ec) return std::nullopt; return {};
return std::chrono::time_point_cast<std::chrono::nanoseconds>(ftime) return Status.getLastModificationTime().time_since_epoch().count();
.time_since_epoch()
.count();
} }
std::string GetDefaultResourceDirectory() { std::string GetDefaultResourceDirectory() {

@ -1 +0,0 @@
Subproject commit 1ca7189fe81ee8c59bf08196852f70843a68a63a