@@ -66,31 +66,27 @@ class ProxyASTConsumer final : public clang::MultiplexConsumer {
6666class ProxyAction final : public clang::WrapperFrontendAction {
6767public:
6868 ProxyAction (std::unique_ptr<clang::FrontendAction> action,
69- bool collect_top_level_decls ,
69+ std::vector<clang::Decl*>* top_level_decls ,
7070 std::shared_ptr<std::atomic_bool> stop) :
71- clang::WrapperFrontendAction (std::move(action)), need_collect(collect_top_level_decls ),
71+ clang::WrapperFrontendAction (std::move(action)), top_level_decls(top_level_decls ),
7272 stop (std::move(stop)) {}
7373
7474 auto CreateASTConsumer (clang::CompilerInstance& instance, llvm::StringRef file)
7575 -> std::unique_ptr<clang::ASTConsumer> final {
7676 return std::make_unique<ProxyASTConsumer>(
7777 WrapperFrontendAction::CreateASTConsumer (instance, file),
7878 instance,
79- need_collect ? & top_level_decls : nullptr ,
79+ top_level_decls,
8080 std::move (stop));
8181 }
8282
8383 // / Make this public.
8484 using clang::WrapperFrontendAction::EndSourceFile;
8585
86- auto pop_decls () {
87- return std::move (top_level_decls);
88- }
89-
9086private:
9187 // / Whether we need to collect top level declarations.
9288 bool need_collect;
93- std::vector<clang::Decl*> top_level_decls;
89+ std::vector<clang::Decl*>* top_level_decls;
9490 std::shared_ptr<std::atomic_bool> stop;
9591};
9692
@@ -149,14 +145,15 @@ auto create_invocation(CompilationParams& params,
149145}
150146
151147// / Do nothing before or after compile state.
152- constexpr static auto NoHook = [](auto & /* ignore*/ ) {
148+ constexpr static auto no_hook = [](auto & /* ignore*/ ) {
153149};
154150
155- template <typename Action>
151+ template <typename Action,
152+ typename BeforeExecute = decltype (no_hook),
153+ typename AfterExecute = decltype (no_hook)>
156154CompilationResult run_clang (CompilationParams& params,
157- auto before_execute = NoHook,
158- auto after_execute = NoHook,
159- bool collect = false ) {
155+ const BeforeExecute& before_execute = no_hook,
156+ const AfterExecute& after_execute = no_hook) {
160157 auto diagnostics =
161158 params.diagnostics ? params.diagnostics : std::make_shared<std::vector<Diagnostic>>();
162159 auto diagnostic_engine =
@@ -186,7 +183,17 @@ CompilationResult run_clang(CompilationParams& params,
186183 // / Adjust the compiler instance, for example, set preamble or modules.
187184 before_execute (*instance);
188185
189- auto action = std::make_unique<ProxyAction>(std::make_unique<Action>(), collect, params.stop );
186+ // / Frontend information ...
187+ std::vector<clang::Decl*> top_level_decls;
188+ llvm::DenseMap<clang::FileID, Directive> directives;
189+ std::optional<clang::syntax::TokenCollector> token_collector;
190+
191+ auto action = std::make_unique<ProxyAction>(
192+ std::make_unique<Action>(),
193+ // / We only collect top level declarations for parse main file.
194+ params.kind == CompilationUnit::Content ? &top_level_decls : nullptr ,
195+ params.stop );
196+
190197 if (!action->BeginSourceFile (*instance, instance->getFrontendOpts ().Inputs [0 ])) {
191198 return std::unexpected (" Fail to begin source file" );
192199 }
@@ -196,18 +203,12 @@ CompilationResult run_clang(CompilationParams& params,
196203
197204 // / `BeginSourceFile` may create new preprocessor, so all operations related to preprocessor
198205 // / should be done after `BeginSourceFile`.
199-
200- // / Collect directives.
201- llvm::DenseMap<clang::FileID, Directive> directives;
202206 Directive::attach (pp, directives);
203207
204- // / Collect tokens.
205- std::optional<clang::syntax::TokenCollector> tok_collector;
206-
207208 // / It is not necessary to collect tokens if we are running code completion.
208209 // / And in fact will cause assertion failure.
209210 if (!instance->hasCodeCompletionConsumer ()) {
210- tok_collector .emplace (pp);
211+ token_collector .emplace (pp);
211212 }
212213
213214 if (auto error = action->Execute ()) {
@@ -231,9 +232,9 @@ CompilationResult run_clang(CompilationParams& params,
231232 return std::unexpected (" Compilation is canceled." );
232233 }
233234
234- std::optional<clang::syntax::TokenBuffer> tok_buf ;
235- if (tok_collector ) {
236- tok_buf = std::move (*tok_collector ).consume ();
235+ std::optional<clang::syntax::TokenBuffer> token_buffer ;
236+ if (token_collector ) {
237+ token_buffer = std::move (*token_collector ).consume ();
237238 }
238239
239240 // / FIXME: getDependencies currently return ArrayRef<std::string>, which actually results in
@@ -244,38 +245,34 @@ CompilationResult run_clang(CompilationParams& params,
244245 resolver.emplace (instance->getSema ());
245246 }
246247
247- auto top_level_decls = action->pop_decls ();
248-
249248 auto impl = new CompilationUnit::Impl{
250249 .interested = pp.getSourceManager ().getMainFileID (),
251250 .src_mgr = instance->getSourceManager (),
252251 .action = std::move (action),
253252 .instance = std::move (instance),
254253 .m_resolver = std::move (resolver),
255- .buffer = std::move (tok_buf ),
254+ .buffer = std::move (token_buffer ),
256255 .m_directives = std::move (directives),
257256 .pathCache = llvm::DenseMap<clang::FileID, llvm::StringRef>(),
258257 .symbolHashCache = llvm::DenseMap<const void *, std::uint64_t >(),
259258 .diagnostics = diagnostics,
260259 .top_level_decls = std::move (top_level_decls),
261260 };
262261
263- CompilationUnit unit (CompilationUnit::SyntaxOnly , impl);
262+ CompilationUnit unit (CompilationUnit::Content , impl);
264263 after_execute (unit);
265264 return unit;
266265}
267266
268267} // namespace
269268
270269CompilationResult preprocess (CompilationParams& params) {
271- return run_clang<clang::PreprocessOnlyAction>(params,
272- /* before_execute=*/ NoHook,
273- /* after_execute=*/ NoHook);
270+ return run_clang<clang::PreprocessOnlyAction>(params);
274271}
275272
276273CompilationResult compile (CompilationParams& params) {
277274 const bool collect_top_level_decls = params.output_file .empty ();
278- return run_clang<clang::SyntaxOnlyAction>(params, NoHook, NoHook, collect_top_level_decls );
275+ return run_clang<clang::SyntaxOnlyAction>(params);
279276}
280277
281278CompilationResult compile (CompilationParams& params, PCHInfo& out) {
@@ -304,8 +301,7 @@ CompilationResult compile(CompilationParams& params, PCHInfo& out) {
304301 out.preamble = unit.interested_content ();
305302 out.deps = unit.deps ();
306303 out.arguments = params.arguments ;
307- },
308- /* collect_top_level_decls=*/ true );
304+ });
309305}
310306
311307CompilationResult compile (CompilationParams& params, PCMInfo& out) {
@@ -327,8 +323,7 @@ CompilationResult compile(CompilationParams& params, PCMInfo& out) {
327323 for (auto & [name, path]: params.pcms ) {
328324 out.mods .emplace_back (name);
329325 }
330- },
331- /* collect_top_level_decls=*/ true );
326+ });
332327}
333328
334329CompilationResult complete (CompilationParams& params, clang::CodeCompleteConsumer* consumer) {
@@ -351,16 +346,13 @@ CompilationResult complete(CompilationParams& params, clang::CodeCompleteConsume
351346 column += 1 ;
352347 }
353348
354- return run_clang<clang::SyntaxOnlyAction>(
355- params,
356- [&](clang::CompilerInstance& instance) {
357- // / Set options to run code completion.
358- instance.getFrontendOpts ().CodeCompletionAt .FileName = std::move (file);
359- instance.getFrontendOpts ().CodeCompletionAt .Line = line;
360- instance.getFrontendOpts ().CodeCompletionAt .Column = column;
361- instance.setCodeCompletionConsumer (consumer);
362- },
363- /* after_execute=*/ NoHook);
349+ return run_clang<clang::SyntaxOnlyAction>(params, [&](clang::CompilerInstance& instance) {
350+ // / Set options to run code completion.
351+ instance.getFrontendOpts ().CodeCompletionAt .FileName = std::move (file);
352+ instance.getFrontendOpts ().CodeCompletionAt .Line = line;
353+ instance.getFrontendOpts ().CodeCompletionAt .Column = column;
354+ instance.setCodeCompletionConsumer (consumer);
355+ });
364356}
365357
366358} // namespace clice
0 commit comments