]> 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/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/Log.h"
36 #include "lldb/Utility/Reproducer.h"
37 #include "lldb/Utility/StreamString.h"
38
39 using namespace lldb_private;
40
41 namespace {
42 // Any Clang compiler requires a consumer for diagnostics.  This one stores
43 // them as strings so we can provide them to the user in case a module failed
44 // to load.
45 class StoringDiagnosticConsumer : public clang::DiagnosticConsumer {
46 public:
47   StoringDiagnosticConsumer();
48
49   void HandleDiagnostic(clang::DiagnosticsEngine::Level DiagLevel,
50                         const clang::Diagnostic &info) override;
51
52   void ClearDiagnostics();
53
54   void DumpDiagnostics(Stream &error_stream);
55
56 private:
57   typedef std::pair<clang::DiagnosticsEngine::Level, std::string>
58       IDAndDiagnostic;
59   std::vector<IDAndDiagnostic> m_diagnostics;
60   Log *m_log;
61 };
62
63 // The private implementation of our ClangModulesDeclVendor.  Contains all the
64 // Clang state required to load modules.
65 class ClangModulesDeclVendorImpl : public ClangModulesDeclVendor {
66 public:
67   ClangModulesDeclVendorImpl(
68       llvm::IntrusiveRefCntPtr<clang::DiagnosticsEngine> diagnostics_engine,
69       std::shared_ptr<clang::CompilerInvocation> compiler_invocation,
70       std::unique_ptr<clang::CompilerInstance> compiler_instance,
71       std::unique_ptr<clang::Parser> parser);
72
73   ~ClangModulesDeclVendorImpl() override = default;
74
75   bool AddModule(const SourceModule &module, ModuleVector *exported_modules,
76                  Stream &error_stream) override;
77
78   bool AddModulesForCompileUnit(CompileUnit &cu, ModuleVector &exported_modules,
79                                 Stream &error_stream) override;
80
81   uint32_t FindDecls(ConstString name, bool append, uint32_t max_matches,
82                      std::vector<clang::NamedDecl *> &decls) override;
83
84   void ForEachMacro(const ModuleVector &modules,
85                     std::function<bool(const std::string &)> handler) override;
86
87   clang::ExternalASTMerger::ImporterSource GetImporterSource() override;
88 private:
89   void
90   ReportModuleExportsHelper(std::set<ClangModulesDeclVendor::ModuleID> &exports,
91                             clang::Module *module);
92
93   void ReportModuleExports(ModuleVector &exports, clang::Module *module);
94
95   clang::ModuleLoadResult DoGetModule(clang::ModuleIdPath path,
96                                       bool make_visible);
97
98   bool m_enabled = false;
99
100   llvm::IntrusiveRefCntPtr<clang::DiagnosticsEngine> m_diagnostics_engine;
101   std::shared_ptr<clang::CompilerInvocation> m_compiler_invocation;
102   std::unique_ptr<clang::CompilerInstance> m_compiler_instance;
103   std::unique_ptr<clang::Parser> m_parser;
104   size_t m_source_location_index =
105       0; // used to give name components fake SourceLocations
106
107   typedef std::vector<ConstString> ImportedModule;
108   typedef std::map<ImportedModule, clang::Module *> ImportedModuleMap;
109   typedef std::set<ModuleID> ImportedModuleSet;
110   ImportedModuleMap m_imported_modules;
111   ImportedModuleSet m_user_imported_modules;
112   const clang::ExternalASTMerger::OriginMap m_origin_map;
113 };
114 } // anonymous namespace
115
116 StoringDiagnosticConsumer::StoringDiagnosticConsumer() {
117   m_log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS);
118 }
119
120 void StoringDiagnosticConsumer::HandleDiagnostic(
121     clang::DiagnosticsEngine::Level DiagLevel, const clang::Diagnostic &info) {
122   llvm::SmallVector<char, 256> diagnostic_string;
123
124   info.FormatDiagnostic(diagnostic_string);
125
126   m_diagnostics.push_back(
127       IDAndDiagnostic(DiagLevel, std::string(diagnostic_string.data(),
128                                              diagnostic_string.size())));
129 }
130
131 void StoringDiagnosticConsumer::ClearDiagnostics() { m_diagnostics.clear(); }
132
133 void StoringDiagnosticConsumer::DumpDiagnostics(Stream &error_stream) {
134   for (IDAndDiagnostic &diag : m_diagnostics) {
135     switch (diag.first) {
136     default:
137       error_stream.PutCString(diag.second);
138       error_stream.PutChar('\n');
139       break;
140     case clang::DiagnosticsEngine::Level::Ignored:
141       break;
142     }
143   }
144 }
145
146 ClangModulesDeclVendor::ClangModulesDeclVendor() {}
147
148 ClangModulesDeclVendor::~ClangModulesDeclVendor() {}
149
150 ClangModulesDeclVendorImpl::ClangModulesDeclVendorImpl(
151     llvm::IntrusiveRefCntPtr<clang::DiagnosticsEngine> diagnostics_engine,
152     std::shared_ptr<clang::CompilerInvocation> compiler_invocation,
153     std::unique_ptr<clang::CompilerInstance> compiler_instance,
154     std::unique_ptr<clang::Parser> parser)
155     : m_diagnostics_engine(std::move(diagnostics_engine)),
156       m_compiler_invocation(std::move(compiler_invocation)),
157       m_compiler_instance(std::move(compiler_instance)),
158       m_parser(std::move(parser)), m_origin_map() {}
159
160 void ClangModulesDeclVendorImpl::ReportModuleExportsHelper(
161     std::set<ClangModulesDeclVendor::ModuleID> &exports,
162     clang::Module *module) {
163   if (exports.count(reinterpret_cast<ClangModulesDeclVendor::ModuleID>(module)))
164     return;
165
166   exports.insert(reinterpret_cast<ClangModulesDeclVendor::ModuleID>(module));
167
168   llvm::SmallVector<clang::Module *, 2> sub_exports;
169
170   module->getExportedModules(sub_exports);
171
172   for (clang::Module *module : sub_exports) {
173     ReportModuleExportsHelper(exports, module);
174   }
175 }
176
177 void ClangModulesDeclVendorImpl::ReportModuleExports(
178     ClangModulesDeclVendor::ModuleVector &exports, clang::Module *module) {
179   std::set<ClangModulesDeclVendor::ModuleID> exports_set;
180
181   ReportModuleExportsHelper(exports_set, module);
182
183   for (ModuleID module : exports_set) {
184     exports.push_back(module);
185   }
186 }
187
188 bool ClangModulesDeclVendorImpl::AddModule(const SourceModule &module,
189                                            ModuleVector *exported_modules,
190                                            Stream &error_stream) {
191   // Fail early.
192
193   if (m_compiler_instance->hadModuleLoaderFatalFailure()) {
194     error_stream.PutCString("error: Couldn't load a module because the module "
195                             "loader is in a fatal state.\n");
196     return false;
197   }
198
199   // Check if we've already imported this module.
200
201   std::vector<ConstString> imported_module;
202
203   for (ConstString path_component : module.path) {
204     imported_module.push_back(path_component);
205   }
206
207   {
208     ImportedModuleMap::iterator mi = m_imported_modules.find(imported_module);
209
210     if (mi != m_imported_modules.end()) {
211       if (exported_modules) {
212         ReportModuleExports(*exported_modules, mi->second);
213       }
214       return true;
215     }
216   }
217
218   clang::HeaderSearch &HS =
219     m_compiler_instance->getPreprocessor().getHeaderSearchInfo();
220
221   if (module.search_path) {
222     auto path_begin = llvm::sys::path::begin(module.search_path.GetStringRef());
223     auto path_end = llvm::sys::path::end(module.search_path.GetStringRef());
224     auto sysroot_begin = llvm::sys::path::begin(module.sysroot.GetStringRef());
225     auto sysroot_end = llvm::sys::path::end(module.sysroot.GetStringRef());
226     // FIXME: Use C++14 std::equal(it, it, it, it) variant once it's available.
227     bool is_system_module = (std::distance(path_begin, path_end) >=
228                              std::distance(sysroot_begin, sysroot_end)) &&
229                             std::equal(sysroot_begin, sysroot_end, path_begin);
230     // No need to inject search paths to modules in the sysroot.
231     if (!is_system_module) {
232       auto error = [&]() {
233         error_stream.Printf("error: No module map file in %s\n",
234                             module.search_path.AsCString());
235         return false;
236       };
237
238       bool is_system = true;
239       bool is_framework = false;
240       auto *dir =
241           HS.getFileMgr().getDirectory(module.search_path.GetStringRef());
242       if (!dir)
243         return error();
244       auto *file = HS.lookupModuleMapFile(dir, is_framework);
245       if (!file)
246         return error();
247       if (!HS.loadModuleMapFile(file, is_system))
248         return error();
249     }
250   }
251   if (!HS.lookupModule(module.path.front().GetStringRef())) {
252     error_stream.Printf("error: Header search couldn't locate module %s\n",
253                         module.path.front().AsCString());
254     return false;
255   }
256
257   llvm::SmallVector<std::pair<clang::IdentifierInfo *, clang::SourceLocation>,
258                     4>
259       clang_path;
260
261   {
262     clang::SourceManager &source_manager =
263         m_compiler_instance->getASTContext().getSourceManager();
264
265     for (ConstString path_component : module.path) {
266       clang_path.push_back(std::make_pair(
267           &m_compiler_instance->getASTContext().Idents.get(
268               path_component.GetStringRef()),
269           source_manager.getLocForStartOfFile(source_manager.getMainFileID())
270               .getLocWithOffset(m_source_location_index++)));
271     }
272   }
273
274   StoringDiagnosticConsumer *diagnostic_consumer =
275       static_cast<StoringDiagnosticConsumer *>(
276           m_compiler_instance->getDiagnostics().getClient());
277
278   diagnostic_consumer->ClearDiagnostics();
279
280   clang::Module *top_level_module = DoGetModule(clang_path.front(), false);
281
282   if (!top_level_module) {
283     diagnostic_consumer->DumpDiagnostics(error_stream);
284     error_stream.Printf("error: Couldn't load top-level module %s\n",
285                         module.path.front().AsCString());
286     return false;
287   }
288
289   clang::Module *submodule = top_level_module;
290
291   for (auto &component : llvm::ArrayRef<ConstString>(module.path).drop_front()) {
292     submodule = submodule->findSubmodule(component.GetStringRef());
293     if (!submodule) {
294       diagnostic_consumer->DumpDiagnostics(error_stream);
295       error_stream.Printf("error: Couldn't load submodule %s\n",
296                           component.GetCString());
297       return false;
298     }
299   }
300
301   clang::Module *requested_module = DoGetModule(clang_path, true);
302
303   if (requested_module != nullptr) {
304     if (exported_modules) {
305       ReportModuleExports(*exported_modules, requested_module);
306     }
307
308     m_imported_modules[imported_module] = requested_module;
309
310     m_enabled = true;
311
312     return true;
313   }
314
315   return false;
316 }
317
318 bool ClangModulesDeclVendor::LanguageSupportsClangModules(
319     lldb::LanguageType language) {
320   switch (language) {
321   default:
322     return false;
323   case lldb::LanguageType::eLanguageTypeC:
324   case lldb::LanguageType::eLanguageTypeC11:
325   case lldb::LanguageType::eLanguageTypeC89:
326   case lldb::LanguageType::eLanguageTypeC99:
327   case lldb::LanguageType::eLanguageTypeC_plus_plus:
328   case lldb::LanguageType::eLanguageTypeC_plus_plus_03:
329   case lldb::LanguageType::eLanguageTypeC_plus_plus_11:
330   case lldb::LanguageType::eLanguageTypeC_plus_plus_14:
331   case lldb::LanguageType::eLanguageTypeObjC:
332   case lldb::LanguageType::eLanguageTypeObjC_plus_plus:
333     return true;
334   }
335 }
336
337 bool ClangModulesDeclVendorImpl::AddModulesForCompileUnit(
338     CompileUnit &cu, ClangModulesDeclVendor::ModuleVector &exported_modules,
339     Stream &error_stream) {
340   if (LanguageSupportsClangModules(cu.GetLanguage())) {
341     for (auto &imported_module : cu.GetImportedModules())
342       if (!AddModule(imported_module, &exported_modules, error_stream))
343         return false;
344   }
345   return true;
346 }
347
348 // ClangImporter::lookupValue
349
350 uint32_t
351 ClangModulesDeclVendorImpl::FindDecls(ConstString name, bool append,
352                                       uint32_t max_matches,
353                                       std::vector<clang::NamedDecl *> &decls) {
354   if (!m_enabled) {
355     return 0;
356   }
357
358   if (!append)
359     decls.clear();
360
361   clang::IdentifierInfo &ident =
362       m_compiler_instance->getASTContext().Idents.get(name.GetStringRef());
363
364   clang::LookupResult lookup_result(
365       m_compiler_instance->getSema(), clang::DeclarationName(&ident),
366       clang::SourceLocation(), clang::Sema::LookupOrdinaryName);
367
368   m_compiler_instance->getSema().LookupName(
369       lookup_result,
370       m_compiler_instance->getSema().getScopeForContext(
371           m_compiler_instance->getASTContext().getTranslationUnitDecl()));
372
373   uint32_t num_matches = 0;
374
375   for (clang::NamedDecl *named_decl : lookup_result) {
376     if (num_matches >= max_matches)
377       return num_matches;
378
379     decls.push_back(named_decl);
380     ++num_matches;
381   }
382
383   return num_matches;
384 }
385
386 void ClangModulesDeclVendorImpl::ForEachMacro(
387     const ClangModulesDeclVendor::ModuleVector &modules,
388     std::function<bool(const std::string &)> handler) {
389   if (!m_enabled) {
390     return;
391   }
392
393   typedef std::map<ModuleID, ssize_t> ModulePriorityMap;
394   ModulePriorityMap module_priorities;
395
396   ssize_t priority = 0;
397
398   for (ModuleID module : modules) {
399     module_priorities[module] = priority++;
400   }
401
402   if (m_compiler_instance->getPreprocessor().getExternalSource()) {
403     m_compiler_instance->getPreprocessor()
404         .getExternalSource()
405         ->ReadDefinedMacros();
406   }
407
408   for (clang::Preprocessor::macro_iterator
409            mi = m_compiler_instance->getPreprocessor().macro_begin(),
410            me = m_compiler_instance->getPreprocessor().macro_end();
411        mi != me; ++mi) {
412     const clang::IdentifierInfo *ii = nullptr;
413
414     {
415       if (clang::IdentifierInfoLookup *lookup =
416               m_compiler_instance->getPreprocessor()
417                   .getIdentifierTable()
418                   .getExternalIdentifierLookup()) {
419         lookup->get(mi->first->getName());
420       }
421       if (!ii) {
422         ii = mi->first;
423       }
424     }
425
426     ssize_t found_priority = -1;
427     clang::MacroInfo *macro_info = nullptr;
428
429     for (clang::ModuleMacro *module_macro :
430          m_compiler_instance->getPreprocessor().getLeafModuleMacros(ii)) {
431       clang::Module *module = module_macro->getOwningModule();
432
433       {
434         ModulePriorityMap::iterator pi =
435             module_priorities.find(reinterpret_cast<ModuleID>(module));
436
437         if (pi != module_priorities.end() && pi->second > found_priority) {
438           macro_info = module_macro->getMacroInfo();
439           found_priority = pi->second;
440         }
441       }
442
443       clang::Module *top_level_module = module->getTopLevelModule();
444
445       if (top_level_module != module) {
446         ModulePriorityMap::iterator pi = module_priorities.find(
447             reinterpret_cast<ModuleID>(top_level_module));
448
449         if ((pi != module_priorities.end()) && pi->second > found_priority) {
450           macro_info = module_macro->getMacroInfo();
451           found_priority = pi->second;
452         }
453       }
454     }
455
456     if (macro_info) {
457       std::string macro_expansion = "#define ";
458       macro_expansion.append(mi->first->getName().str());
459
460       {
461         if (macro_info->isFunctionLike()) {
462           macro_expansion.append("(");
463
464           bool first_arg = true;
465
466           for (auto pi = macro_info->param_begin(),
467                     pe = macro_info->param_end();
468                pi != pe; ++pi) {
469             if (!first_arg) {
470               macro_expansion.append(", ");
471             } else {
472               first_arg = false;
473             }
474
475             macro_expansion.append((*pi)->getName().str());
476           }
477
478           if (macro_info->isC99Varargs()) {
479             if (first_arg) {
480               macro_expansion.append("...");
481             } else {
482               macro_expansion.append(", ...");
483             }
484           } else if (macro_info->isGNUVarargs()) {
485             macro_expansion.append("...");
486           }
487
488           macro_expansion.append(")");
489         }
490
491         macro_expansion.append(" ");
492
493         bool first_token = true;
494
495         for (clang::MacroInfo::tokens_iterator ti = macro_info->tokens_begin(),
496                                                te = macro_info->tokens_end();
497              ti != te; ++ti) {
498           if (!first_token) {
499             macro_expansion.append(" ");
500           } else {
501             first_token = false;
502           }
503
504           if (ti->isLiteral()) {
505             if (const char *literal_data = ti->getLiteralData()) {
506               std::string token_str(literal_data, ti->getLength());
507               macro_expansion.append(token_str);
508             } else {
509               bool invalid = false;
510               const char *literal_source =
511                   m_compiler_instance->getSourceManager().getCharacterData(
512                       ti->getLocation(), &invalid);
513
514               if (invalid) {
515                 lldbassert(0 && "Unhandled token kind");
516                 macro_expansion.append("<unknown literal value>");
517               } else {
518                 macro_expansion.append(
519                     std::string(literal_source, ti->getLength()));
520               }
521             }
522           } else if (const char *punctuator_spelling =
523                          clang::tok::getPunctuatorSpelling(ti->getKind())) {
524             macro_expansion.append(punctuator_spelling);
525           } else if (const char *keyword_spelling =
526                          clang::tok::getKeywordSpelling(ti->getKind())) {
527             macro_expansion.append(keyword_spelling);
528           } else {
529             switch (ti->getKind()) {
530             case clang::tok::TokenKind::identifier:
531               macro_expansion.append(ti->getIdentifierInfo()->getName().str());
532               break;
533             case clang::tok::TokenKind::raw_identifier:
534               macro_expansion.append(ti->getRawIdentifier().str());
535               break;
536             default:
537               macro_expansion.append(ti->getName());
538               break;
539             }
540           }
541         }
542
543         if (handler(macro_expansion)) {
544           return;
545         }
546       }
547     }
548   }
549 }
550
551 clang::ModuleLoadResult
552 ClangModulesDeclVendorImpl::DoGetModule(clang::ModuleIdPath path,
553                                         bool make_visible) {
554   clang::Module::NameVisibilityKind visibility =
555       make_visible ? clang::Module::AllVisible : clang::Module::Hidden;
556
557   const bool is_inclusion_directive = false;
558
559   return m_compiler_instance->loadModule(path.front().second, path, visibility,
560                                          is_inclusion_directive);
561 }
562
563 clang::ExternalASTMerger::ImporterSource
564 ClangModulesDeclVendorImpl::GetImporterSource() {
565   return {m_compiler_instance->getASTContext(),
566           m_compiler_instance->getFileManager(), m_origin_map};
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->createModuleManager();
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 }