mirror of
https://github.com/MaskRay/ccls.git
synced 2024-11-25 09:05:10 +00:00
experimental/filesystem -> LLVM/Support/FileSystem.h; sparsepp -> DenseMap
This commit is contained in:
parent
c81ca26a2e
commit
36729818c3
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -4,9 +4,6 @@
|
||||
[submodule "third_party/doctest"]
|
||||
path = third_party/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"]
|
||||
path = third_party/loguru
|
||||
url = https://github.com/emilk/loguru
|
||||
|
@ -91,10 +91,9 @@ if(NOT SYSTEM_CLANG)
|
||||
target_compile_options(ccls PRIVATE -nostdinc++ -cxx-isystem ${CLANG_ROOT}/include/c++/v1)
|
||||
if(${CMAKE_SYSTEM_NAME} STREQUAL Linux)
|
||||
# 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)
|
||||
else()
|
||||
# FreeBSD uses system libcxxrt.a and does not need libc++abi.
|
||||
target_link_libraries(ccls PRIVATE -stdlib=libc++ -L${CLANG_ROOT}/lib c++experimental)
|
||||
target_link_libraries(ccls PRIVATE -L${CLANG_ROOT}/lib c++ c++abi)
|
||||
|
||||
# FreeBSD defaults to -stdlib=libc++ and uses system libcxxrt.a
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@ -121,25 +120,17 @@ if(${CMAKE_SYSTEM_NAME} STREQUAL Darwin)
|
||||
target_link_libraries(ccls PRIVATE -lc++experimental)
|
||||
|
||||
elseif(${CMAKE_SYSTEM_NAME} STREQUAL Linux)
|
||||
if(NOT CLANG_USE_BUNDLED_LIBC++)
|
||||
target_link_libraries(ccls PRIVATE -lstdc++fs)
|
||||
endif()
|
||||
# loguru calls dladdr
|
||||
target_link_libraries(ccls PRIVATE ${CMAKE_DL_LIBS})
|
||||
|
||||
elseif(${CMAKE_SYSTEM_NAME} STREQUAL FreeBSD)
|
||||
# loguru::stacktrace_as_stdstring calls backtrace_symbols
|
||||
# sparsepp/spp_memory.h uses libkvm
|
||||
# src/platform_posix.cc uses libthr
|
||||
find_package(Backtrace REQUIRED)
|
||||
target_link_libraries(ccls PRIVATE ${Backtrace_LIBRARIES} kvm thr)
|
||||
target_link_libraries(ccls PRIVATE ${Backtrace_LIBRARIES} thr)
|
||||
if(SYSTEM_CLANG)
|
||||
target_link_libraries(ccls PRIVATE c++experimental)
|
||||
endif()
|
||||
|
||||
elseif(${CMAKE_SYSTEM_NAME} STREQUAL Windows)
|
||||
# sparsepp/spp_memory.h uses LibPsapi
|
||||
target_link_libraries(ccls PRIVATE Psapi)
|
||||
endif()
|
||||
|
||||
### Definitions
|
||||
@ -156,7 +147,6 @@ target_include_directories(ccls PRIVATE
|
||||
src
|
||||
third_party
|
||||
third_party/rapidjson/include
|
||||
third_party/sparsepp
|
||||
third_party/loguru
|
||||
third_party/doctest)
|
||||
|
||||
|
@ -70,6 +70,7 @@ set(_Clang_REQUIRED_VARS Clang_LIBRARY Clang_INCLUDE_DIR Clang_EXECUTABLE
|
||||
|
||||
_Clang_find_library(Clang_LIBRARY clang)
|
||||
_Clang_find_add_library(clangDriver)
|
||||
_Clang_find_add_library(clangBasic)
|
||||
_Clang_find_add_library(LLVMOption)
|
||||
_Clang_find_add_library(LLVMSupport)
|
||||
_Clang_find_add_library(LLVMDemangle)
|
||||
|
@ -1,10 +1,12 @@
|
||||
#include "clang_complete.h"
|
||||
|
||||
#include "clang_utils.h"
|
||||
#include "filesystem.hh"
|
||||
#include "platform.h"
|
||||
#include "timer.h"
|
||||
|
||||
#include "filesystem.hh"
|
||||
using namespace llvm;
|
||||
|
||||
#include <loguru.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
@ -29,8 +31,9 @@ unsigned Flags() {
|
||||
}
|
||||
|
||||
std::string StripFileType(const std::string& path) {
|
||||
fs::path p(path);
|
||||
return p.parent_path() / p.stem();
|
||||
SmallString<128> Ret;
|
||||
sys::path::append(Ret, sys::path::parent_path(path), sys::path::stem(path));
|
||||
return Ret.str();
|
||||
}
|
||||
|
||||
unsigned GetCompletionPriority(const CXCompletionString& str,
|
||||
|
@ -1,8 +1,10 @@
|
||||
#include "clang_utils.h"
|
||||
|
||||
#include "filesystem.hh"
|
||||
#include "platform.h"
|
||||
|
||||
#include "filesystem.hh"
|
||||
using namespace llvm;
|
||||
|
||||
namespace {
|
||||
|
||||
lsRange GetLsRangeForFixIt(const CXSourceRange& range) {
|
||||
@ -115,8 +117,11 @@ std::string FileName(CXFile file) {
|
||||
// clang_getFileName return values may contain ..
|
||||
ret = NormalizePath(ToString(clang_getFileName(file)));
|
||||
// Resolve /usr/include/c++/7.3.0 symlink.
|
||||
if (!StartsWith(ret, g_config->projectRoot))
|
||||
ret = fs::canonical(ret);
|
||||
if (!StartsWith(ret, g_config->projectRoot)) {
|
||||
SmallString<256> dest;
|
||||
sys::fs::real_path(ret, dest);
|
||||
ret = dest.str();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
#include "filesystem.hh"
|
||||
using namespace llvm;
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
#include <queue>
|
||||
#include <utility>
|
||||
|
||||
static void GetFilesInFolderHelper(
|
||||
@ -10,31 +10,33 @@ static void GetFilesInFolderHelper(
|
||||
bool recursive,
|
||||
std::string output_prefix,
|
||||
const std::function<void(const std::string&)>& handler) {
|
||||
std::queue<std::pair<fs::path, fs::path>> q;
|
||||
q.emplace(fs::path(folder), fs::path(output_prefix));
|
||||
while (!q.empty()) {
|
||||
try {
|
||||
for (auto it = fs::directory_iterator(q.front().first);
|
||||
it != fs::directory_iterator(); ++it) {
|
||||
auto path = it->path();
|
||||
std::string filename = path.filename();
|
||||
if (filename[0] != '.' || filename == ".ccls") {
|
||||
fs::file_status status = it->symlink_status();
|
||||
if (fs::is_regular_file(status))
|
||||
handler(q.front().second / filename);
|
||||
else if (fs::is_directory(status) || fs::is_symlink(status)) {
|
||||
if (recursive) {
|
||||
std::string child_dir = q.front().second / filename;
|
||||
if (fs::is_directory(status))
|
||||
q.push(make_pair(path, child_dir));
|
||||
}
|
||||
}
|
||||
}
|
||||
std::error_code ec;
|
||||
if (recursive)
|
||||
for (sys::fs::recursive_directory_iterator I(folder, ec), E; I != E && !ec;
|
||||
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);
|
||||
}
|
||||
}
|
||||
else
|
||||
for (sys::fs::directory_iterator I(folder, ec), E; I != E && !ec;
|
||||
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,
|
||||
|
@ -1,11 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <experimental/filesystem>
|
||||
#include <llvm/Support/FileSystem.h>
|
||||
#include <llvm/Support/Path.h>
|
||||
|
||||
#include <functional>
|
||||
#include <string>
|
||||
|
||||
namespace fs = std::experimental::filesystem;
|
||||
|
||||
void GetFilesInFolder(std::string folder,
|
||||
bool recursive,
|
||||
bool add_folder_to_path,
|
||||
|
@ -1,6 +1,5 @@
|
||||
#include "cache_manager.h"
|
||||
#include "diagnostics_engine.h"
|
||||
#include "filesystem.hh"
|
||||
#include "import_pipeline.h"
|
||||
#include "include_complete.h"
|
||||
#include "message_handler.h"
|
||||
@ -11,6 +10,9 @@
|
||||
#include "timer.h"
|
||||
#include "working_files.h"
|
||||
|
||||
#include "filesystem.hh"
|
||||
using namespace llvm;
|
||||
|
||||
#include <loguru.hpp>
|
||||
|
||||
#include <iostream>
|
||||
@ -492,10 +494,10 @@ struct Handler_Initialize : BaseMessageHandler<In_InitializeRequest> {
|
||||
config->projectRoot = project_path;
|
||||
// Create two cache directories for files inside and outside of the
|
||||
// project.
|
||||
fs::create_directories(config->cacheDirectory +
|
||||
EscapeFileName(config->projectRoot));
|
||||
fs::create_directories(config->cacheDirectory + '@' +
|
||||
EscapeFileName(config->projectRoot));
|
||||
sys::fs::create_directories(config->cacheDirectory +
|
||||
EscapeFileName(config->projectRoot));
|
||||
sys::fs::create_directories(config->cacheDirectory + '@' +
|
||||
EscapeFileName(config->projectRoot));
|
||||
|
||||
g_config = std::move(config);
|
||||
Timer time;
|
||||
|
@ -35,15 +35,17 @@ using namespace llvm::opt;
|
||||
#include <vector>
|
||||
|
||||
struct CompileCommandsEntry {
|
||||
fs::path directory;
|
||||
std::string directory;
|
||||
std::string file;
|
||||
std::string command;
|
||||
std::vector<std::string> args;
|
||||
|
||||
fs::path ResolveIfRelative(fs::path path) const {
|
||||
if (path.is_absolute())
|
||||
std::string ResolveIfRelative(std::string path) const {
|
||||
if (sys::path::is_absolute(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);
|
||||
@ -56,7 +58,7 @@ struct ProjectConfig {
|
||||
std::unordered_set<std::string> quote_dirs;
|
||||
std::unordered_set<std::string> angle_dirs;
|
||||
std::vector<std::string> extra_flags;
|
||||
fs::path project_dir;
|
||||
std::string project_dir;
|
||||
ProjectMode mode = ProjectMode::CompileCommandsJson;
|
||||
};
|
||||
|
||||
@ -72,7 +74,7 @@ Project::Entry GetCompilationEntryFromCompileCommandEntry(
|
||||
const CompileCommandsEntry& entry) {
|
||||
Project::Entry result;
|
||||
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
|
||||
std::vector<std::string> args;
|
||||
@ -145,7 +147,7 @@ Project::Entry GetCompilationEntryFromCompileCommandEntry(
|
||||
if (!Args.hasArg(OPT_resource_dir))
|
||||
args.push_back("-resource-dir=" + g_config->clang.resourceDir);
|
||||
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
|
||||
// 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> result;
|
||||
config->mode = ProjectMode::DotCcls;
|
||||
LOG_IF_S(WARNING, !fs::exists(config->project_dir / ".ccls") &&
|
||||
config->extra_flags.empty())
|
||||
<< "ccls has no clang arguments. Considering adding either a "
|
||||
"compile_commands.json or .ccls file. See the ccls README for "
|
||||
SmallString<256> Path;
|
||||
sys::path::append(Path, config->project_dir, ".ccls");
|
||||
LOG_IF_S(WARNING, !sys::fs::exists(Path) && config->extra_flags.empty())
|
||||
<< "ccls has no clang arguments. Use either "
|
||||
"compile_commands.json or .ccls, See ccls README for "
|
||||
"more information.";
|
||||
|
||||
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) {
|
||||
if (SourceFileLanguage(path) != LanguageId::Unknown) {
|
||||
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;
|
||||
folder_args.emplace(
|
||||
fs::path(path).parent_path().string(),
|
||||
ReadCompilerArgumentsFromFile(path));
|
||||
folder_args.emplace(sys::path::parent_path(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];
|
||||
LOG_IF_S(INFO, !project_dir_args.empty())
|
||||
<< "Using .ccls arguments " << StringJoin(project_dir_args);
|
||||
|
||||
auto GetCompilerArgumentForFile = [&project_dir, &folder_args](fs::path cur) {
|
||||
while (!(cur = cur.parent_path()).empty()) {
|
||||
auto GetCompilerArgumentForFile = [&project_dir, &folder_args](std::string cur) {
|
||||
while (!(cur = sys::path::parent_path(cur)).empty()) {
|
||||
auto it = folder_args.find(cur);
|
||||
if (it != folder_args.end())
|
||||
return it->second;
|
||||
@ -235,16 +237,20 @@ std::vector<Project::Entry> LoadCompilationEntriesFromDirectory(
|
||||
ProjectConfig* project,
|
||||
const std::string& opt_compilation_db_dir) {
|
||||
// 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);
|
||||
|
||||
// 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()) {
|
||||
project->mode = ProjectMode::CompileCommandsJson;
|
||||
// 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;
|
||||
sys::path::append(Path, comp_db_dir, "compile_commands.json");
|
||||
} else {
|
||||
project->mode = ProjectMode::ExternalCommand;
|
||||
#ifdef _WIN32
|
||||
@ -254,6 +260,7 @@ std::vector<Project::Entry> LoadCompilationEntriesFromDirectory(
|
||||
if (!mkdtemp(tmpdir))
|
||||
return {};
|
||||
comp_db_dir = tmpdir;
|
||||
sys::path::append(Path, comp_db_dir, "compile_commands.json");
|
||||
rapidjson::StringBuffer input;
|
||||
rapidjson::Writer<rapidjson::StringBuffer> writer(input);
|
||||
JsonWriter json_writer(&writer);
|
||||
@ -262,14 +269,12 @@ std::vector<Project::Entry> LoadCompilationEntriesFromDirectory(
|
||||
std::vector<std::string>{g_config->compilationDatabaseCommand,
|
||||
project->project_dir},
|
||||
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);
|
||||
fclose(fout);
|
||||
#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 cx_db = clang_CompilationDatabase_fromDirectory(
|
||||
comp_db_dir.c_str(), &cx_db_load_error);
|
||||
@ -277,17 +282,18 @@ std::vector<Project::Entry> LoadCompilationEntriesFromDirectory(
|
||||
#ifdef _WIN32
|
||||
// TODO
|
||||
#else
|
||||
unlink(comp_db_path.c_str());
|
||||
unlink(Path.c_str());
|
||||
rmdir(comp_db_dir.c_str());
|
||||
#endif
|
||||
}
|
||||
|
||||
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.";
|
||||
return LoadFromDirectoryListing(project);
|
||||
}
|
||||
|
||||
LOG_S(INFO) << "loaded " << Path.c_str();
|
||||
|
||||
Timer clang_time;
|
||||
Timer our_time;
|
||||
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
|
||||
// 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) {
|
||||
try {
|
||||
if (arg == best_entry->filename ||
|
||||
fs::path(arg).filename() == best_entry_base_name) {
|
||||
sys::path::filename(arg) == best_entry_base_name)
|
||||
arg = filename;
|
||||
}
|
||||
} catch (...) {
|
||||
}
|
||||
}
|
||||
|
16
src/query.cc
16
src/query.cc
@ -154,7 +154,7 @@ QueryFile::DefUpdate BuildFileDefUpdate(const IndexFile& indexed) {
|
||||
|
||||
// Returns true if an element with the same file is found.
|
||||
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)
|
||||
if (def1.spell->file_id == def.spell->file_id) {
|
||||
def1 = std::move(def);
|
||||
@ -262,18 +262,22 @@ void QueryDatabase::RemoveUsrs(
|
||||
case SymbolKind::Func: {
|
||||
for (auto usr : to_remove) {
|
||||
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;
|
||||
});
|
||||
if (it != func.def.end())
|
||||
func.def.erase(it);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SymbolKind::Var: {
|
||||
for (auto usr : to_remove) {
|
||||
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;
|
||||
});
|
||||
if (it != var.def.end())
|
||||
var.def.erase(it);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -348,7 +352,7 @@ void QueryDatabase::Update(int file_id,
|
||||
QueryFunc& existing = Func(u.first);
|
||||
existing.usr = u.first;
|
||||
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);
|
||||
}
|
||||
}
|
||||
@ -364,7 +368,7 @@ void QueryDatabase::Update(int file_id,
|
||||
QueryType& existing = Type(u.first);
|
||||
existing.usr = u.first;
|
||||
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);
|
||||
}
|
||||
}
|
||||
@ -380,7 +384,7 @@ void QueryDatabase::Update(int file_id,
|
||||
QueryVar& existing = Var(u.first);
|
||||
existing.usr = u.first;
|
||||
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())
|
||||
UpdateSymbols(&existing.symbol_idx, SymbolKind::Var, u.first);
|
||||
}
|
||||
|
17
src/query.h
17
src/query.h
@ -3,9 +3,8 @@
|
||||
#include "indexer.h"
|
||||
#include "serializer.h"
|
||||
|
||||
#include <sparsepp/spp.h>
|
||||
|
||||
#include <forward_list>
|
||||
#include <llvm/ADT/DenseMap.h>
|
||||
#include <llvm/ADT/SmallVector.h>
|
||||
|
||||
struct QueryFile;
|
||||
struct QueryType;
|
||||
@ -69,7 +68,7 @@ using UsrUpdate =
|
||||
struct QueryFunc : QueryEntity<QueryFunc, FuncDef> {
|
||||
Usr usr;
|
||||
int symbol_idx = -1;
|
||||
std::forward_list<Def> def;
|
||||
llvm::SmallVector<Def, 1> def;
|
||||
std::vector<Use> declarations;
|
||||
std::vector<Use> uses;
|
||||
std::vector<Usr> derived;
|
||||
@ -78,7 +77,7 @@ struct QueryFunc : QueryEntity<QueryFunc, FuncDef> {
|
||||
struct QueryType : QueryEntity<QueryType, TypeDef> {
|
||||
Usr usr;
|
||||
int symbol_idx = -1;
|
||||
std::forward_list<Def> def;
|
||||
llvm::SmallVector<Def, 1> def;
|
||||
std::vector<Use> declarations;
|
||||
std::vector<Use> uses;
|
||||
std::vector<Usr> derived;
|
||||
@ -88,7 +87,7 @@ struct QueryType : QueryEntity<QueryType, TypeDef> {
|
||||
struct QueryVar : QueryEntity<QueryVar, VarDef> {
|
||||
Usr usr;
|
||||
int symbol_idx = -1;
|
||||
std::forward_list<Def> def;
|
||||
llvm::SmallVector<Def, 1> def;
|
||||
std::vector<Use> declarations;
|
||||
std::vector<Use> uses;
|
||||
};
|
||||
@ -138,9 +137,9 @@ struct QueryDatabase {
|
||||
|
||||
std::vector<QueryFile> files;
|
||||
std::unordered_map<std::string, int> name2file_id;
|
||||
spp::sparse_hash_map<Usr, QueryFunc> usr2func;
|
||||
spp::sparse_hash_map<Usr, QueryType> usr2type;
|
||||
spp::sparse_hash_map<Usr, QueryVar> usr2var;
|
||||
llvm::DenseMap<Usr, QueryFunc> usr2func;
|
||||
llvm::DenseMap<Usr, QueryType> usr2type;
|
||||
llvm::DenseMap<Usr, QueryVar> usr2var;
|
||||
|
||||
// Marks the given Usrs as invalid.
|
||||
void RemoveUsrs(SymbolKind usr_kind, const std::vector<Usr>& to_remove);
|
||||
|
@ -11,7 +11,7 @@ Maybe<Use> GetDefinitionExtent(QueryDatabase* db, SymbolIdx sym);
|
||||
// Get defining declaration (if exists) or an arbitrary declaration (otherwise)
|
||||
// for each id.
|
||||
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) {
|
||||
std::vector<Use> ret;
|
||||
ret.reserve(usrs.size());
|
||||
@ -135,7 +135,7 @@ void EachOccurrenceWithParent(QueryDatabase* db,
|
||||
}
|
||||
|
||||
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,
|
||||
Fn&& fn) {
|
||||
for (Usr usr : usrs) {
|
||||
|
@ -160,7 +160,7 @@ void Reflect(Writer& visitor, IndexInclude& value) {
|
||||
REFLECT_MEMBER_START();
|
||||
REFLECT_MEMBER(line);
|
||||
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, "&"))
|
||||
basename = "&" + basename;
|
||||
REFLECT_MEMBER2("resolved_path", basename);
|
||||
|
11
src/utils.cc
11
src/utils.cc
@ -1,6 +1,7 @@
|
||||
#include "utils.h"
|
||||
|
||||
#include "filesystem.hh"
|
||||
using namespace llvm;
|
||||
#include "platform.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::error_code ec;
|
||||
auto ftime = fs::last_write_time(filename, ec);
|
||||
if (ec) return std::nullopt;
|
||||
return std::chrono::time_point_cast<std::chrono::nanoseconds>(ftime)
|
||||
.time_since_epoch()
|
||||
.count();
|
||||
sys::fs::file_status Status;
|
||||
if (sys::fs::status(filename, Status))
|
||||
return {};
|
||||
return Status.getLastModificationTime().time_since_epoch().count();
|
||||
}
|
||||
|
||||
std::string GetDefaultResourceDirectory() {
|
||||
|
1
third_party/sparsepp
vendored
1
third_party/sparsepp
vendored
@ -1 +0,0 @@
|
||||
Subproject commit 1ca7189fe81ee8c59bf08196852f70843a68a63a
|
Loading…
Reference in New Issue
Block a user