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::tokens_iterator ti = macro_info->tokens_begin(),
522                                                te = macro_info->tokens_end();
523              ti != te; ++ti) {
524           if (!first_token)
525             macro_expansion.append(" ");
526           else
527             first_token = false;
528 
529           if (ti->isLiteral()) {
530             if (const char *literal_data = ti->getLiteralData()) {
531               std::string token_str(literal_data, ti->getLength());
532               macro_expansion.append(token_str);
533             } else {
534               bool invalid = false;
535               const char *literal_source =
536                   m_compiler_instance->getSourceManager().getCharacterData(
537                       ti->getLocation(), &invalid);
538 
539               if (invalid) {
540                 lldbassert(0 && "Unhandled token kind");
541                 macro_expansion.append("<unknown literal value>");
542               } else {
543                 macro_expansion.append(
544                     std::string(literal_source, ti->getLength()));
545               }
546             }
547           } else if (const char *punctuator_spelling =
548                          clang::tok::getPunctuatorSpelling(ti->getKind())) {
549             macro_expansion.append(punctuator_spelling);
550           } else if (const char *keyword_spelling =
551                          clang::tok::getKeywordSpelling(ti->getKind())) {
552             macro_expansion.append(keyword_spelling);
553           } else {
554             switch (ti->getKind()) {
555             case clang::tok::TokenKind::identifier:
556               macro_expansion.append(ti->getIdentifierInfo()->getName().str());
557               break;
558             case clang::tok::TokenKind::raw_identifier:
559               macro_expansion.append(ti->getRawIdentifier().str());
560               break;
561             default:
562               macro_expansion.append(ti->getName());
563               break;
564             }
565           }
566         }
567 
568         if (handler(macro_identifier, macro_expansion)) {
569           return;
570         }
571       }
572     }
573   }
574 }
575 
576 clang::ModuleLoadResult
577 ClangModulesDeclVendorImpl::DoGetModule(clang::ModuleIdPath path,
578                                         bool make_visible) {
579   clang::Module::NameVisibilityKind visibility =
580       make_visible ? clang::Module::AllVisible : clang::Module::Hidden;
581 
582   const bool is_inclusion_directive = false;
583 
584   return m_compiler_instance->loadModule(path.front().second, path, visibility,
585                                          is_inclusion_directive);
586 }
587 
588 static const char *ModuleImportBufferName = "LLDBModulesMemoryBuffer";
589 
590 lldb_private::ClangModulesDeclVendor *
591 ClangModulesDeclVendor::Create(Target &target) {
592   // FIXME we should insure programmatically that the expression parser's
593   // compiler and the modules runtime's
594   // compiler are both initialized in the same way – preferably by the same
595   // code.
596 
597   if (!target.GetPlatform()->SupportsModules())
598     return nullptr;
599 
600   const ArchSpec &arch = target.GetArchitecture();
601 
602   std::vector<std::string> compiler_invocation_arguments = {
603       "clang",
604       "-fmodules",
605       "-fimplicit-module-maps",
606       "-fcxx-modules",
607       "-fsyntax-only",
608       "-femit-all-decls",
609       "-target",
610       arch.GetTriple().str(),
611       "-fmodules-validate-system-headers",
612       "-Werror=non-modular-include-in-framework-module"};
613 
614   target.GetPlatform()->AddClangModuleCompilationOptions(
615       &target, compiler_invocation_arguments);
616 
617   compiler_invocation_arguments.push_back(ModuleImportBufferName);
618 
619   // Add additional search paths with { "-I", path } or { "-F", path } here.
620 
621   {
622     llvm::SmallString<128> path;
623     const auto &props = ModuleList::GetGlobalModuleListProperties();
624     props.GetClangModulesCachePath().GetPath(path);
625     std::string module_cache_argument("-fmodules-cache-path=");
626     module_cache_argument.append(std::string(path.str()));
627     compiler_invocation_arguments.push_back(module_cache_argument);
628   }
629 
630   FileSpecList module_search_paths = target.GetClangModuleSearchPaths();
631 
632   for (size_t spi = 0, spe = module_search_paths.GetSize(); spi < spe; ++spi) {
633     const FileSpec &search_path = module_search_paths.GetFileSpecAtIndex(spi);
634 
635     std::string search_path_argument = "-I";
636     search_path_argument.append(search_path.GetPath());
637 
638     compiler_invocation_arguments.push_back(search_path_argument);
639   }
640 
641   {
642     FileSpec clang_resource_dir = GetClangResourceDir();
643 
644     if (FileSystem::Instance().IsDirectory(clang_resource_dir.GetPath())) {
645       compiler_invocation_arguments.push_back("-resource-dir");
646       compiler_invocation_arguments.push_back(clang_resource_dir.GetPath());
647     }
648   }
649 
650   llvm::IntrusiveRefCntPtr<clang::DiagnosticsEngine> diagnostics_engine =
651       clang::CompilerInstance::createDiagnostics(new clang::DiagnosticOptions,
652                                                  new StoringDiagnosticConsumer);
653 
654   std::vector<const char *> compiler_invocation_argument_cstrs;
655   compiler_invocation_argument_cstrs.reserve(
656       compiler_invocation_arguments.size());
657   for (const std::string &arg : compiler_invocation_arguments)
658     compiler_invocation_argument_cstrs.push_back(arg.c_str());
659 
660   Log *log = GetLog(LLDBLog::Expressions);
661   LLDB_LOG(log, "ClangModulesDeclVendor's compiler flags {0:$[ ]}",
662            llvm::make_range(compiler_invocation_arguments.begin(),
663                             compiler_invocation_arguments.end()));
664 
665   std::shared_ptr<clang::CompilerInvocation> invocation =
666       clang::createInvocationFromCommandLine(compiler_invocation_argument_cstrs,
667                                              diagnostics_engine);
668 
669   if (!invocation)
670     return nullptr;
671 
672   std::unique_ptr<llvm::MemoryBuffer> source_buffer =
673       llvm::MemoryBuffer::getMemBuffer(
674           "extern int __lldb __attribute__((unavailable));",
675           ModuleImportBufferName);
676 
677   invocation->getPreprocessorOpts().addRemappedFile(ModuleImportBufferName,
678                                                     source_buffer.release());
679 
680   std::unique_ptr<clang::CompilerInstance> instance(
681       new clang::CompilerInstance);
682 
683   // When capturing a reproducer, hook up the file collector with clang to
684   // collector modules and headers.
685   if (repro::Generator *g = repro::Reproducer::Instance().GetGenerator()) {
686     repro::FileProvider &fp = g->GetOrCreate<repro::FileProvider>();
687     instance->setModuleDepCollector(
688         std::make_shared<ModuleDependencyCollectorAdaptor>(
689             fp.GetFileCollector()));
690     clang::DependencyOutputOptions &opts = instance->getDependencyOutputOpts();
691     opts.IncludeSystemHeaders = true;
692     opts.IncludeModuleFiles = true;
693   }
694 
695   // Make sure clang uses the same VFS as LLDB.
696   instance->createFileManager(FileSystem::Instance().GetVirtualFileSystem());
697   instance->setDiagnostics(diagnostics_engine.get());
698   instance->setInvocation(invocation);
699 
700   std::unique_ptr<clang::FrontendAction> action(new clang::SyntaxOnlyAction);
701 
702   instance->setTarget(clang::TargetInfo::CreateTargetInfo(
703       *diagnostics_engine, instance->getInvocation().TargetOpts));
704 
705   if (!instance->hasTarget())
706     return nullptr;
707 
708   instance->getTarget().adjust(*diagnostics_engine, instance->getLangOpts());
709 
710   if (!action->BeginSourceFile(*instance,
711                                instance->getFrontendOpts().Inputs[0]))
712     return nullptr;
713 
714   instance->getPreprocessor().enableIncrementalProcessing();
715 
716   instance->createASTReader();
717 
718   instance->createSema(action->getTranslationUnitKind(), nullptr);
719 
720   const bool skipFunctionBodies = false;
721   std::unique_ptr<clang::Parser> parser(new clang::Parser(
722       instance->getPreprocessor(), instance->getSema(), skipFunctionBodies));
723 
724   instance->getPreprocessor().EnterMainSourceFile();
725   parser->Initialize();
726 
727   clang::Parser::DeclGroupPtrTy parsed;
728 
729   while (!parser->ParseTopLevelDecl(parsed))
730     ;
731 
732   return new ClangModulesDeclVendorImpl(std::move(diagnostics_engine),
733                                         std::move(invocation),
734                                         std::move(instance), std::move(parser));
735 }
736