mirror of
https://github.com/MaskRay/ccls.git
synced 2024-11-27 01:51:57 +00:00
Drop support for LLVM 7, 8, and 9
This commit is contained in:
parent
192a82ba85
commit
50fd8d069e
@ -201,7 +201,6 @@ target_sources(ccls PRIVATE
|
|||||||
src/filesystem.cc
|
src/filesystem.cc
|
||||||
src/fuzzy_match.cc
|
src/fuzzy_match.cc
|
||||||
src/main.cc
|
src/main.cc
|
||||||
src/include_complete.cc
|
|
||||||
src/indexer.cc
|
src/indexer.cc
|
||||||
src/log.cc
|
src/log.cc
|
||||||
src/lsp.cc
|
src/lsp.cc
|
||||||
|
@ -163,12 +163,7 @@ buildCompilerInvocation(const std::string &main, std::vector<const char *> args,
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
const llvm::opt::ArgStringList &cc_args = cmd.getArguments();
|
const llvm::opt::ArgStringList &cc_args = cmd.getArguments();
|
||||||
auto ci = std::make_unique<CompilerInvocation>();
|
auto ci = std::make_unique<CompilerInvocation>();
|
||||||
#if LLVM_VERSION_MAJOR >= 10 // rC370122
|
|
||||||
if (!CompilerInvocation::CreateFromArgs(*ci, cc_args, *diags))
|
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;
|
return nullptr;
|
||||||
|
|
||||||
ci->getDiagnosticOpts().IgnoreWarnings = true;
|
ci->getDiagnosticOpts().IgnoreWarnings = true;
|
||||||
@ -189,9 +184,7 @@ buildCompilerInvocation(const std::string &main, std::vector<const char *> args,
|
|||||||
auto &isec = ci->getFrontendOpts().Inputs;
|
auto &isec = ci->getFrontendOpts().Inputs;
|
||||||
if (isec.size())
|
if (isec.size())
|
||||||
isec[0] = FrontendInputFile(main, isec[0].getKind(), isec[0].isSystem());
|
isec[0] = FrontendInputFile(main, isec[0].getKind(), isec[0].isSystem());
|
||||||
#if LLVM_VERSION_MAJOR >= 10 // llvmorg-11-init-2414-g75f09b54429
|
|
||||||
ci->getPreprocessorOpts().DisablePragmaDebugCrash = true;
|
ci->getPreprocessorOpts().DisablePragmaDebugCrash = true;
|
||||||
#endif
|
|
||||||
// clangSerialization has an unstable format. Disable PCH reading/writing
|
// clangSerialization has an unstable format. Disable PCH reading/writing
|
||||||
// to work around PCH mismatch problems.
|
// to work around PCH mismatch problems.
|
||||||
ci->getPreprocessorOpts().ImplicitPCHInclude.clear();
|
ci->getPreprocessorOpts().ImplicitPCHInclude.clear();
|
||||||
|
@ -10,13 +10,6 @@
|
|||||||
#include <clang/Basic/SourceManager.h>
|
#include <clang/Basic/SourceManager.h>
|
||||||
#include <clang/Frontend/CompilerInstance.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
|
#if LLVM_VERSION_MAJOR < 14 // llvmorg-14-init-3863-g601102d282d5
|
||||||
#define isAsciiIdentifierContinue isIdentifierBody
|
#define isAsciiIdentifierContinue isIdentifierBody
|
||||||
#endif
|
#endif
|
||||||
|
@ -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
|
|
@ -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
|
|
@ -710,9 +710,6 @@ public:
|
|||||||
public:
|
public:
|
||||||
IndexDataConsumer(IndexParam ¶m) : param(param) {}
|
IndexDataConsumer(IndexParam ¶m) : param(param) {}
|
||||||
void initialize(ASTContext &ctx) override { this->ctx = param.ctx = &ctx; }
|
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,
|
bool handleDeclOccurrence(const Decl *d, index::SymbolRoleSet roles,
|
||||||
ArrayRef<index::SymbolRelation> relations,
|
ArrayRef<index::SymbolRelation> relations,
|
||||||
SourceLocation src_loc,
|
SourceLocation src_loc,
|
||||||
@ -899,31 +896,6 @@ public:
|
|||||||
if (!isa<EnumConstantDecl>(d))
|
if (!isa<EnumConstantDecl>(d))
|
||||||
db->toType(usr1).instances.push_back(usr);
|
db->toType(usr1).instances.push_back(usr);
|
||||||
} else if (const Decl *d1 = getAdjustedDecl(getTypeDecl(t))) {
|
} 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;
|
IndexParam::DeclInfo *info1;
|
||||||
Usr usr1 = getUsr(d1, &info1);
|
Usr usr1 = getUsr(d1, &info1);
|
||||||
var->def.type = usr1;
|
var->def.type = usr1;
|
||||||
@ -1237,10 +1209,8 @@ public:
|
|||||||
std::make_unique<IndexPPCallbacks>(pp->getSourceManager(), param));
|
std::make_unique<IndexPPCallbacks>(pp->getSourceManager(), param));
|
||||||
std::vector<std::unique_ptr<ASTConsumer>> consumers;
|
std::vector<std::unique_ptr<ASTConsumer>> consumers;
|
||||||
consumers.push_back(std::make_unique<SkipProcessed>(param));
|
consumers.push_back(std::make_unique<SkipProcessed>(param));
|
||||||
#if LLVM_VERSION_MAJOR >= 10 // rC370337
|
|
||||||
consumers.push_back(index::createIndexingASTConsumer(
|
consumers.push_back(index::createIndexingASTConsumer(
|
||||||
dataConsumer, indexOpts, std::move(pp)));
|
dataConsumer, indexOpts, std::move(pp)));
|
||||||
#endif
|
|
||||||
return std::make_unique<MultiplexConsumer>(std::move(consumers));
|
return std::make_unique<MultiplexConsumer>(std::move(consumers));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -1349,12 +1319,7 @@ index(SemaManager *manager, WorkingFiles *wfiles, VFS *vfs,
|
|||||||
if (!clang->hasTarget())
|
if (!clang->hasTarget())
|
||||||
return {};
|
return {};
|
||||||
clang->getPreprocessorOpts().RetainRemappedFileBuffers = true;
|
clang->getPreprocessorOpts().RetainRemappedFileBuffers = true;
|
||||||
#if LLVM_VERSION_MAJOR >= 9 // rC357037
|
|
||||||
clang->createFileManager(fs);
|
clang->createFileManager(fs);
|
||||||
#else
|
|
||||||
clang->setVirtualFileSystem(fs);
|
|
||||||
clang->createFileManager();
|
|
||||||
#endif
|
|
||||||
clang->setSourceManager(new SourceManager(clang->getDiagnostics(),
|
clang->setSourceManager(new SourceManager(clang->getDiagnostics(),
|
||||||
clang->getFileManager(), true));
|
clang->getFileManager(), true));
|
||||||
|
|
||||||
@ -1366,39 +1331,23 @@ index(SemaManager *manager, WorkingFiles *wfiles, VFS *vfs,
|
|||||||
if (no_linkage) {
|
if (no_linkage) {
|
||||||
indexOpts.IndexFunctionLocals = true;
|
indexOpts.IndexFunctionLocals = true;
|
||||||
indexOpts.IndexImplicitInstantiation = true;
|
indexOpts.IndexImplicitInstantiation = true;
|
||||||
#if LLVM_VERSION_MAJOR >= 9
|
|
||||||
|
|
||||||
indexOpts.IndexParametersInDeclarations =
|
indexOpts.IndexParametersInDeclarations =
|
||||||
g_config->index.parametersInDeclarations;
|
g_config->index.parametersInDeclarations;
|
||||||
indexOpts.IndexTemplateParameters = true;
|
indexOpts.IndexTemplateParameters = true;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LLVM_VERSION_MAJOR >= 10 // rC370337
|
|
||||||
auto action = std::make_unique<IndexFrontendAction>(
|
auto action = std::make_unique<IndexFrontendAction>(
|
||||||
std::make_shared<IndexDataConsumer>(param), indexOpts, param);
|
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;
|
std::string reason;
|
||||||
{
|
{
|
||||||
llvm::CrashRecoveryContext crc;
|
llvm::CrashRecoveryContext crc;
|
||||||
auto parse = [&]() {
|
auto parse = [&]() {
|
||||||
if (!action->BeginSourceFile(*clang, clang->getFrontendOpts().Inputs[0]))
|
if (!action->BeginSourceFile(*clang, clang->getFrontendOpts().Inputs[0]))
|
||||||
return;
|
return;
|
||||||
#if LLVM_VERSION_MAJOR >= 9 // rL364464
|
|
||||||
if (llvm::Error e = action->Execute()) {
|
if (llvm::Error e = action->Execute()) {
|
||||||
reason = llvm::toString(std::move(e));
|
reason = llvm::toString(std::move(e));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
if (!action->Execute())
|
|
||||||
return;
|
|
||||||
#endif
|
|
||||||
action->EndSourceFile();
|
action->EndSourceFile();
|
||||||
ok = true;
|
ok = true;
|
||||||
};
|
};
|
||||||
|
@ -14,7 +14,6 @@
|
|||||||
namespace ccls {
|
namespace ccls {
|
||||||
struct SemaManager;
|
struct SemaManager;
|
||||||
struct VFS;
|
struct VFS;
|
||||||
struct IncludeComplete;
|
|
||||||
struct Project;
|
struct Project;
|
||||||
struct WorkingFile;
|
struct WorkingFile;
|
||||||
struct WorkingFiles;
|
struct WorkingFiles;
|
||||||
@ -239,7 +238,6 @@ struct ReplyOnce {
|
|||||||
struct MessageHandler {
|
struct MessageHandler {
|
||||||
SemaManager *manager = nullptr;
|
SemaManager *manager = nullptr;
|
||||||
DB *db = nullptr;
|
DB *db = nullptr;
|
||||||
IncludeComplete *include_complete = nullptr;
|
|
||||||
Project *project = nullptr;
|
Project *project = nullptr;
|
||||||
VFS *vfs = nullptr;
|
VFS *vfs = nullptr;
|
||||||
WorkingFiles *wfiles = nullptr;
|
WorkingFiles *wfiles = nullptr;
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
#include "filesystem.hh"
|
#include "filesystem.hh"
|
||||||
#include "include_complete.hh"
|
|
||||||
#include "log.hh"
|
#include "log.hh"
|
||||||
#include "message_handler.hh"
|
#include "message_handler.hh"
|
||||||
#include "pipeline.hh"
|
#include "pipeline.hh"
|
||||||
@ -261,7 +260,7 @@ void *indexer(void *arg_) {
|
|||||||
// Don't lower priority on __APPLE__. getpriority(2) says "When setting a
|
// Don't lower priority on __APPLE__. getpriority(2) says "When setting a
|
||||||
// thread into background state the scheduling priority is set to lowest
|
// thread into background state the scheduling priority is set to lowest
|
||||||
// value, disk and network IO are throttled."
|
// 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);
|
set_thread_priority(ThreadPriority::Background);
|
||||||
#endif
|
#endif
|
||||||
pipeline::indexer_Main(h->manager, h->vfs, h->project, h->wfiles);
|
pipeline::indexer_Main(h->manager, h->vfs, h->project, h->wfiles);
|
||||||
@ -389,10 +388,6 @@ void do_initialize(MessageHandler *m, InitializeParam ¶m,
|
|||||||
for (int i = 0; i < g_config->index.threads; i++)
|
for (int i = 0; i < g_config->index.threads; i++)
|
||||||
spawnThread(indexer, new std::pair<MessageHandler *, int>{m, 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";
|
LOG_S(INFO) << "dispatch initial index requests";
|
||||||
m->project->index(m->wfiles, reply.id);
|
m->project->index(m->wfiles, reply.id);
|
||||||
|
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
#include "fuzzy_match.hh"
|
#include "fuzzy_match.hh"
|
||||||
#include "include_complete.hh"
|
|
||||||
#include "log.hh"
|
#include "log.hh"
|
||||||
#include "message_handler.hh"
|
#include "message_handler.hh"
|
||||||
#include "pipeline.hh"
|
#include "pipeline.hh"
|
||||||
@ -13,10 +12,6 @@
|
|||||||
#include <clang/Sema/Sema.h>
|
#include <clang/Sema/Sema.h>
|
||||||
#include <llvm/ADT/Twine.h>
|
#include <llvm/ADT/Twine.h>
|
||||||
|
|
||||||
#if LLVM_VERSION_MAJOR < 8
|
|
||||||
#include <regex>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if LLVM_VERSION_MAJOR >= 18 // llvmorg-18-init-10631-gedd690b02e16
|
#if LLVM_VERSION_MAJOR >= 18 // llvmorg-18-init-10631-gedd690b02e16
|
||||||
#define TTK_Struct TagTypeKind::Struct
|
#define TTK_Struct TagTypeKind::Struct
|
||||||
#endif
|
#endif
|
||||||
@ -52,54 +47,6 @@ struct CompletionList {
|
|||||||
};
|
};
|
||||||
REFLECT_STRUCT(CompletionList, isIncomplete, items);
|
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
|
// Pre-filters completion responses before sending to vscode. This results in a
|
||||||
// significantly snappier completion experience as vscode is easily overloaded
|
// significantly snappier completion experience as vscode is easily overloaded
|
||||||
// when given 1000+ completion items.
|
// when given 1000+ completion items.
|
||||||
@ -309,10 +256,8 @@ CompletionItemKind getCompletionKind(CodeCompletionContext::Kind k,
|
|||||||
case CodeCompletionResult::RK_Macro:
|
case CodeCompletionResult::RK_Macro:
|
||||||
return CompletionItemKind::Reference;
|
return CompletionItemKind::Reference;
|
||||||
case CodeCompletionResult::RK_Pattern:
|
case CodeCompletionResult::RK_Pattern:
|
||||||
#if LLVM_VERSION_MAJOR >= 8
|
|
||||||
if (k == CodeCompletionContext::CCC_IncludedFile)
|
if (k == CodeCompletionContext::CCC_IncludedFile)
|
||||||
return CompletionItemKind::File;
|
return CompletionItemKind::File;
|
||||||
#endif
|
|
||||||
return CompletionItemKind::Snippet;
|
return CompletionItemKind::Snippet;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -402,11 +347,7 @@ public:
|
|||||||
|
|
||||||
CompletionConsumer(const CodeCompleteOptions &opts, bool from_cache)
|
CompletionConsumer(const CodeCompleteOptions &opts, bool from_cache)
|
||||||
:
|
:
|
||||||
#if LLVM_VERSION_MAJOR >= 9 // rC358696
|
|
||||||
CodeCompleteConsumer(opts),
|
CodeCompleteConsumer(opts),
|
||||||
#else
|
|
||||||
CodeCompleteConsumer(opts, false),
|
|
||||||
#endif
|
|
||||||
alloc(std::make_shared<clang::GlobalCodeCompletionAllocator>()),
|
alloc(std::make_shared<clang::GlobalCodeCompletionAllocator>()),
|
||||||
cctu_info(alloc), from_cache(from_cache) {
|
cctu_info(alloc), from_cache(from_cache) {
|
||||||
}
|
}
|
||||||
@ -544,31 +485,6 @@ void MessageHandler::textDocument_completion(CompletionParam ¶m,
|
|||||||
Position end_pos = param.position;
|
Position end_pos = param.position;
|
||||||
Position begin_pos = wf->getCompletionPosition(param.position, &filter);
|
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 =
|
SemaManager::OnComplete callback =
|
||||||
[filter, path, begin_pos, end_pos, reply,
|
[filter, path, begin_pos, end_pos, reply,
|
||||||
buffer_line](CodeCompleteConsumer *optConsumer) {
|
buffer_line](CodeCompleteConsumer *optConsumer) {
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
// Copyright 2017-2018 ccls Authors
|
// Copyright 2017-2018 ccls Authors
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
#include "include_complete.hh"
|
|
||||||
#include "message_handler.hh"
|
#include "message_handler.hh"
|
||||||
#include "pipeline.hh"
|
#include "pipeline.hh"
|
||||||
#include "project.hh"
|
#include "project.hh"
|
||||||
@ -38,7 +37,6 @@ void MessageHandler::textDocument_didOpen(DidOpenTextDocumentParam ¶m) {
|
|||||||
emitSkippedRanges(wf, *file);
|
emitSkippedRanges(wf, *file);
|
||||||
emitSemanticHighlight(db, 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
|
// Submit new index request if it is not a header file or there is no
|
||||||
// pending index request.
|
// pending index request.
|
||||||
|
@ -65,22 +65,10 @@ public:
|
|||||||
bool from_cache;
|
bool from_cache;
|
||||||
SignatureHelp ls_sighelp;
|
SignatureHelp ls_sighelp;
|
||||||
SignatureHelpConsumer(const clang::CodeCompleteOptions &opts, bool from_cache)
|
SignatureHelpConsumer(const clang::CodeCompleteOptions &opts, bool from_cache)
|
||||||
:
|
: CodeCompleteConsumer(opts), alloc(std::make_shared<GlobalCodeCompletionAllocator>()), cCTUInfo(alloc),
|
||||||
#if LLVM_VERSION_MAJOR >= 9 // rC358696
|
from_cache(from_cache) {}
|
||||||
CodeCompleteConsumer(opts),
|
void ProcessOverloadCandidates(Sema &s, unsigned currentArg, OverloadCandidate *candidates, unsigned numCandidates,
|
||||||
#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
|
|
||||||
,
|
|
||||||
SourceLocation openParLoc
|
SourceLocation openParLoc
|
||||||
#endif
|
|
||||||
#if LLVM_VERSION_MAJOR >= 14
|
#if LLVM_VERSION_MAJOR >= 14
|
||||||
,
|
,
|
||||||
bool braced
|
bool braced
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
#include "pipeline.hh"
|
#include "pipeline.hh"
|
||||||
|
|
||||||
#include "config.hh"
|
#include "config.hh"
|
||||||
#include "include_complete.hh"
|
|
||||||
#include "log.hh"
|
#include "log.hh"
|
||||||
#include "lsp.hh"
|
#include "lsp.hh"
|
||||||
#include "message_handler.hh"
|
#include "message_handler.hh"
|
||||||
@ -657,7 +656,6 @@ void mainLoop() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
IncludeComplete include_complete(&project);
|
|
||||||
DB db;
|
DB db;
|
||||||
|
|
||||||
// Setup shared references.
|
// Setup shared references.
|
||||||
@ -667,7 +665,6 @@ void mainLoop() {
|
|||||||
handler.vfs = &vfs;
|
handler.vfs = &vfs;
|
||||||
handler.wfiles = &wfiles;
|
handler.wfiles = &wfiles;
|
||||||
handler.manager = &manager;
|
handler.manager = &manager;
|
||||||
handler.include_complete = &include_complete;
|
|
||||||
|
|
||||||
bool work_done_created = false, in_progress = false;
|
bool work_done_created = false, in_progress = false;
|
||||||
bool has_indexed = false;
|
bool has_indexed = false;
|
||||||
@ -787,14 +784,12 @@ void standalone(const std::string &root) {
|
|||||||
nullptr, nullptr,
|
nullptr, nullptr,
|
||||||
[](const std::string &, const std::vector<Diagnostic> &) {},
|
[](const std::string &, const std::vector<Diagnostic> &) {},
|
||||||
[](const RequestId &id) {});
|
[](const RequestId &id) {});
|
||||||
IncludeComplete complete(&project);
|
|
||||||
|
|
||||||
MessageHandler handler;
|
MessageHandler handler;
|
||||||
handler.project = &project;
|
handler.project = &project;
|
||||||
handler.wfiles = &wfiles;
|
handler.wfiles = &wfiles;
|
||||||
handler.vfs = &vfs;
|
handler.vfs = &vfs;
|
||||||
handler.manager = &manager;
|
handler.manager = &manager;
|
||||||
handler.include_complete = &complete;
|
|
||||||
|
|
||||||
standaloneInitialize(handler, root);
|
standaloneInitialize(handler, root);
|
||||||
bool tty = sys::Process::StandardOutIsDisplayed();
|
bool tty = sys::Process::StandardOutIsDisplayed();
|
||||||
|
@ -134,88 +134,6 @@ struct ProjectProcessor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
entry.args = args;
|
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.args.push_back(intern(args[i]));
|
||||||
}
|
}
|
||||||
entry.compdb_size = entry.args.size();
|
entry.compdb_size = entry.args.size();
|
||||||
proc.getSearchDirs(entry);
|
|
||||||
if (seen.insert(entry.filename).second)
|
if (seen.insert(entry.filename).second)
|
||||||
folder.entries.push_back(entry);
|
folder.entries.push_back(entry);
|
||||||
}
|
}
|
||||||
|
@ -26,39 +26,6 @@ using namespace llvm;
|
|||||||
#include <thread>
|
#include <thread>
|
||||||
namespace chrono = std::chrono;
|
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 {
|
namespace ccls {
|
||||||
|
|
||||||
TextEdit toTextEdit(const clang::SourceManager &sm, const clang::LangOptions &l,
|
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
|
// Construct SourceManager with UserFilesAreVolatile: true because otherwise
|
||||||
// RequiresNullTerminator: true may cause out-of-bounds read when a file is
|
// RequiresNullTerminator: true may cause out-of-bounds read when a file is
|
||||||
// mmap'ed but is saved concurrently.
|
// mmap'ed but is saved concurrently.
|
||||||
#if LLVM_VERSION_MAJOR >= 9 // rC357037
|
|
||||||
clang->createFileManager(fs);
|
clang->createFileManager(fs);
|
||||||
#else
|
|
||||||
clang->setVirtualFileSystem(fs);
|
|
||||||
clang->createFileManager();
|
|
||||||
#endif
|
|
||||||
clang->setSourceManager(new SourceManager(clang->getDiagnostics(),
|
clang->setSourceManager(new SourceManager(clang->getDiagnostics(),
|
||||||
clang->getFileManager(), true));
|
clang->getFileManager(), true));
|
||||||
auto &isec = clang->getFrontendOpts().Inputs;
|
auto &isec = clang->getFrontendOpts().Inputs;
|
||||||
@ -353,15 +315,10 @@ bool parse(CompilerInstance &clang) {
|
|||||||
auto run = [&]() {
|
auto run = [&]() {
|
||||||
if (!action.BeginSourceFile(clang, clang.getFrontendOpts().Inputs[0]))
|
if (!action.BeginSourceFile(clang, clang.getFrontendOpts().Inputs[0]))
|
||||||
return;
|
return;
|
||||||
#if LLVM_VERSION_MAJOR >= 9 // rL364464
|
|
||||||
if (llvm::Error e = action.Execute()) {
|
if (llvm::Error e = action.Execute()) {
|
||||||
llvm::consumeError(std::move(e));
|
llvm::consumeError(std::move(e));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
if (!action.Execute())
|
|
||||||
return;
|
|
||||||
#endif
|
|
||||||
action.EndSourceFile();
|
action.EndSourceFile();
|
||||||
ok = true;
|
ok = true;
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user