1 //===-- ClangModulesDeclVendor.cpp ----------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "clang/Basic/TargetInfo.h"
10 #include "clang/Frontend/CompilerInstance.h"
11 #include "clang/Frontend/FrontendActions.h"
12 #include "clang/Frontend/TextDiagnosticPrinter.h"
13 #include "clang/Lex/Preprocessor.h"
14 #include "clang/Lex/PreprocessorOptions.h"
15 #include "clang/Parse/Parser.h"
16 #include "clang/Sema/Lookup.h"
17 #include "clang/Serialization/ASTReader.h"
18 #include "llvm/Support/FileSystem.h"
19 #include "llvm/Support/Path.h"
20 #include "llvm/Support/Threading.h"
21 
22 #include "ClangHost.h"
23 #include "ClangModulesDeclVendor.h"
24 #include "ModuleDependencyCollector.h"
25 
26 #include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
27 #include "lldb/Core/ModuleList.h"
28 #include "lldb/Host/Host.h"
29 #include "lldb/Host/HostInfo.h"
30 #include "lldb/Symbol/CompileUnit.h"
31 #include "lldb/Symbol/SourceModule.h"
32 #include "lldb/Target/Target.h"
33 #include "lldb/Utility/FileSpec.h"
34 #include "lldb/Utility/LLDBAssert.h"
35 #include "lldb/Utility/LLDBLog.h"
36 #include "lldb/Utility/Log.h"
37 #include "lldb/Utility/ReproducerProvider.h"
38 #include "lldb/Utility/StreamString.h"
39 
40 #include <memory>
41 #include <mutex>
42 
43 using namespace lldb_private;
44 
45 namespace {
46 /// Any Clang compiler requires a consumer for diagnostics.  This one stores
47 /// them as strings so we can provide them to the user in case a module failed
48 /// to load.
49 class StoringDiagnosticConsumer : public clang::DiagnosticConsumer {
50 public:
51   StoringDiagnosticConsumer();
52 
53   void HandleDiagnostic(clang::DiagnosticsEngine::Level DiagLevel,
54                         const clang::Diagnostic &info) override;
55 
56   void ClearDiagnostics();
57 
58   void DumpDiagnostics(Stream &error_stream);
59 
60   void BeginSourceFile(const clang::LangOptions &LangOpts,
61                        const clang::Preprocessor *PP = nullptr) override;
62   void EndSourceFile() override;
63 
64 private:
65   typedef std::pair<clang::DiagnosticsEngine::Level, std::string>
66       IDAndDiagnostic;
67   std::vector<IDAndDiagnostic> m_diagnostics;
68   /// The DiagnosticPrinter used for creating the full diagnostic messages
69   /// that are stored in m_diagnostics.
70   std::shared_ptr<clang::TextDiagnosticPrinter> m_diag_printer;
71   /// Output stream of m_diag_printer.
72   std::shared_ptr<llvm::raw_string_ostream> m_os;
73   /// Output string filled by m_os. Will be reused for different diagnostics.
74   std::string m_output;
75   Log *m_log;
76 };
77 
78 /// The private implementation of our ClangModulesDeclVendor.  Contains all the
79 /// Clang state required to load modules.
80 class ClangModulesDeclVendorImpl : public ClangModulesDeclVendor {
81 public:
82   ClangModulesDeclVendorImpl(
83       llvm::IntrusiveRefCntPtr<clang::DiagnosticsEngine> diagnostics_engine,
84       std::shared_ptr<clang::CompilerInvocation> compiler_invocation,
85       std::unique_ptr<clang::CompilerInstance> compiler_instance,
86       std::unique_ptr<clang::Parser> parser);
87 
88   ~ClangModulesDeclVendorImpl() override = default;
89 
90   bool AddModule(const SourceModule &module, ModuleVector *exported_modules,
91                  Stream &error_stream) override;
92 
93   bool AddModulesForCompileUnit(CompileUnit &cu, ModuleVector &exported_modules,
94                                 Stream &error_stream) override;
95 
96   uint32_t FindDecls(ConstString name, bool append, uint32_t max_matches,
97                      std::vector<CompilerDecl> &decls) override;
98 
99   void ForEachMacro(
100       const ModuleVector &modules,
101       std::function<bool(llvm::StringRef, llvm::StringRef)> handler) override;
102 
103 private:
104   typedef llvm::DenseSet<ModuleID> ExportedModuleSet;
105   void ReportModuleExportsHelper(ExportedModuleSet &exports,
106                                  clang::Module *module);
107 
108   void ReportModuleExports(ModuleVector &exports, clang::Module *module);
109 
110   clang::ModuleLoadResult DoGetModule(clang::ModuleIdPath path,
111                                       bool make_visible);
112 
113   bool m_enabled = false;
114 
115   llvm::IntrusiveRefCntPtr<clang::DiagnosticsEngine> m_diagnostics_engine;
116   std::shared_ptr<clang::CompilerInvocation> m_compiler_invocation;
117   std::unique_ptr<clang::CompilerInstance> m_compiler_instance;
118   std::unique_ptr<clang::Parser> m_parser;
119   size_t m_source_location_index =
120       0; // used to give name components fake SourceLocations
121 
122   typedef std::vector<ConstString> ImportedModule;
123   typedef std::map<ImportedModule, clang::Module *> ImportedModuleMap;
124   typedef llvm::DenseSet<ModuleID> ImportedModuleSet;
125   ImportedModuleMap m_imported_modules;
126   ImportedModuleSet m_user_imported_modules;
127   // We assume that every ASTContext has an TypeSystemClang, so we also store
128   // a custom TypeSystemClang for our internal ASTContext.
129   std::unique_ptr<TypeSystemClang> m_ast_context;
130 };
131 } // anonymous namespace
132 
133 StoringDiagnosticConsumer::StoringDiagnosticConsumer() {
134   m_log = GetLog(LLDBLog::Expressions);
135 
136   clang::DiagnosticOptions *m_options = new clang::DiagnosticOptions();
137   m_os = std::make_shared<llvm::raw_string_ostream>(m_output);
138   m_diag_printer =
139       std::make_shared<clang::TextDiagnosticPrinter>(*m_os, m_options);
140 }
141 
142 void StoringDiagnosticConsumer::HandleDiagnostic(
143     clang::DiagnosticsEngine::Level DiagLevel, const clang::Diagnostic &info) {
144   // Print the diagnostic to m_output.
145   m_output.clear();
146   m_diag_printer->HandleDiagnostic(DiagLevel, info);
147   m_os->flush();
148 
149   // Store the diagnostic for later.
150   m_diagnostics.push_back(IDAndDiagnostic(DiagLevel, m_output));
151 }
152 
153 void StoringDiagnosticConsumer::ClearDiagnostics() { m_diagnostics.clear(); }
154 
155 void StoringDiagnosticConsumer::DumpDiagnostics(Stream &error_stream) {
156   for (IDAndDiagnostic &diag : m_diagnostics) {
157     switch (diag.first) {
158     default:
159       error_stream.PutCString(diag.second);
160       error_stream.PutChar('\n');
161       break;
162     case clang::DiagnosticsEngine::Level::Ignored:
163       break;
164     }
165   }
166 }
167 
168 void StoringDiagnosticConsumer::BeginSourceFile(
169     const clang::LangOptions &LangOpts, const clang::Preprocessor *PP) {
170   m_diag_printer->BeginSourceFile(LangOpts, PP);
171 }
172 
173 void StoringDiagnosticConsumer::EndSourceFile() {
174   m_diag_printer->EndSourceFile();
175 }
176 
177 ClangModulesDeclVendor::ClangModulesDeclVendor()
178     : ClangDeclVendor(eClangModuleDeclVendor) {}
179 
180 ClangModulesDeclVendor::~ClangModulesDeclVendor() = default;
181 
182 ClangModulesDeclVendorImpl::ClangModulesDeclVendorImpl(
183     llvm::IntrusiveRefCntPtr<clang::DiagnosticsEngine> diagnostics_engine,
184     std::shared_ptr<clang::CompilerInvocation> compiler_invocation,
185     std::unique_ptr<clang::CompilerInstance> compiler_instance,
186     std::unique_ptr<clang::Parser> parser)
187     : m_diagnostics_engine(std::move(diagnostics_engine)),
188       m_compiler_invocation(std::move(compiler_invocation)),
189       m_compiler_instance(std::move(compiler_instance)),
190       m_parser(std::move(parser)) {
191 
192   // Initialize our TypeSystemClang.
193   m_ast_context =
194       std::make_unique<TypeSystemClang>("ClangModulesDeclVendor ASTContext",
195                                         m_compiler_instance->getASTContext());
196 }
197 
198 void ClangModulesDeclVendorImpl::ReportModuleExportsHelper(
199     ExportedModuleSet &exports, clang::Module *module) {
200   if (exports.count(reinterpret_cast<ClangModulesDeclVendor::ModuleID>(module)))
201     return;
202 
203   exports.insert(reinterpret_cast<ClangModulesDeclVendor::ModuleID>(module));
204 
205   llvm::SmallVector<clang::Module *, 2> sub_exports;
206 
207   module->getExportedModules(sub_exports);
208 
209   for (clang::Module *module : sub_exports)
210     ReportModuleExportsHelper(exports, module);
211 }
212 
213 void ClangModulesDeclVendorImpl::ReportModuleExports(
214     ClangModulesDeclVendor::ModuleVector &exports, clang::Module *module) {
215   ExportedModuleSet exports_set;
216 
217   ReportModuleExportsHelper(exports_set, module);
218 
219   for (ModuleID module : exports_set)
220     exports.push_back(module);
221 }
222 
223 bool ClangModulesDeclVendorImpl::AddModule(const SourceModule &module,
224                                            ModuleVector *exported_modules,
225                                            Stream &error_stream) {
226   // Fail early.
227 
228   if (m_compiler_instance->hadModuleLoaderFatalFailure()) {
229     error_stream.PutCString("error: Couldn't load a module because the module "
230                             "loader is in a fatal state.\n");
231     return false;
232   }
233 
234   // Check if we've already imported this module.
235 
236   std::vector<ConstString> imported_module;
237 
238   for (ConstString path_component : module.path)
239     imported_module.push_back(path_component);
240 
241   {
242     ImportedModuleMap::iterator mi = m_imported_modules.find(imported_module);
243 
244     if (mi != m_imported_modules.end()) {
245       if (exported_modules)
246         ReportModuleExports(*exported_modules, mi->second);
247       return true;
248     }
249   }
250 
251   clang::HeaderSearch &HS =
252     m_compiler_instance->getPreprocessor().getHeaderSearchInfo();
253 
254   if (module.search_path) {
255     auto path_begin = llvm::sys::path::begin(module.search_path.GetStringRef());
256     auto path_end = llvm::sys::path::end(module.search_path.GetStringRef());
257     auto sysroot_begin = llvm::sys::path::begin(module.sysroot.GetStringRef());
258     auto sysroot_end = llvm::sys::path::end(module.sysroot.GetStringRef());
259     // FIXME: Use C++14 std::equal(it, it, it, it) variant once it's available.
260     bool is_system_module = (std::distance(path_begin, path_end) >=
261                              std::distance(sysroot_begin, sysroot_end)) &&
262                             std::equal(sysroot_begin, sysroot_end, path_begin);
263     // No need to inject search paths to modules in the sysroot.
264     if (!is_system_module) {
265       auto error = [&]() {
266         error_stream.Printf("error: No module map file in %s\n",
267                             module.search_path.AsCString());
268         return false;
269       };
270 
271       bool is_system = true;
272       bool is_framework = false;
273       auto dir =
274           HS.getFileMgr().getDirectory(module.search_path.GetStringRef());
275       if (!dir)
276         return error();
277       auto *file = HS.lookupModuleMapFile(*dir, is_framework);
278       if (!file)
279         return error();
280       if (!HS.loadModuleMapFile(file, is_system))
281         return error();
282     }
283   }
284   if (!HS.lookupModule(module.path.front().GetStringRef())) {
285     error_stream.Printf("error: Header search couldn't locate module %s\n",
286                         module.path.front().AsCString());
287     return false;
288   }
289 
290   llvm::SmallVector<std::pair<clang::IdentifierInfo *, clang::SourceLocation>,
291                     4>
292       clang_path;
293 
294   {
295     clang::SourceManager &source_manager =
296         m_compiler_instance->getASTContext().getSourceManager();
297 
298     for (ConstString path_component : module.path) {
299       clang_path.push_back(std::make_pair(
300           &m_compiler_instance->getASTContext().Idents.get(
301               path_component.GetStringRef()),
302           source_manager.getLocForStartOfFile(source_manager.getMainFileID())
303               .getLocWithOffset(m_source_location_index++)));
304     }
305   }
306 
307   StoringDiagnosticConsumer *diagnostic_consumer =
308       static_cast<StoringDiagnosticConsumer *>(
309           m_compiler_instance->getDiagnostics().getClient());
310 
311   diagnostic_consumer->ClearDiagnostics();
312 
313   clang::Module *top_level_module = DoGetModule(clang_path.front(), false);
314 
315   if (!top_level_module) {
316     diagnostic_consumer->DumpDiagnostics(error_stream);
317     error_stream.Printf("error: Couldn't load top-level module %s\n",
318                         module.path.front().AsCString());
319     return false;
320   }
321 
322   clang::Module *submodule = top_level_module;
323 
324   for (auto &component : llvm::ArrayRef<ConstString>(module.path).drop_front()) {
325     submodule = submodule->findSubmodule(component.GetStringRef());
326     if (!submodule) {
327       diagnostic_consumer->DumpDiagnostics(error_stream);
328       error_stream.Printf("error: Couldn't load submodule %s\n",
329                           component.GetCString());
330       return false;
331     }
332   }
333 
334   clang::Module *requested_module = DoGetModule(clang_path, true);
335 
336   if (requested_module != nullptr) {
337     if (exported_modules)
338       ReportModuleExports(*exported_modules, requested_module);
339 
340     m_imported_modules[imported_module] = requested_module;
341 
342     m_enabled = true;
343 
344     return true;
345   }
346 
347   return false;
348 }
349 
350 bool ClangModulesDeclVendor::LanguageSupportsClangModules(
351     lldb::LanguageType language) {
352   switch (language) {
353   default:
354     return false;
355   case lldb::LanguageType::eLanguageTypeC:
356   case lldb::LanguageType::eLanguageTypeC11:
357   case lldb::LanguageType::eLanguageTypeC89:
358   case lldb::LanguageType::eLanguageTypeC99:
359   case lldb::LanguageType::eLanguageTypeC_plus_plus:
360   case lldb::LanguageType::eLanguageTypeC_plus_plus_03:
361   case lldb::LanguageType::eLanguageTypeC_plus_plus_11:
362   case lldb::LanguageType::eLanguageTypeC_plus_plus_14:
363   case lldb::LanguageType::eLanguageTypeObjC:
364   case lldb::LanguageType::eLanguageTypeObjC_plus_plus:
365     return true;
366   }
367 }
368 
369 bool ClangModulesDeclVendorImpl::AddModulesForCompileUnit(
370     CompileUnit &cu, ClangModulesDeclVendor::ModuleVector &exported_modules,
371     Stream &error_stream) {
372   if (LanguageSupportsClangModules(cu.GetLanguage())) {
373     for (auto &imported_module : cu.GetImportedModules())
374       if (!AddModule(imported_module, &exported_modules, error_stream))
375         return false;
376   }
377   return true;
378 }
379 
380 // ClangImporter::lookupValue
381 
382 uint32_t
383 ClangModulesDeclVendorImpl::FindDecls(ConstString name, bool append,
384                                       uint32_t max_matches,
385                                       std::vector<CompilerDecl> &decls) {
386   if (!m_enabled)
387     return 0;
388 
389   if (!append)
390     decls.clear();
391 
392   clang::IdentifierInfo &ident =
393       m_compiler_instance->getASTContext().Idents.get(name.GetStringRef());
394 
395   clang::LookupResult lookup_result(
396       m_compiler_instance->getSema(), clang::DeclarationName(&ident),
397       clang::SourceLocation(), clang::Sema::LookupOrdinaryName);
398 
399   m_compiler_instance->getSema().LookupName(
400       lookup_result,
401       m_compiler_instance->getSema().getScopeForContext(
402           m_compiler_instance->getASTContext().getTranslationUnitDecl()));
403 
404   uint32_t num_matches = 0;
405 
406   for (clang::NamedDecl *named_decl : lookup_result) {
407     if (num_matches >= max_matches)
408       return num_matches;
409 
410     decls.push_back(m_ast_context->GetCompilerDecl(named_decl));
411     ++num_matches;
412   }
413 
414   return num_matches;
415 }
416 
417 void ClangModulesDeclVendorImpl::ForEachMacro(
418     const ClangModulesDeclVendor::ModuleVector &modules,
419     std::function<bool(llvm::StringRef, llvm::StringRef)> handler) {
420   if (!m_enabled)
421     return;
422 
423   typedef std::map<ModuleID, ssize_t> ModulePriorityMap;
424   ModulePriorityMap module_priorities;
425 
426   ssize_t priority = 0;
427 
428   for (ModuleID module : modules)
429     module_priorities[module] = priority++;
430 
431   if (m_compiler_instance->getPreprocessor().getExternalSource()) {
432     m_compiler_instance->getPreprocessor()
433         .getExternalSource()
434         ->ReadDefinedMacros();
435   }
436 
437   for (clang::Preprocessor::macro_iterator
438            mi = m_compiler_instance->getPreprocessor().macro_begin(),
439            me = m_compiler_instance->getPreprocessor().macro_end();
440        mi != me; ++mi) {
441     const clang::IdentifierInfo *ii = nullptr;
442 
443     {
444       if (clang::IdentifierInfoLookup *lookup =
445               m_compiler_instance->getPreprocessor()
446                   .getIdentifierTable()
447                   .getExternalIdentifierLookup()) {
448         lookup->get(mi->first->getName());
449       }
450       if (!ii)
451         ii = mi->first;
452     }
453 
454     ssize_t found_priority = -1;
455     clang::MacroInfo *macro_info = nullptr;
456 
457     for (clang::ModuleMacro *module_macro :
458          m_compiler_instance->getPreprocessor().getLeafModuleMacros(ii)) {
459       clang::Module *module = module_macro->getOwningModule();
460 
461       {
462         ModulePriorityMap::iterator pi =
463             module_priorities.find(reinterpret_cast<ModuleID>(module));
464 
465         if (pi != module_priorities.end() && pi->second > found_priority) {
466           macro_info = module_macro->getMacroInfo();
467           found_priority = pi->second;
468         }
469       }
470 
471       clang::Module *top_level_module = module->getTopLevelModule();
472 
473       if (top_level_module != module) {
474         ModulePriorityMap::iterator pi = module_priorities.find(
475             reinterpret_cast<ModuleID>(top_level_module));
476 
477         if ((pi != module_priorities.end()) && pi->second > found_priority) {
478           macro_info = module_macro->getMacroInfo();
479           found_priority = pi->second;
480         }
481       }
482     }
483 
484     if (macro_info) {
485       std::string macro_expansion = "#define ";
486       llvm::StringRef macro_identifier = mi->first->getName();
487       macro_expansion.append(macro_identifier.str());
488 
489       {
490         if (macro_info->isFunctionLike()) {
491           macro_expansion.append("(");
492 
493           bool first_arg = true;
494 
495           for (auto pi = macro_info->param_begin(),
496                     pe = macro_info->param_end();
497                pi != pe; ++pi) {
498             if (!first_arg)
499               macro_expansion.append(", ");
500             else
501               first_arg = false;
502 
503             macro_expansion.append((*pi)->getName().str());
504           }
505 
506           if (macro_info->isC99Varargs()) {
507             if (first_arg)
508               macro_expansion.append("...");
509             else
510               macro_expansion.append(", ...");
511           } else if (macro_info->isGNUVarargs())
512             macro_expansion.append("...");
513 
514           macro_expansion.append(")");
515         }
516 
517         macro_expansion.append(" ");
518 
519         bool first_token = true;
520 
521         for (clang::MacroInfo::const_tokens_iterator
522                  ti = macro_info->tokens_begin(),
523                  te = macro_info->tokens_end();
524              ti != te; ++ti) {
525           if (!first_token)
526             macro_expansion.append(" ");
527           else
528             first_token = false;
529 
530           if (ti->isLiteral()) {
531             if (const char *literal_data = ti->getLiteralData()) {
532               std::string token_str(literal_data, ti->getLength());
533               macro_expansion.append(token_str);
534             } else {
535               bool invalid = false;
536               const char *literal_source =
537                   m_compiler_instance->getSourceManager().getCharacterData(
538                       ti->getLocation(), &invalid);
539 
540               if (invalid) {
541                 lldbassert(0 && "Unhandled token kind");
542                 macro_expansion.append("<unknown literal value>");
543               } else {
544                 macro_expansion.append(
545                     std::string(literal_source, ti->getLength()));
546               }
547             }
548           } else if (const char *punctuator_spelling =
549                          clang::tok::getPunctuatorSpelling(ti->getKind())) {
550             macro_expansion.append(punctuator_spelling);
551           } else if (const char *keyword_spelling =
552                          clang::tok::getKeywordSpelling(ti->getKind())) {
553             macro_expansion.append(keyword_spelling);
554           } else {
555             switch (ti->getKind()) {
556             case clang::tok::TokenKind::identifier:
557               macro_expansion.append(ti->getIdentifierInfo()->getName().str());
558               break;
559             case clang::tok::TokenKind::raw_identifier:
560               macro_expansion.append(ti->getRawIdentifier().str());
561               break;
562             default:
563               macro_expansion.append(ti->getName());
564               break;
565             }
566           }
567         }
568 
569         if (handler(macro_identifier, macro_expansion)) {
570           return;
571         }
572       }
573     }
574   }
575 }
576 
577 clang::ModuleLoadResult
578 ClangModulesDeclVendorImpl::DoGetModule(clang::ModuleIdPath path,
579                                         bool make_visible) {
580   clang::Module::NameVisibilityKind visibility =
581       make_visible ? clang::Module::AllVisible : clang::Module::Hidden;
582 
583   const bool is_inclusion_directive = false;
584 
585   return m_compiler_instance->loadModule(path.front().second, path, visibility,
586                                          is_inclusion_directive);
587 }
588 
589 static const char *ModuleImportBufferName = "LLDBModulesMemoryBuffer";
590 
591 lldb_private::ClangModulesDeclVendor *
592 ClangModulesDeclVendor::Create(Target &target) {
593   // FIXME we should insure programmatically that the expression parser's
594   // compiler and the modules runtime's
595   // compiler are both initialized in the same way – preferably by the same
596   // code.
597 
598   if (!target.GetPlatform()->SupportsModules())
599     return nullptr;
600 
601   const ArchSpec &arch = target.GetArchitecture();
602 
603   std::vector<std::string> compiler_invocation_arguments = {
604       "clang",
605       "-fmodules",
606       "-fimplicit-module-maps",
607       "-fcxx-modules",
608       "-fsyntax-only",
609       "-femit-all-decls",
610       "-target",
611       arch.GetTriple().str(),
612       "-fmodules-validate-system-headers",
613       "-Werror=non-modular-include-in-framework-module"};
614 
615   target.GetPlatform()->AddClangModuleCompilationOptions(
616       &target, compiler_invocation_arguments);
617 
618   compiler_invocation_arguments.push_back(ModuleImportBufferName);
619 
620   // Add additional search paths with { "-I", path } or { "-F", path } here.
621 
622   {
623     llvm::SmallString<128> path;
624     const auto &props = ModuleList::GetGlobalModuleListProperties();
625     props.GetClangModulesCachePath().GetPath(path);
626     std::string module_cache_argument("-fmodules-cache-path=");
627     module_cache_argument.append(std::string(path.str()));
628     compiler_invocation_arguments.push_back(module_cache_argument);
629   }
630 
631   FileSpecList module_search_paths = target.GetClangModuleSearchPaths();
632 
633   for (size_t spi = 0, spe = module_search_paths.GetSize(); spi < spe; ++spi) {
634     const FileSpec &search_path = module_search_paths.GetFileSpecAtIndex(spi);
635 
636     std::string search_path_argument = "-I";
637     search_path_argument.append(search_path.GetPath());
638 
639     compiler_invocation_arguments.push_back(search_path_argument);
640   }
641 
642   {
643     FileSpec clang_resource_dir = GetClangResourceDir();
644 
645     if (FileSystem::Instance().IsDirectory(clang_resource_dir.GetPath())) {
646       compiler_invocation_arguments.push_back("-resource-dir");
647       compiler_invocation_arguments.push_back(clang_resource_dir.GetPath());
648     }
649   }
650 
651   llvm::IntrusiveRefCntPtr<clang::DiagnosticsEngine> diagnostics_engine =
652       clang::CompilerInstance::createDiagnostics(new clang::DiagnosticOptions,
653                                                  new StoringDiagnosticConsumer);
654 
655   std::vector<const char *> compiler_invocation_argument_cstrs;
656   compiler_invocation_argument_cstrs.reserve(
657       compiler_invocation_arguments.size());
658   for (const std::string &arg : compiler_invocation_arguments)
659     compiler_invocation_argument_cstrs.push_back(arg.c_str());
660 
661   Log *log = GetLog(LLDBLog::Expressions);
662   LLDB_LOG(log, "ClangModulesDeclVendor's compiler flags {0:$[ ]}",
663            llvm::make_range(compiler_invocation_arguments.begin(),
664                             compiler_invocation_arguments.end()));
665 
666   clang::CreateInvocationOptions CIOpts;
667   CIOpts.Diags = diagnostics_engine;
668   std::shared_ptr<clang::CompilerInvocation> invocation =
669       clang::createInvocation(compiler_invocation_argument_cstrs,
670                               std::move(CIOpts));
671 
672   if (!invocation)
673     return nullptr;
674 
675   std::unique_ptr<llvm::MemoryBuffer> source_buffer =
676       llvm::MemoryBuffer::getMemBuffer(
677           "extern int __lldb __attribute__((unavailable));",
678           ModuleImportBufferName);
679 
680   invocation->getPreprocessorOpts().addRemappedFile(ModuleImportBufferName,
681                                                     source_buffer.release());
682 
683   std::unique_ptr<clang::CompilerInstance> instance(
684       new clang::CompilerInstance);
685 
686   // When capturing a reproducer, hook up the file collector with clang to
687   // collector modules and headers.
688   if (repro::Generator *g = repro::Reproducer::Instance().GetGenerator()) {
689     repro::FileProvider &fp = g->GetOrCreate<repro::FileProvider>();
690     instance->setModuleDepCollector(
691         std::make_shared<ModuleDependencyCollectorAdaptor>(
692             fp.GetFileCollector()));
693     clang::DependencyOutputOptions &opts = instance->getDependencyOutputOpts();
694     opts.IncludeSystemHeaders = true;
695     opts.IncludeModuleFiles = true;
696   }
697 
698   // Make sure clang uses the same VFS as LLDB.
699   instance->createFileManager(FileSystem::Instance().GetVirtualFileSystem());
700   instance->setDiagnostics(diagnostics_engine.get());
701   instance->setInvocation(invocation);
702 
703   std::unique_ptr<clang::FrontendAction> action(new clang::SyntaxOnlyAction);
704 
705   instance->setTarget(clang::TargetInfo::CreateTargetInfo(
706       *diagnostics_engine, instance->getInvocation().TargetOpts));
707 
708   if (!instance->hasTarget())
709     return nullptr;
710 
711   instance->getTarget().adjust(*diagnostics_engine, instance->getLangOpts());
712 
713   if (!action->BeginSourceFile(*instance,
714                                instance->getFrontendOpts().Inputs[0]))
715     return nullptr;
716 
717   instance->getPreprocessor().enableIncrementalProcessing();
718 
719   instance->createASTReader();
720 
721   instance->createSema(action->getTranslationUnitKind(), nullptr);
722 
723   const bool skipFunctionBodies = false;
724   std::unique_ptr<clang::Parser> parser(new clang::Parser(
725       instance->getPreprocessor(), instance->getSema(), skipFunctionBodies));
726 
727   instance->getPreprocessor().EnterMainSourceFile();
728   parser->Initialize();
729 
730   clang::Parser::DeclGroupPtrTy parsed;
731   auto ImportState = clang::Sema::ModuleImportState::NotACXX20Module;
732   while (!parser->ParseTopLevelDecl(parsed, ImportState))
733     ;
734 
735   return new ClangModulesDeclVendorImpl(std::move(diagnostics_engine),
736                                         std::move(invocation),
737                                         std::move(instance), std::move(parser));
738 }
739