Drop support for LLVM 7, 8, and 9

This commit is contained in:
Fangrui Song 2024-11-01 23:26:56 -07:00
parent 192a82ba85
commit 50fd8d069e
14 changed files with 4 additions and 540 deletions

View File

@ -201,7 +201,6 @@ target_sources(ccls PRIVATE
src/filesystem.cc
src/fuzzy_match.cc
src/main.cc
src/include_complete.cc
src/indexer.cc
src/log.cc
src/lsp.cc

View File

@ -163,12 +163,7 @@ buildCompilerInvocation(const std::string &main, std::vector<const char *> args,
return nullptr;
const llvm::opt::ArgStringList &cc_args = cmd.getArguments();
auto ci = std::make_unique<CompilerInvocation>();
#if LLVM_VERSION_MAJOR >= 10 // rC370122
if (!CompilerInvocation::CreateFromArgs(*ci, cc_args, *diags))
#else
if (!CompilerInvocation::CreateFromArgs(
*ci, cc_args.data(), cc_args.data() + cc_args.size(), *diags))
#endif
return nullptr;
ci->getDiagnosticOpts().IgnoreWarnings = true;
@ -189,9 +184,7 @@ buildCompilerInvocation(const std::string &main, std::vector<const char *> args,
auto &isec = ci->getFrontendOpts().Inputs;
if (isec.size())
isec[0] = FrontendInputFile(main, isec[0].getKind(), isec[0].isSystem());
#if LLVM_VERSION_MAJOR >= 10 // llvmorg-11-init-2414-g75f09b54429
ci->getPreprocessorOpts().DisablePragmaDebugCrash = true;
#endif
// clangSerialization has an unstable format. Disable PCH reading/writing
// to work around PCH mismatch problems.
ci->getPreprocessorOpts().ImplicitPCHInclude.clear();

View File

@ -10,13 +10,6 @@
#include <clang/Basic/SourceManager.h>
#include <clang/Frontend/CompilerInstance.h>
#if LLVM_VERSION_MAJOR < 8
// D52783 Lift VFS from clang to llvm
namespace llvm {
namespace vfs = clang::vfs;
}
#endif
#if LLVM_VERSION_MAJOR < 14 // llvmorg-14-init-3863-g601102d282d5
#define isAsciiIdentifierContinue isIdentifierBody
#endif

View File

@ -1,185 +0,0 @@
// Copyright 2017-2018 ccls Authors
// SPDX-License-Identifier: Apache-2.0
#include "include_complete.hh"
#include "filesystem.hh"
#include "platform.hh"
#include "project.hh"
#include <llvm/ADT/Twine.h>
#include <llvm/Support/Threading.h>
#include <llvm/Support/Timer.h>
#include <unordered_set>
using namespace llvm;
#include <thread>
namespace ccls {
namespace {
struct CompletionCandidate {
std::string absolute_path;
CompletionItem completion_item;
};
std::string elideLongPath(const std::string &path) {
if (g_config->completion.include.maxPathSize <= 0 ||
(int)path.size() <= g_config->completion.include.maxPathSize)
return path;
size_t start = path.size() - g_config->completion.include.maxPathSize;
return ".." + path.substr(start + 2);
}
size_t trimCommonPathPrefix(const std::string &result,
const std::string &trimmer) {
#ifdef _WIN32
std::string s = result, t = trimmer;
std::transform(s.begin(), s.end(), s.begin(), ::tolower);
std::transform(t.begin(), t.end(), t.begin(), ::tolower);
if (s.compare(0, t.size(), t) == 0)
return t.size();
#else
if (result.compare(0, trimmer.size(), trimmer) == 0)
return trimmer.size();
#endif
return 0;
}
int trimPath(Project *project, std::string &path) {
size_t pos = 0;
int kind = 0;
for (auto &[root, folder] : project->root2folder)
for (auto &[search, search_dir_kind] : folder.search_dir2kind)
if (int t = trimCommonPathPrefix(path, search); t > pos)
pos = t, kind = search_dir_kind;
path = path.substr(pos);
return kind;
}
CompletionItem buildCompletionItem(const std::string &path, int kind) {
CompletionItem item;
item.label = elideLongPath(path);
item.detail = path; // the include path, used in de-duplicating
item.textEdit.newText = path;
item.insertTextFormat = InsertTextFormat::PlainText;
item.kind = CompletionItemKind::File;
item.quote_kind_ = kind;
item.priority_ = 0;
return item;
}
} // namespace
IncludeComplete::IncludeComplete(Project *project)
: is_scanning(false), project_(project) {}
IncludeComplete::~IncludeComplete() {
// Spin until the scanning has completed.
while (is_scanning.load())
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
void IncludeComplete::rescan() {
if (is_scanning || LLVM_VERSION_MAJOR >= 8)
return;
completion_items.clear();
absolute_path_to_completion_item.clear();
inserted_paths.clear();
if (!match_ && (g_config->completion.include.whitelist.size() ||
g_config->completion.include.blacklist.size()))
match_ =
std::make_unique<GroupMatch>(g_config->completion.include.whitelist,
g_config->completion.include.blacklist);
is_scanning = true;
std::thread([this]() {
set_thread_name("include");
for (auto &[root, folder] : project_->root2folder) {
for (auto &search_kind : folder.search_dir2kind) {
const std::string &search = search_kind.first;
int kind = search_kind.second;
assert(search.back() == '/');
if (match_ && !match_->matches(search))
return;
bool include_cpp = search.find("include/c++") != std::string::npos;
std::vector<CompletionCandidate> results;
getFilesInFolder(
search, true /*recursive*/, false /*add_folder_to_path*/,
[&](const std::string &path) {
bool ok = include_cpp;
for (StringRef suffix :
g_config->completion.include.suffixWhitelist)
if (StringRef(path).endswith(suffix))
ok = true;
if (!ok)
return;
if (match_ && !match_->matches(search + path))
return;
CompletionCandidate candidate;
candidate.absolute_path = search + path;
candidate.completion_item = buildCompletionItem(path, kind);
results.push_back(candidate);
});
std::lock_guard lock(completion_items_mutex);
for (CompletionCandidate &result : results)
insertCompletionItem(result.absolute_path,
std::move(result.completion_item));
}
}
is_scanning = false;
}).detach();
}
void IncludeComplete::insertCompletionItem(const std::string &absolute_path,
CompletionItem &&item) {
if (inserted_paths.try_emplace(item.detail, inserted_paths.size()).second) {
completion_items.push_back(item);
// insert if not found or with shorter include path
auto it = absolute_path_to_completion_item.find(absolute_path);
if (it == absolute_path_to_completion_item.end() ||
completion_items[it->second].detail.length() > item.detail.length()) {
absolute_path_to_completion_item[absolute_path] =
completion_items.size() - 1;
}
}
}
void IncludeComplete::addFile(const std::string &path) {
bool ok = false;
for (StringRef suffix : g_config->completion.include.suffixWhitelist)
if (StringRef(path).endswith(suffix))
ok = true;
if (!ok)
return;
if (match_ && !match_->matches(path))
return;
std::string trimmed_path = path;
int kind = trimPath(project_, trimmed_path);
CompletionItem item = buildCompletionItem(trimmed_path, kind);
std::unique_lock<std::mutex> lock(completion_items_mutex, std::defer_lock);
if (is_scanning)
lock.lock();
insertCompletionItem(path, std::move(item));
}
std::optional<CompletionItem>
IncludeComplete::findCompletionItemForAbsolutePath(
const std::string &absolute_path) {
std::lock_guard<std::mutex> lock(completion_items_mutex);
auto it = absolute_path_to_completion_item.find(absolute_path);
if (it == absolute_path_to_completion_item.end())
return std::nullopt;
return completion_items[it->second];
}
} // namespace ccls

View File

@ -1,49 +0,0 @@
// Copyright 2017-2018 ccls Authors
// SPDX-License-Identifier: Apache-2.0
#pragma once
#include "message_handler.hh"
#include <atomic>
#include <mutex>
namespace ccls {
struct GroupMatch;
struct Project;
struct IncludeComplete {
IncludeComplete(Project *project);
~IncludeComplete();
// Starts scanning directories. Clears existing cache.
void rescan();
// Ensures the one-off file is inside |completion_items|.
void addFile(const std::string &absolute_path);
std::optional<ccls::CompletionItem>
findCompletionItemForAbsolutePath(const std::string &absolute_path);
// Insert item to |completion_items|.
// Update |absolute_path_to_completion_item| and |inserted_paths|.
void insertCompletionItem(const std::string &absolute_path,
ccls::CompletionItem &&item);
// Guards |completion_items| when |is_scanning| is true.
std::mutex completion_items_mutex;
std::atomic<bool> is_scanning;
std::vector<ccls::CompletionItem> completion_items;
// Absolute file path to the completion item in |completion_items|.
// Keep the one with shortest include path.
std::unordered_map<std::string, int> absolute_path_to_completion_item;
// Only one completion item per include path.
std::unordered_map<std::string, int> inserted_paths;
// Cached references
Project *project_;
std::unique_ptr<GroupMatch> match_;
};
} // namespace ccls

View File

@ -710,9 +710,6 @@ public:
public:
IndexDataConsumer(IndexParam &param) : param(param) {}
void initialize(ASTContext &ctx) override { this->ctx = param.ctx = &ctx; }
#if LLVM_VERSION_MAJOR < 10 // llvmorg-10-init-12036-g3b9715cb219
# define handleDeclOccurrence handleDeclOccurence
#endif
bool handleDeclOccurrence(const Decl *d, index::SymbolRoleSet roles,
ArrayRef<index::SymbolRelation> relations,
SourceLocation src_loc,
@ -899,31 +896,6 @@ public:
if (!isa<EnumConstantDecl>(d))
db->toType(usr1).instances.push_back(usr);
} else if (const Decl *d1 = getAdjustedDecl(getTypeDecl(t))) {
#if LLVM_VERSION_MAJOR < 9
if (isa<TemplateTypeParmDecl>(d1)) {
// e.g. TemplateTypeParmDecl is not handled by
// handleDeclOccurence.
SourceRange sr1 = d1->getSourceRange();
if (sm.getFileID(sr1.getBegin()) == fid) {
IndexParam::DeclInfo *info1;
Usr usr1 = getUsr(d1, &info1);
IndexType &type1 = db->toType(usr1);
SourceLocation sl1 = d1->getLocation();
type1.def.spell = {
Use{{fromTokenRange(sm, lang, {sl1, sl1}), Role::Definition},
lid},
fromTokenRange(sm, lang, sr1)};
type1.def.detailed_name = intern(info1->short_name);
type1.def.short_name_size = int16_t(info1->short_name.size());
type1.def.kind = SymbolKind::TypeParameter;
type1.def.parent_kind = SymbolKind::Class;
var->def.type = usr1;
type1.instances.push_back(usr);
break;
}
}
#endif
IndexParam::DeclInfo *info1;
Usr usr1 = getUsr(d1, &info1);
var->def.type = usr1;
@ -1237,10 +1209,8 @@ public:
std::make_unique<IndexPPCallbacks>(pp->getSourceManager(), param));
std::vector<std::unique_ptr<ASTConsumer>> consumers;
consumers.push_back(std::make_unique<SkipProcessed>(param));
#if LLVM_VERSION_MAJOR >= 10 // rC370337
consumers.push_back(index::createIndexingASTConsumer(
dataConsumer, indexOpts, std::move(pp)));
#endif
return std::make_unique<MultiplexConsumer>(std::move(consumers));
}
};
@ -1349,12 +1319,7 @@ index(SemaManager *manager, WorkingFiles *wfiles, VFS *vfs,
if (!clang->hasTarget())
return {};
clang->getPreprocessorOpts().RetainRemappedFileBuffers = true;
#if LLVM_VERSION_MAJOR >= 9 // rC357037
clang->createFileManager(fs);
#else
clang->setVirtualFileSystem(fs);
clang->createFileManager();
#endif
clang->setSourceManager(new SourceManager(clang->getDiagnostics(),
clang->getFileManager(), true));
@ -1366,39 +1331,23 @@ index(SemaManager *manager, WorkingFiles *wfiles, VFS *vfs,
if (no_linkage) {
indexOpts.IndexFunctionLocals = true;
indexOpts.IndexImplicitInstantiation = true;
#if LLVM_VERSION_MAJOR >= 9
indexOpts.IndexParametersInDeclarations =
g_config->index.parametersInDeclarations;
indexOpts.IndexTemplateParameters = true;
#endif
}
#if LLVM_VERSION_MAJOR >= 10 // rC370337
auto action = std::make_unique<IndexFrontendAction>(
std::make_shared<IndexDataConsumer>(param), indexOpts, param);
#else
auto dataConsumer = std::make_shared<IndexDataConsumer>(param);
auto action = createIndexingAction(
dataConsumer, indexOpts,
std::make_unique<IndexFrontendAction>(dataConsumer, indexOpts, param));
#endif
std::string reason;
{
llvm::CrashRecoveryContext crc;
auto parse = [&]() {
if (!action->BeginSourceFile(*clang, clang->getFrontendOpts().Inputs[0]))
return;
#if LLVM_VERSION_MAJOR >= 9 // rL364464
if (llvm::Error e = action->Execute()) {
reason = llvm::toString(std::move(e));
return;
}
#else
if (!action->Execute())
return;
#endif
action->EndSourceFile();
ok = true;
};

View File

@ -14,7 +14,6 @@
namespace ccls {
struct SemaManager;
struct VFS;
struct IncludeComplete;
struct Project;
struct WorkingFile;
struct WorkingFiles;
@ -239,7 +238,6 @@ struct ReplyOnce {
struct MessageHandler {
SemaManager *manager = nullptr;
DB *db = nullptr;
IncludeComplete *include_complete = nullptr;
Project *project = nullptr;
VFS *vfs = nullptr;
WorkingFiles *wfiles = nullptr;

View File

@ -2,7 +2,6 @@
// SPDX-License-Identifier: Apache-2.0
#include "filesystem.hh"
#include "include_complete.hh"
#include "log.hh"
#include "message_handler.hh"
#include "pipeline.hh"
@ -261,7 +260,7 @@ void *indexer(void *arg_) {
// Don't lower priority on __APPLE__. getpriority(2) says "When setting a
// thread into background state the scheduling priority is set to lowest
// value, disk and network IO are throttled."
#if LLVM_ENABLE_THREADS && LLVM_VERSION_MAJOR >= 9 && !defined(__APPLE__)
#if LLVM_ENABLE_THREADS && !defined(__APPLE__)
set_thread_priority(ThreadPriority::Background);
#endif
pipeline::indexer_Main(h->manager, h->vfs, h->project, h->wfiles);
@ -389,10 +388,6 @@ void do_initialize(MessageHandler *m, InitializeParam &param,
for (int i = 0; i < g_config->index.threads; i++)
spawnThread(indexer, new std::pair<MessageHandler *, int>{m, i});
// Start scanning include directories before dispatching project
// files, because that takes a long time.
m->include_complete->rescan();
LOG_S(INFO) << "dispatch initial index requests";
m->project->index(m->wfiles, reply.id);

View File

@ -2,7 +2,6 @@
// SPDX-License-Identifier: Apache-2.0
#include "fuzzy_match.hh"
#include "include_complete.hh"
#include "log.hh"
#include "message_handler.hh"
#include "pipeline.hh"
@ -13,10 +12,6 @@
#include <clang/Sema/Sema.h>
#include <llvm/ADT/Twine.h>
#if LLVM_VERSION_MAJOR < 8
#include <regex>
#endif
#if LLVM_VERSION_MAJOR >= 18 // llvmorg-18-init-10631-gedd690b02e16
#define TTK_Struct TagTypeKind::Struct
#endif
@ -52,54 +47,6 @@ struct CompletionList {
};
REFLECT_STRUCT(CompletionList, isIncomplete, items);
#if LLVM_VERSION_MAJOR < 8
void decorateIncludePaths(const std::smatch &match,
std::vector<CompletionItem> *items, char quote) {
std::string spaces_after_include = " ";
if (match[3].compare("include") == 0 && quote != '\0')
spaces_after_include = match[4].str();
std::string prefix =
match[1].str() + '#' + match[2].str() + "include" + spaces_after_include;
std::string suffix = match[7].str();
for (CompletionItem &item : *items) {
char quote0, quote1;
if (quote != '"')
quote0 = '<', quote1 = '>';
else
quote0 = quote1 = '"';
item.textEdit.newText =
prefix + quote0 + item.textEdit.newText + quote1 + suffix;
item.label = prefix + quote0 + item.label + quote1 + suffix;
}
}
struct ParseIncludeLineResult {
bool ok;
std::string keyword;
std::string quote;
std::string pattern;
std::smatch match;
};
ParseIncludeLineResult ParseIncludeLine(const std::string &line) {
static const std::regex pattern("(\\s*)" // [1]: spaces before '#'
"#" //
"(\\s*)" // [2]: spaces after '#'
"([^\\s\"<]*)" // [3]: "include"
"(\\s*)" // [4]: spaces before quote
"([\"<])?" // [5]: the first quote char
"([^\\s\">]*)" // [6]: path of file
"[\">]?" //
"(.*)"); // [7]: suffix after quote char
std::smatch match;
bool ok = std::regex_match(line, match, pattern);
return {ok, match[3], match[5], match[6], match};
}
#endif
// Pre-filters completion responses before sending to vscode. This results in a
// significantly snappier completion experience as vscode is easily overloaded
// when given 1000+ completion items.
@ -309,10 +256,8 @@ CompletionItemKind getCompletionKind(CodeCompletionContext::Kind k,
case CodeCompletionResult::RK_Macro:
return CompletionItemKind::Reference;
case CodeCompletionResult::RK_Pattern:
#if LLVM_VERSION_MAJOR >= 8
if (k == CodeCompletionContext::CCC_IncludedFile)
return CompletionItemKind::File;
#endif
return CompletionItemKind::Snippet;
}
}
@ -402,11 +347,7 @@ public:
CompletionConsumer(const CodeCompleteOptions &opts, bool from_cache)
:
#if LLVM_VERSION_MAJOR >= 9 // rC358696
CodeCompleteConsumer(opts),
#else
CodeCompleteConsumer(opts, false),
#endif
alloc(std::make_shared<clang::GlobalCodeCompletionAllocator>()),
cctu_info(alloc), from_cache(from_cache) {
}
@ -544,31 +485,6 @@ void MessageHandler::textDocument_completion(CompletionParam &param,
Position end_pos = param.position;
Position begin_pos = wf->getCompletionPosition(param.position, &filter);
#if LLVM_VERSION_MAJOR < 8
ParseIncludeLineResult preprocess = ParseIncludeLine(buffer_line);
if (preprocess.ok && preprocess.keyword.compare("include") == 0) {
CompletionList result;
char quote = std::string(preprocess.match[5])[0];
{
std::unique_lock<std::mutex> lock(
include_complete->completion_items_mutex, std::defer_lock);
if (include_complete->is_scanning)
lock.lock();
for (auto &item : include_complete->completion_items)
if (quote == '\0' || (item.quote_kind_ & 1 && quote == '"') ||
(item.quote_kind_ & 2 && quote == '<'))
result.items.push_back(item);
}
begin_pos.character = 0;
end_pos.character = (int)buffer_line.size();
filterCandidates(result, preprocess.pattern, begin_pos, end_pos,
buffer_line);
decorateIncludePaths(preprocess.match, &result.items, quote);
reply(result);
return;
}
#endif
SemaManager::OnComplete callback =
[filter, path, begin_pos, end_pos, reply,
buffer_line](CodeCompleteConsumer *optConsumer) {

View File

@ -1,7 +1,6 @@
// Copyright 2017-2018 ccls Authors
// SPDX-License-Identifier: Apache-2.0
#include "include_complete.hh"
#include "message_handler.hh"
#include "pipeline.hh"
#include "project.hh"
@ -38,7 +37,6 @@ void MessageHandler::textDocument_didOpen(DidOpenTextDocumentParam &param) {
emitSkippedRanges(wf, *file);
emitSemanticHighlight(db, wf, *file);
}
include_complete->addFile(wf->filename);
// Submit new index request if it is not a header file or there is no
// pending index request.

View File

@ -65,22 +65,10 @@ public:
bool from_cache;
SignatureHelp ls_sighelp;
SignatureHelpConsumer(const clang::CodeCompleteOptions &opts, bool from_cache)
:
#if LLVM_VERSION_MAJOR >= 9 // rC358696
CodeCompleteConsumer(opts),
#else
CodeCompleteConsumer(opts, false),
#endif
alloc(std::make_shared<GlobalCodeCompletionAllocator>()),
cCTUInfo(alloc), from_cache(from_cache) {
}
void ProcessOverloadCandidates(Sema &s, unsigned currentArg,
OverloadCandidate *candidates,
unsigned numCandidates
#if LLVM_VERSION_MAJOR >= 8
,
: CodeCompleteConsumer(opts), alloc(std::make_shared<GlobalCodeCompletionAllocator>()), cCTUInfo(alloc),
from_cache(from_cache) {}
void ProcessOverloadCandidates(Sema &s, unsigned currentArg, OverloadCandidate *candidates, unsigned numCandidates,
SourceLocation openParLoc
#endif
#if LLVM_VERSION_MAJOR >= 14
,
bool braced

View File

@ -4,7 +4,6 @@
#include "pipeline.hh"
#include "config.hh"
#include "include_complete.hh"
#include "log.hh"
#include "lsp.hh"
#include "message_handler.hh"
@ -657,7 +656,6 @@ void mainLoop() {
}
});
IncludeComplete include_complete(&project);
DB db;
// Setup shared references.
@ -667,7 +665,6 @@ void mainLoop() {
handler.vfs = &vfs;
handler.wfiles = &wfiles;
handler.manager = &manager;
handler.include_complete = &include_complete;
bool work_done_created = false, in_progress = false;
bool has_indexed = false;
@ -787,14 +784,12 @@ void standalone(const std::string &root) {
nullptr, nullptr,
[](const std::string &, const std::vector<Diagnostic> &) {},
[](const RequestId &id) {});
IncludeComplete complete(&project);
MessageHandler handler;
handler.project = &project;
handler.wfiles = &wfiles;
handler.vfs = &vfs;
handler.manager = &manager;
handler.include_complete = &complete;
standaloneInitialize(handler, root);
bool tty = sys::Process::StandardOutIsDisplayed();

View File

@ -134,88 +134,6 @@ struct ProjectProcessor {
}
}
entry.args = args;
getSearchDirs(entry);
}
void getSearchDirs(Project::Entry &entry) {
#if LLVM_VERSION_MAJOR < 8
const std::string base_name = sys::path::filename(entry.filename);
size_t hash = std::hash<std::string>{}(entry.directory);
bool OPT_o = false;
for (auto &arg : entry.args) {
bool last_o = OPT_o;
OPT_o = false;
if (arg[0] == '-') {
OPT_o = arg[1] == 'o' && arg[2] == '\0';
if (OPT_o || arg[1] == 'D' || arg[1] == 'W')
continue;
} else if (last_o) {
continue;
} else if (sys::path::filename(arg) == base_name) {
LanguageId lang = lookupExtension(arg).first;
if (lang != LanguageId::Unknown) {
hash_combine(hash, (size_t)lang);
continue;
}
}
hash_combine(hash, std::hash<std::string_view>{}(arg));
}
if (!command_set.insert(hash).second)
return;
auto args = entry.args;
args.push_back("-fsyntax-only");
for (const std::string &arg : g_config->clang.extraArgs)
args.push_back(intern(arg));
args.push_back(intern("-working-directory=" + entry.directory));
args.push_back(intern("-resource-dir=" + g_config->clang.resourceDir));
// a weird C++ deduction guide heap-use-after-free causes libclang to crash.
IgnoringDiagConsumer DiagC;
IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts(new DiagnosticOptions());
DiagnosticsEngine Diags(
IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs()), &*DiagOpts,
&DiagC, false);
driver::Driver Driver(args[0], llvm::sys::getDefaultTargetTriple(), Diags);
auto TargetAndMode =
driver::ToolChain::getTargetAndModeFromProgramName(args[0]);
if (!TargetAndMode.TargetPrefix.empty()) {
const char *arr[] = {"-target", TargetAndMode.TargetPrefix.c_str()};
args.insert(args.begin() + 1, std::begin(arr), std::end(arr));
Driver.setTargetAndMode(TargetAndMode);
}
Driver.setCheckInputsExist(false);
std::unique_ptr<driver::Compilation> C(Driver.BuildCompilation(args));
const driver::JobList &Jobs = C->getJobs();
if (Jobs.size() != 1)
return;
const auto &CCArgs = Jobs.begin()->getArguments();
auto CI = std::make_unique<CompilerInvocation>();
CompilerInvocation::CreateFromArgs(*CI, CCArgs.data(),
CCArgs.data() + CCArgs.size(), Diags);
CI->getFrontendOpts().DisableFree = false;
CI->getCodeGenOpts().DisableFree = false;
HeaderSearchOptions &HeaderOpts = CI->getHeaderSearchOpts();
for (auto &E : HeaderOpts.UserEntries) {
std::string path =
normalizePath(resolveIfRelative(entry.directory, E.Path));
ensureEndsInSlash(path);
switch (E.Group) {
default:
folder.search_dir2kind[path] |= 2;
break;
case frontend::Quoted:
folder.search_dir2kind[path] |= 1;
break;
case frontend::Angled:
folder.search_dir2kind[path] |= 3;
break;
}
}
#endif
}
};
@ -452,7 +370,6 @@ void Project::loadDirectory(const std::string &root, Project::Folder &folder) {
entry.args.push_back(intern(args[i]));
}
entry.compdb_size = entry.args.size();
proc.getSearchDirs(entry);
if (seen.insert(entry.filename).second)
folder.entries.push_back(entry);
}

View File

@ -26,39 +26,6 @@ using namespace llvm;
#include <thread>
namespace chrono = std::chrono;
#if LLVM_VERSION_MAJOR < 8
namespace clang::vfs {
struct ProxyFileSystem : FileSystem {
explicit ProxyFileSystem(IntrusiveRefCntPtr<FileSystem> FS)
: FS(std::move(FS)) {}
llvm::ErrorOr<Status> status(const Twine &Path) override {
return FS->status(Path);
}
llvm::ErrorOr<std::unique_ptr<File>>
openFileForRead(const Twine &Path) override {
return FS->openFileForRead(Path);
}
directory_iterator dir_begin(const Twine &Dir, std::error_code &EC) override {
return FS->dir_begin(Dir, EC);
}
llvm::ErrorOr<std::string> getCurrentWorkingDirectory() const override {
return FS->getCurrentWorkingDirectory();
}
std::error_code setCurrentWorkingDirectory(const Twine &Path) override {
return FS->setCurrentWorkingDirectory(Path);
}
#if LLVM_VERSION_MAJOR == 7
std::error_code getRealPath(const Twine &Path,
SmallVectorImpl<char> &Output) const override {
return FS->getRealPath(Path, Output);
}
#endif
FileSystem &getUnderlyingFS() { return *FS; }
IntrusiveRefCntPtr<FileSystem> FS;
};
} // namespace clang::vfs
#endif
namespace ccls {
TextEdit toTextEdit(const clang::SourceManager &sm, const clang::LangOptions &l,
@ -330,12 +297,7 @@ buildCompilerInstance(Session &session, std::unique_ptr<CompilerInvocation> ci,
// Construct SourceManager with UserFilesAreVolatile: true because otherwise
// RequiresNullTerminator: true may cause out-of-bounds read when a file is
// mmap'ed but is saved concurrently.
#if LLVM_VERSION_MAJOR >= 9 // rC357037
clang->createFileManager(fs);
#else
clang->setVirtualFileSystem(fs);
clang->createFileManager();
#endif
clang->setSourceManager(new SourceManager(clang->getDiagnostics(),
clang->getFileManager(), true));
auto &isec = clang->getFrontendOpts().Inputs;
@ -353,15 +315,10 @@ bool parse(CompilerInstance &clang) {
auto run = [&]() {
if (!action.BeginSourceFile(clang, clang.getFrontendOpts().Inputs[0]))
return;
#if LLVM_VERSION_MAJOR >= 9 // rL364464
if (llvm::Error e = action.Execute()) {
llvm::consumeError(std::move(e));
return;
}
#else
if (!action.Execute())
return;
#endif
action.EndSourceFile();
ok = true;
};