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