LLDB  mainline
ClangModulesDeclVendor.cpp
Go to the documentation of this file.
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"
26 
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 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() {
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 
147 
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(
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 
319  lldb::LanguageType language) {
320  switch (language) {
321  default:
322  return false;
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(
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 
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;
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 
636  if (log)
637  log->PutString("ClangModulesDeclVendor::Create()");
638  std::vector<const char *> compiler_invocation_argument_cstrs;
639  compiler_invocation_argument_cstrs.reserve(
640  compiler_invocation_arguments.size());
641  for (const std::string &arg : compiler_invocation_arguments) {
642  compiler_invocation_argument_cstrs.push_back(arg.c_str());
643  if (log) {
644  log->PutString("\n ");
645  log->PutString(arg);
646  }
647  }
648  if (log)
649  log->PutString("\n");
650 
651  std::shared_ptr<clang::CompilerInvocation> invocation =
652  clang::createInvocationFromCommandLine(compiler_invocation_argument_cstrs,
653  diagnostics_engine);
654 
655  if (!invocation)
656  return nullptr;
657 
658  std::unique_ptr<llvm::MemoryBuffer> source_buffer =
659  llvm::MemoryBuffer::getMemBuffer(
660  "extern int __lldb __attribute__((unavailable));",
661  ModuleImportBufferName);
662 
663  invocation->getPreprocessorOpts().addRemappedFile(ModuleImportBufferName,
664  source_buffer.release());
665 
666  std::unique_ptr<clang::CompilerInstance> instance(
667  new clang::CompilerInstance);
668 
669  // When capturing a reproducer, hook up the file collector with clang to
670  // collector modules and headers.
671  if (repro::Generator *g = repro::Reproducer::Instance().GetGenerator()) {
672  repro::FileProvider &fp = g->GetOrCreate<repro::FileProvider>();
673  instance->setModuleDepCollector(
674  std::make_shared<ModuleDependencyCollectorAdaptor>(
675  fp.GetFileCollector()));
676  clang::DependencyOutputOptions &opts = instance->getDependencyOutputOpts();
677  opts.IncludeSystemHeaders = true;
678  opts.IncludeModuleFiles = true;
679  }
680 
681  // Make sure clang uses the same VFS as LLDB.
682  instance->createFileManager(FileSystem::Instance().GetVirtualFileSystem());
683  instance->setDiagnostics(diagnostics_engine.get());
684  instance->setInvocation(invocation);
685 
686  std::unique_ptr<clang::FrontendAction> action(new clang::SyntaxOnlyAction);
687 
688  instance->setTarget(clang::TargetInfo::CreateTargetInfo(
689  *diagnostics_engine, instance->getInvocation().TargetOpts));
690 
691  if (!instance->hasTarget())
692  return nullptr;
693 
694  instance->getTarget().adjust(instance->getLangOpts());
695 
696  if (!action->BeginSourceFile(*instance,
697  instance->getFrontendOpts().Inputs[0]))
698  return nullptr;
699 
700  instance->getPreprocessor().enableIncrementalProcessing();
701 
702  instance->createModuleManager();
703 
704  instance->createSema(action->getTranslationUnitKind(), nullptr);
705 
706  const bool skipFunctionBodies = false;
707  std::unique_ptr<clang::Parser> parser(new clang::Parser(
708  instance->getPreprocessor(), instance->getSema(), skipFunctionBodies));
709 
710  instance->getPreprocessor().EnterMainSourceFile();
711  parser->Initialize();
712 
713  clang::Parser::DeclGroupPtrTy parsed;
714 
715  while (!parser->ParseTopLevelDecl(parsed))
716  ;
717 
718  return new ClangModulesDeclVendorImpl(std::move(diagnostics_engine),
719  std::move(invocation),
720  std::move(instance), std::move(parser));
721 }
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
Definition: Stream.cpp:61
FileSpec GetClangResourceDir()
Definition: ClangHost.cpp:155
Enumerations for broadcasting.
Definition: SBLaunchInfo.h:14
const ArchSpec & GetArchitecture() const
Definition: Target.h:941
const char * AsCString(const char *value_if_empty=nullptr) const
Get the string value as a C string.
Definition: ConstString.h:224
A stream class that can stream formatted output to a file.
Definition: Stream.h:28
#define lldbassert(x)
Definition: LLDBAssert.h:15
std::vector< ConstString > path
Something like "Module.Submodule".
Definition: SourceModule.h:20
void PutString(llvm::StringRef str)
Definition: Log.cpp:110
A file utility class.
Definition: FileSpec.h:55
An architecture specification class.
Definition: ArchSpec.h:32
lldb::LanguageType GetLanguage()
static ClangModulesDeclVendor * Create(Target &target)
static FileSystem & Instance()
const std::vector< SourceModule > & GetImportedModules()
Get the compile unit&#39;s imported module list.
A class that describes a compilation unit.
Definition: CompileUnit.h:35
llvm::Triple & GetTriple()
Architecture triple accessor.
Definition: ArchSpec.h:431
LanguageType
Programming language type.
static ModuleListProperties & GetGlobalModuleListProperties()
Definition: ModuleList.cpp:744
Log * GetLogIfAllCategoriesSet(uint32_t mask)
Definition: Logging.cpp:57
llvm::StringRef GetStringRef() const
Get the string value as a llvm::StringRef.
Definition: ConstString.h:233
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition: Stream.cpp:106
static Reproducer & Instance()
Definition: Reproducer.cpp:21
size_t PutChar(char ch)
Definition: Stream.cpp:103
lldb::PlatformSP GetPlatform()
Definition: Target.h:1214
A uniqued constant string class.
Definition: ConstString.h:38
The generator is responsible for the logic needed to generate a reproducer.
Definition: Reproducer.h:169
Non-standardized C, such as K&R.
static const char * ModuleImportBufferName
FileSpecList GetClangModuleSearchPaths()
Definition: Target.cpp:3893
#define LIBLLDB_LOG_EXPRESSIONS
Definition: Logging.h:22
FileCollector & GetFileCollector()
Definition: Reproducer.h:98
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
Definition: FileSpec.cpp:376
static bool LanguageSupportsClangModules(lldb::LanguageType language)
Query whether Clang supports modules for a particular language.
Information needed to import a source-language module.
Definition: SourceModule.h:18