Skip to content

Commit 6aee7b9

Browse files
committed
Remove ASTUnit from indexer and clean up
1 parent df17175 commit 6aee7b9

File tree

10 files changed

+66
-149
lines changed

10 files changed

+66
-149
lines changed

index_tests/_empty_test.cc

+1-7
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,4 @@
11
/*
22
OUTPUT:
3-
{
4-
"includes": [],
5-
"skipped_ranges": [],
6-
"usr2func": [],
7-
"usr2type": [],
8-
"usr2var": []
9-
}
3+
{}
104
*/

src/clang_complete.cc

+12-32
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
#include "platform.h"
1010

1111
#include <clang/Frontend/CompilerInstance.h>
12-
#include <clang/Frontend/FrontendDiagnostic.h>
1312
#include <clang/Lex/PreprocessorOptions.h>
1413
#include <clang/Sema/CodeCompleteConsumer.h>
1514
#include <llvm/ADT/Twine.h>
@@ -385,10 +384,6 @@ class CaptureCompletionResults : public CodeCompleteConsumer {
385384
}
386385
}
387386

388-
void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg,
389-
OverloadCandidate *Candidates,
390-
unsigned NumCandidates) override {}
391-
392387
CodeCompletionAllocator &getAllocator() override { return *Alloc; }
393388

394389
CodeCompletionTUInfo &getCodeCompletionTUInfo() override { return CCTUInfo; }
@@ -472,30 +467,10 @@ class StoreDiags : public DiagnosticConsumer {
472467
}
473468
};
474469

475-
std::unique_ptr<CompilerInvocation>
476-
buildCompilerInvocation(const std::vector<std::string> &args,
477-
IntrusiveRefCntPtr<vfs::FileSystem> VFS) {
478-
std::vector<const char *> cargs;
479-
for (auto &arg : args)
480-
cargs.push_back(arg.c_str());
481-
IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
482-
CompilerInstance::createDiagnostics(new DiagnosticOptions));
483-
std::unique_ptr<CompilerInvocation> CI =
484-
createInvocationFromCommandLine(cargs, Diags, VFS);
485-
if (CI) {
486-
CI->getFrontendOpts().DisableFree = false;
487-
CI->getLangOpts()->CommentOpts.ParseAllComments = true;
488-
CI->getLangOpts()->SpellChecking = false;
489-
}
490-
return CI;
491-
}
492-
493-
std::unique_ptr<CompilerInstance>
494-
BuildCompilerInstance(CompletionSession &session,
495-
std::unique_ptr<CompilerInvocation> CI,
496-
DiagnosticConsumer &DC,
497-
const WorkingFiles::Snapshot &snapshot,
498-
std::vector<std::unique_ptr<llvm::MemoryBuffer>> &Bufs) {
470+
std::unique_ptr<CompilerInstance> BuildCompilerInstance(
471+
CompletionSession &session, std::unique_ptr<CompilerInvocation> CI,
472+
DiagnosticConsumer &DC, const WorkingFiles::Snapshot &snapshot,
473+
std::vector<std::unique_ptr<llvm::MemoryBuffer>> &Bufs) {
499474
for (auto &file : snapshot.files) {
500475
Bufs.push_back(llvm::MemoryBuffer::getMemBuffer(file.content));
501476
if (file.filename == session.file.filename) {
@@ -558,7 +533,7 @@ void CompletionPreloadMain(ClangCompleteManager *completion_manager) {
558533

559534
LOG_S(INFO) << "create completion session for " << session->file.filename;
560535
if (std::unique_ptr<CompilerInvocation> CI =
561-
buildCompilerInvocation(args, session->FS))
536+
BuildCompilerInvocation(args, session->FS))
562537
session->BuildPreamble(*CI);
563538
}
564539
}
@@ -583,10 +558,12 @@ void CompletionQueryMain(ClangCompleteManager *completion_manager) {
583558
true /*create_if_needed*/);
584559

585560
std::unique_ptr<CompilerInvocation> CI =
586-
buildCompilerInvocation(session->file.args, session->FS);
561+
BuildCompilerInvocation(session->file.args, session->FS);
587562
if (!CI)
588563
continue;
564+
CI->getDiagnosticOpts().IgnoreWarnings = true;
589565
clang::CodeCompleteOptions CCOpts;
566+
CCOpts.IncludeBriefComments = true;
590567
#if LLVM_VERSION_MAJOR >= 7
591568
CCOpts.IncludeFixIts = true;
592569
#endif
@@ -596,6 +573,8 @@ void CompletionQueryMain(ClangCompleteManager *completion_manager) {
596573
FOpts.CodeCompletionAt.FileName = session->file.filename;
597574
FOpts.CodeCompletionAt.Line = request->position.line + 1;
598575
FOpts.CodeCompletionAt.Column = request->position.character + 1;
576+
FOpts.SkipFunctionBodies = true;
577+
CI->getLangOpts()->CommentOpts.ParseAllComments = true;
599578

600579
StoreDiags DC;
601580
WorkingFiles::Snapshot snapshot =
@@ -629,7 +608,7 @@ void DiagnosticQueryMain(ClangCompleteManager *manager) {
629608
path, true /*mark_as_completion*/, true /*create_if_needed*/);
630609

631610
std::unique_ptr<CompilerInvocation> CI =
632-
buildCompilerInvocation(session->file.args, session->FS);
611+
BuildCompilerInvocation(session->file.args, session->FS);
633612
if (!CI)
634613
continue;
635614
StoreDiags DC;
@@ -690,6 +669,7 @@ void CompletionSession::BuildPreamble(CompilerInvocation &CI) {
690669
return;
691670
CI.getFrontendOpts().SkipFunctionBodies = true;
692671
CI.getLangOpts()->RetainCommentsFromSystemHeaders = true;
672+
CI.getLangOpts()->CommentOpts.ParseAllComments = true;
693673
#if LLVM_VERSION_MAJOR >= 7
694674
CI.getPreprocessorOpts().WriteCommentListToPCH = false;
695675
#endif

src/clang_tu.cc

+17
Original file line numberDiff line numberDiff line change
@@ -51,3 +51,20 @@ Range FromTokenRange(const SourceManager &SM, const LangOptions &LangOpts,
5151
return FromCharSourceRange(SM, LangOpts, CharSourceRange::getTokenRange(R),
5252
UniqueID);
5353
}
54+
55+
std::unique_ptr<CompilerInvocation>
56+
BuildCompilerInvocation(const std::vector<std::string> &args,
57+
IntrusiveRefCntPtr<vfs::FileSystem> VFS) {
58+
std::vector<const char *> cargs;
59+
for (auto &arg : args)
60+
cargs.push_back(arg.c_str());
61+
IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
62+
CompilerInstance::createDiagnostics(new DiagnosticOptions));
63+
std::unique_ptr<CompilerInvocation> CI =
64+
createInvocationFromCommandLine(cargs, Diags, VFS);
65+
if (CI) {
66+
CI->getFrontendOpts().DisableFree = false;
67+
CI->getLangOpts()->SpellChecking = false;
68+
}
69+
return CI;
70+
}

src/clang_tu.h

+5
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
#include <clang/Basic/LangOptions.h>
88
#include <clang/Basic/SourceManager.h>
9+
#include <clang/Frontend/CompilerInstance.h>
910

1011
#include <stdlib.h>
1112

@@ -21,3 +22,7 @@ Range FromCharRange(const clang::SourceManager &SM,
2122
Range FromTokenRange(const clang::SourceManager &SM,
2223
const clang::LangOptions &LangOpts, clang::SourceRange R,
2324
llvm::sys::fs::UniqueID *UniqueID = nullptr);
25+
26+
std::unique_ptr<clang::CompilerInvocation>
27+
BuildCompilerInvocation(const std::vector<std::string> &args,
28+
llvm::IntrusiveRefCntPtr<clang::vfs::FileSystem> VFS);

src/indexer.cc

+30-64
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@
1010
using ccls::Intern;
1111

1212
#include <clang/AST/AST.h>
13-
#include <clang/Frontend/ASTUnit.h>
14-
#include <clang/Frontend/CompilerInstance.h>
1513
#include <clang/Frontend/FrontendAction.h>
1614
#include <clang/Index/IndexDataConsumer.h>
1715
#include <clang/Index/IndexingAction.h>
@@ -45,13 +43,10 @@ struct IndexParam {
4543
};
4644
std::unordered_map<const Decl *, DeclInfo> Decl2Info;
4745

48-
ASTUnit &Unit;
4946
ASTContext *Ctx;
50-
5147
FileConsumer *file_consumer = nullptr;
5248

53-
IndexParam(ASTUnit &Unit, FileConsumer *file_consumer)
54-
: Unit(Unit), file_consumer(file_consumer) {}
49+
IndexParam(FileConsumer *file_consumer) : file_consumer(file_consumer) {}
5550

5651
IndexFile *ConsumeFile(const FileEntry &File) {
5752
IndexFile *db = file_consumer->TryConsumeFile(File, &file_contents);
@@ -1158,14 +1153,9 @@ Index(VFS *vfs, const std::string &opt_wdir, const std::string &file,
11581153
if (!g_config->index.enabled)
11591154
return {};
11601155

1161-
std::vector<const char *> Args;
1162-
for (auto &arg : args)
1163-
Args.push_back(arg.c_str());
1164-
auto PCHCO = std::make_shared<PCHContainerOperations>();
1165-
IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
1166-
CompilerInstance::createDiagnostics(new DiagnosticOptions));
1167-
std::shared_ptr<CompilerInvocation> CI =
1168-
createInvocationFromCommandLine(Args, Diags);
1156+
auto PCH = std::make_shared<PCHContainerOperations>();
1157+
llvm::IntrusiveRefCntPtr<vfs::FileSystem> FS = vfs::getRealFileSystem();
1158+
std::shared_ptr<CompilerInvocation> CI = BuildCompilerInvocation(args, FS);
11691159
if (!CI)
11701160
return {};
11711161
// -fparse-all-comments enables documentation in the indexer and in
@@ -1175,20 +1165,18 @@ Index(VFS *vfs, const std::string &opt_wdir, const std::string &file,
11751165
CI->getLangOpts()->RetainCommentsFromSystemHeaders = true;
11761166
CI->getLangOpts()->SpellChecking = false;
11771167

1178-
std::vector<std::unique_ptr<llvm::MemoryBuffer>> BufOwner;
1179-
for (auto &c : file_contents) {
1180-
std::unique_ptr<llvm::MemoryBuffer> MB =
1181-
llvm::MemoryBuffer::getMemBufferCopy(c.content, c.path);
1182-
CI->getPreprocessorOpts().addRemappedFile(c.path, MB.get());
1183-
BufOwner.push_back(std::move(MB));
1184-
}
1185-
1186-
auto Unit = ASTUnit::create(CI, Diags, true, true);
1187-
if (!Unit)
1168+
DiagnosticConsumer DC;
1169+
auto Clang = std::make_unique<CompilerInstance>(PCH);
1170+
Clang->setInvocation(std::move(CI));
1171+
Clang->setVirtualFileSystem(FS);
1172+
Clang->createDiagnostics(&DC, false);
1173+
Clang->setTarget(TargetInfo::CreateTargetInfo(
1174+
Clang->getDiagnostics(), Clang->getInvocation().TargetOpts));
1175+
if (!Clang->hasTarget())
11881176
return {};
11891177

11901178
FileConsumer file_consumer(vfs, file);
1191-
IndexParam param(*Unit, &file_consumer);
1179+
IndexParam param(&file_consumer);
11921180
auto DataConsumer = std::make_shared<IndexDataConsumer>(param);
11931181

11941182
index::IndexingOptions IndexOpts;
@@ -1199,36 +1187,30 @@ Index(VFS *vfs, const std::string &opt_wdir, const std::string &file,
11991187
IndexOpts.IndexImplicitInstantiation = true;
12001188
#endif
12011189

1202-
std::unique_ptr<FrontendAction> IndexAction = createIndexingAction(
1190+
std::unique_ptr<FrontendAction> Action = createIndexingAction(
12031191
DataConsumer, IndexOpts, std::make_unique<IndexFrontendAction>(param));
12041192

1205-
DiagnosticErrorTrap DiagTrap(*Diags);
1206-
llvm::CrashRecoveryContext CRC;
1207-
auto compile = [&]() {
1208-
ASTUnit::LoadFromCompilerInvocationAction(
1209-
std::move(CI), PCHCO, Diags, IndexAction.get(), Unit.get(),
1210-
/*Persistent=*/true, /*ResourceDir=*/"",
1211-
/*OnlyLocalDecls=*/true,
1212-
/*CaptureDiagnostics=*/true, 0, false, false,
1213-
/*UserFilesAreVolatile=*/true);
1214-
};
1215-
if (!CRC.RunSafely(compile)) {
1216-
LOG_S(ERROR) << "clang crashed for " << file;
1217-
return {};
1193+
bool ok = false;
1194+
{
1195+
llvm::CrashRecoveryContext CRC;
1196+
auto parse = [&]() {
1197+
if (!Action->BeginSourceFile(*Clang, Clang->getFrontendOpts().Inputs[0]))
1198+
return;
1199+
if (!Action->Execute())
1200+
return;
1201+
Action->EndSourceFile();
1202+
ok = true;
1203+
};
1204+
if (!CRC.RunSafely(parse)) {
1205+
LOG_S(ERROR) << "clang crashed for " << file;
1206+
return {};
1207+
}
12181208
}
1219-
if (!Unit) {
1209+
if (!ok) {
12201210
LOG_S(ERROR) << "failed to index " << file;
12211211
return {};
12221212
}
12231213

1224-
const SourceManager &SM = Unit->getSourceManager();
1225-
const FileEntry *FE = SM.getFileEntryForID(SM.getMainFileID());
1226-
IndexFile *main_file = param.ConsumeFile(*FE);
1227-
std::unordered_map<std::string, int> inc_to_line;
1228-
if (main_file)
1229-
for (auto &inc : main_file->includes)
1230-
inc_to_line[inc.resolved_path] = inc.line;
1231-
12321214
auto result = param.file_consumer->TakeLocalState();
12331215
for (std::unique_ptr<IndexFile> &entry : result) {
12341216
entry->import_file = file;
@@ -1251,22 +1233,6 @@ Index(VFS *vfs, const std::string &opt_wdir, const std::string &file,
12511233
for (auto &it : entry->usr2var)
12521234
Uniquify(it.second.uses);
12531235

1254-
if (main_file) {
1255-
// If there are errors, show at least one at the include position.
1256-
auto it = inc_to_line.find(entry->path);
1257-
if (it != inc_to_line.end()) {
1258-
int line = it->second;
1259-
for (auto ls_diagnostic : entry->diagnostics_) {
1260-
if (ls_diagnostic.severity != lsDiagnosticSeverity::Error)
1261-
continue;
1262-
ls_diagnostic.range =
1263-
lsRange{lsPosition{line, 10}, lsPosition{line, 10}};
1264-
main_file->diagnostics_.push_back(ls_diagnostic);
1265-
break;
1266-
}
1267-
}
1268-
}
1269-
12701236
// Update file contents and modification time.
12711237
entry->last_write_time = param.file2write_time[entry->path];
12721238

src/indexer.h

-2
Original file line numberDiff line numberDiff line change
@@ -251,8 +251,6 @@ struct IndexFile {
251251
std::unordered_map<Usr, IndexType> usr2type;
252252
std::unordered_map<Usr, IndexVar> usr2var;
253253

254-
// Diagnostics found when indexing this file. Not serialized.
255-
std::vector<lsDiagnostic> diagnostics_;
256254
// File contents at the time of index. Not serialized.
257255
std::string file_contents;
258256

src/pipeline.cc

-6
Original file line numberDiff line numberDiff line change
@@ -243,12 +243,6 @@ bool Indexer_Parse(DiagnosticsPublisher *diag_pub, WorkingFiles *working_files,
243243
}
244244

245245
for (std::unique_ptr<IndexFile> &curr : indexes) {
246-
// Only emit diagnostics for non-interactive sessions, which makes it easier
247-
// to identify indexing problems. For interactive sessions, diagnostics are
248-
// handled by code completion.
249-
if (!request.is_interactive)
250-
diag_pub->Publish(working_files, curr->path, curr->diagnostics_);
251-
252246
std::string path = curr->path;
253247
if (!(vfs->Stamp(path, curr->last_write_time) || path == path_to_index))
254248
continue;

src/project.cc

-3
Original file line numberDiff line numberDiff line change
@@ -116,9 +116,6 @@ struct ProjectProcessor {
116116

117117
args.push_back("-resource-dir=" + g_config->clang.resourceDir);
118118
args.push_back("-working-directory=" + entry.directory);
119-
// There could be a clang version mismatch between what the project uses and
120-
// what ccls uses. Make sure we do not emit warnings for mismatched options.
121-
args.push_back("-Wno-unknown-warning-option");
122119

123120
if (!command_set.insert(hash).second) {
124121
entry.args = std::move(args);

src/test.cc

-34
Original file line numberDiff line numberDiff line change
@@ -295,42 +295,8 @@ bool RunIndexTests(const std::string &filter_path, bool enable_update) {
295295
const std::string &expected_path = entry.first;
296296
std::string expected_output = text_replacer.Apply(entry.second);
297297

298-
// FIXME: promote to utils, find and remove duplicates (ie,
299-
// ccls_call_tree.cc, maybe something in project.cc).
300-
auto basename = [](const std::string &path) -> std::string {
301-
size_t last_index = path.find_last_of('/');
302-
if (last_index == std::string::npos)
303-
return path;
304-
return path.substr(last_index + 1);
305-
};
306-
307298
// Get output from index operation.
308299
IndexFile *db = FindDbForPathEnding(expected_path, dbs);
309-
if (db && !db->diagnostics_.empty()) {
310-
printf("For %s\n", path.c_str());
311-
for (const lsDiagnostic &diagnostic : db->diagnostics_) {
312-
printf(" ");
313-
if (diagnostic.severity)
314-
switch (*diagnostic.severity) {
315-
case lsDiagnosticSeverity::Error:
316-
printf("error ");
317-
break;
318-
case lsDiagnosticSeverity::Warning:
319-
printf("warning ");
320-
break;
321-
case lsDiagnosticSeverity::Information:
322-
printf("information ");
323-
break;
324-
case lsDiagnosticSeverity::Hint:
325-
printf("hint ");
326-
break;
327-
}
328-
printf("%s:%s-%s:%s\n", basename(db->path).c_str(),
329-
diagnostic.range.start.ToString().c_str(),
330-
diagnostic.range.end.ToString().c_str(),
331-
diagnostic.message.c_str());
332-
}
333-
}
334300
std::string actual_output = "{}";
335301
if (db) {
336302
VerifySerializeToFrom(db);

0 commit comments

Comments
 (0)