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