brintos

brintos / llvm-project-archived public Read only

0
0
Text · 27.7 KiB · ce8dc50 Raw
799 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9#include "clang/Basic/Diagnostic.h"10#include "clang/Basic/DiagnosticFrontend.h"11#include "clang/Basic/IdentifierTable.h"12#include "clang/Basic/TargetInfo.h"13#include "clang/Driver/CreateInvocationFromArgs.h"14#include "clang/Frontend/CompilerInstance.h"15#include "clang/Frontend/FrontendActions.h"16#include "clang/Frontend/TextDiagnosticPrinter.h"17#include "clang/Lex/Preprocessor.h"18#include "clang/Lex/PreprocessorOptions.h"19#include "clang/Parse/Parser.h"20#include "clang/Sema/Lookup.h"21#include "clang/Serialization/ASTReader.h"22#include "llvm/ADT/StringRef.h"23#include "llvm/Support/Path.h"24#include "llvm/Support/Threading.h"25 26#include "ClangHost.h"27#include "ClangModulesDeclVendor.h"28 29#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"30#include "lldb/Core/ModuleList.h"31#include "lldb/Core/Progress.h"32#include "lldb/Symbol/CompileUnit.h"33#include "lldb/Symbol/SourceModule.h"34#include "lldb/Target/Target.h"35#include "lldb/Utility/FileSpec.h"36#include "lldb/Utility/LLDBAssert.h"37#include "lldb/Utility/LLDBLog.h"38#include "lldb/Utility/Log.h"39 40#include <memory>41 42using namespace lldb_private;43 44namespace {45/// Any Clang compiler requires a consumer for diagnostics.  This one stores46/// them as strings so we can provide them to the user in case a module failed47/// to load.48class StoringDiagnosticConsumer : public clang::DiagnosticConsumer {49public: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 63private:64  bool HandleModuleRemark(const clang::Diagnostic &info);65  void SetCurrentModuleProgress(std::string module_name);66 67  typedef std::pair<clang::DiagnosticsEngine::Level, std::string>68      IDAndDiagnostic;69  std::vector<IDAndDiagnostic> m_diagnostics;70  std::unique_ptr<clang::DiagnosticOptions> m_diag_opts;71  /// Output string filled by m_os. Will be reused for different diagnostics.72  std::string m_output;73  /// Output stream of m_diag_printer.74  std::unique_ptr<llvm::raw_string_ostream> m_os;75  /// The DiagnosticPrinter used for creating the full diagnostic messages76  /// that are stored in m_diagnostics.77  std::unique_ptr<clang::TextDiagnosticPrinter> m_diag_printer;78  /// A Progress with explicitly managed lifetime.79  std::unique_ptr<Progress> m_current_progress_up;80  std::vector<std::string> m_module_build_stack;81};82 83/// The private implementation of our ClangModulesDeclVendor.  Contains all the84/// Clang state required to load modules.85class ClangModulesDeclVendorImpl : public ClangModulesDeclVendor {86public:87  ClangModulesDeclVendorImpl(88      std::unique_ptr<clang::DiagnosticOptions> diagnostic_options,89      llvm::IntrusiveRefCntPtr<clang::DiagnosticsEngine> diagnostics_engine,90      std::shared_ptr<clang::CompilerInvocation> compiler_invocation,91      std::unique_ptr<clang::CompilerInstance> compiler_instance,92      std::unique_ptr<clang::Parser> parser);93 94  ~ClangModulesDeclVendorImpl() override = default;95 96  llvm::Error AddModule(const SourceModule &module,97                        ModuleVector *exported_modules) override;98 99  llvm::Error AddModulesForCompileUnit(CompileUnit &cu,100                                       ModuleVector &exported_modules) override;101 102  uint32_t FindDecls(ConstString name, bool append, uint32_t max_matches,103                     std::vector<CompilerDecl> &decls) override;104 105  void ForEachMacro(106      const ModuleVector &modules,107      std::function<bool(llvm::StringRef, llvm::StringRef)> handler) override;108 109private:110  typedef llvm::DenseSet<ModuleID> ExportedModuleSet;111  void ReportModuleExportsHelper(ExportedModuleSet &exports,112                                 clang::Module *module);113 114  void ReportModuleExports(ModuleVector &exports, clang::Module *module);115 116  clang::ModuleLoadResult DoGetModule(clang::ModuleIdPath path,117                                      bool make_visible);118 119  bool m_enabled = false;120 121  std::unique_ptr<clang::DiagnosticOptions> m_diagnostic_options;122  llvm::IntrusiveRefCntPtr<clang::DiagnosticsEngine> m_diagnostics_engine;123  std::shared_ptr<clang::CompilerInvocation> m_compiler_invocation;124  std::unique_ptr<clang::CompilerInstance> m_compiler_instance;125  std::unique_ptr<clang::Parser> m_parser;126  size_t m_source_location_index =127      0; // used to give name components fake SourceLocations128 129  typedef std::vector<ConstString> ImportedModule;130  typedef std::map<ImportedModule, clang::Module *> ImportedModuleMap;131  typedef llvm::DenseSet<ModuleID> ImportedModuleSet;132  ImportedModuleMap m_imported_modules;133  ImportedModuleSet m_user_imported_modules;134  // We assume that every ASTContext has an TypeSystemClang, so we also store135  // a custom TypeSystemClang for our internal ASTContext.136  std::shared_ptr<TypeSystemClang> m_ast_context;137};138} // anonymous namespace139 140StoringDiagnosticConsumer::StoringDiagnosticConsumer() {141  m_diag_opts = std::make_unique<clang::DiagnosticOptions>();142  m_os = std::make_unique<llvm::raw_string_ostream>(m_output);143  m_diag_printer =144      std::make_unique<clang::TextDiagnosticPrinter>(*m_os, *m_diag_opts);145}146 147void StoringDiagnosticConsumer::HandleDiagnostic(148    clang::DiagnosticsEngine::Level DiagLevel, const clang::Diagnostic &info) {149  if (HandleModuleRemark(info))150    return;151 152  // Print the diagnostic to m_output.153  m_output.clear();154  m_diag_printer->HandleDiagnostic(DiagLevel, info);155 156  // Store the diagnostic for later.157  m_diagnostics.push_back(IDAndDiagnostic(DiagLevel, m_output));158}159 160void StoringDiagnosticConsumer::ClearDiagnostics() { m_diagnostics.clear(); }161 162void StoringDiagnosticConsumer::DumpDiagnostics(Stream &error_stream) {163  for (IDAndDiagnostic &diag : m_diagnostics) {164    switch (diag.first) {165    default:166      error_stream.PutCString(diag.second);167      error_stream.PutChar('\n');168      break;169    case clang::DiagnosticsEngine::Level::Ignored:170      break;171    }172  }173}174 175void StoringDiagnosticConsumer::BeginSourceFile(176    const clang::LangOptions &LangOpts, const clang::Preprocessor *PP) {177  m_diag_printer->BeginSourceFile(LangOpts, PP);178}179 180void StoringDiagnosticConsumer::EndSourceFile() {181  m_current_progress_up = nullptr;182  m_diag_printer->EndSourceFile();183}184 185bool StoringDiagnosticConsumer::HandleModuleRemark(186    const clang::Diagnostic &info) {187  Log *log = GetLog(LLDBLog::Types | LLDBLog::Expressions);188  switch (info.getID()) {189  case clang::diag::remark_module_build: {190    const auto &module_name = info.getArgStdStr(0);191    SetCurrentModuleProgress(module_name);192    m_module_build_stack.push_back(module_name);193 194    const auto &module_path = info.getArgStdStr(1);195    LLDB_LOG(log, "Building Clang module {0} as {1}", module_name, module_path);196    return true;197  }198  case clang::diag::remark_module_build_done: {199    // The current module is done.200    m_module_build_stack.pop_back();201    if (m_module_build_stack.empty()) {202      m_current_progress_up = nullptr;203    } else {204      // When the just completed module began building, a module that depends on205      // it ("module A") was effectively paused. Update the progress to re-show206      // "module A" as continuing to be built.207      const auto &resumed_module_name = m_module_build_stack.back();208      SetCurrentModuleProgress(resumed_module_name);209    }210 211    const auto &module_name = info.getArgStdStr(0);212    LLDB_LOG(log, "Finished building Clang module {0}", module_name);213    return true;214  }215  default:216    return false;217  }218}219 220void StoringDiagnosticConsumer::SetCurrentModuleProgress(221    std::string module_name) {222  if (!m_current_progress_up)223    m_current_progress_up =224        std::make_unique<Progress>("Building Clang modules");225 226  m_current_progress_up->Increment(1, std::move(module_name));227}228 229ClangModulesDeclVendor::ClangModulesDeclVendor()230    : DeclVendor(eClangModuleDeclVendor) {}231 232ClangModulesDeclVendor::~ClangModulesDeclVendor() = default;233 234ClangModulesDeclVendorImpl::ClangModulesDeclVendorImpl(235    std::unique_ptr<clang::DiagnosticOptions> diagnostic_options,236    llvm::IntrusiveRefCntPtr<clang::DiagnosticsEngine> diagnostics_engine,237    std::shared_ptr<clang::CompilerInvocation> compiler_invocation,238    std::unique_ptr<clang::CompilerInstance> compiler_instance,239    std::unique_ptr<clang::Parser> parser)240    : m_diagnostic_options(std::move(diagnostic_options)),241      m_diagnostics_engine(std::move(diagnostics_engine)),242      m_compiler_invocation(std::move(compiler_invocation)),243      m_compiler_instance(std::move(compiler_instance)),244      m_parser(std::move(parser)) {245 246  // Initialize our TypeSystemClang.247  m_ast_context =248      std::make_shared<TypeSystemClang>("ClangModulesDeclVendor ASTContext",249                                        m_compiler_instance->getASTContext());250}251 252void ClangModulesDeclVendorImpl::ReportModuleExportsHelper(253    ExportedModuleSet &exports, clang::Module *module) {254  if (exports.count(reinterpret_cast<ClangModulesDeclVendor::ModuleID>(module)))255    return;256 257  exports.insert(reinterpret_cast<ClangModulesDeclVendor::ModuleID>(module));258 259  llvm::SmallVector<clang::Module *, 2> sub_exports;260 261  module->getExportedModules(sub_exports);262 263  for (clang::Module *module : sub_exports)264    ReportModuleExportsHelper(exports, module);265}266 267void ClangModulesDeclVendorImpl::ReportModuleExports(268    ClangModulesDeclVendor::ModuleVector &exports, clang::Module *module) {269  ExportedModuleSet exports_set;270 271  ReportModuleExportsHelper(exports_set, module);272 273  for (ModuleID module : exports_set)274    exports.push_back(module);275}276 277llvm::Error278ClangModulesDeclVendorImpl::AddModule(const SourceModule &module,279                                      ModuleVector *exported_modules) {280  // Fail early.281 282  if (m_compiler_instance->hadModuleLoaderFatalFailure())283    return llvm::createStringError(284        "couldn't load a module because the module loader is in a fatal state");285 286  // Check if we've already imported this module.287 288  std::vector<ConstString> imported_module;289 290  for (ConstString path_component : module.path)291    imported_module.push_back(path_component);292 293  {294    ImportedModuleMap::iterator mi = m_imported_modules.find(imported_module);295 296    if (mi != m_imported_modules.end()) {297      if (exported_modules)298        ReportModuleExports(*exported_modules, mi->second);299      return llvm::Error::success();300    }301  }302 303  clang::HeaderSearch &HS =304    m_compiler_instance->getPreprocessor().getHeaderSearchInfo();305 306  if (module.search_path) {307    auto path_begin = llvm::sys::path::begin(module.search_path.GetStringRef());308    auto path_end = llvm::sys::path::end(module.search_path.GetStringRef());309    auto sysroot_begin = llvm::sys::path::begin(module.sysroot.GetStringRef());310    auto sysroot_end = llvm::sys::path::end(module.sysroot.GetStringRef());311    // FIXME: Use C++14 std::equal(it, it, it, it) variant once it's available.312    bool is_system_module = (std::distance(path_begin, path_end) >=313                             std::distance(sysroot_begin, sysroot_end)) &&314                            std::equal(sysroot_begin, sysroot_end, path_begin);315    // No need to inject search paths to modules in the sysroot.316    if (!is_system_module) {317      bool is_system = true;318      bool is_framework = false;319      auto dir = HS.getFileMgr().getOptionalDirectoryRef(320          module.search_path.GetStringRef());321      if (!dir)322        return llvm::createStringError(323            "couldn't find module search path directory %s",324            module.search_path.GetCString());325 326      auto file = HS.lookupModuleMapFile(*dir, is_framework);327      if (!file)328        return llvm::createStringError("couldn't find modulemap file in %s",329                                       module.search_path.GetCString());330 331      if (HS.parseAndLoadModuleMapFile(*file, is_system))332        return llvm::createStringError(333            "failed to parse and load modulemap file in %s",334            module.search_path.GetCString());335    }336  }337 338  if (!HS.lookupModule(module.path.front().GetStringRef()))339    return llvm::createStringError("header search couldn't locate module '%s'",340                                   module.path.front().AsCString());341 342  llvm::SmallVector<clang::IdentifierLoc, 4> clang_path;343 344  {345    clang::SourceManager &source_manager =346        m_compiler_instance->getASTContext().getSourceManager();347 348    for (ConstString path_component : module.path) {349      clang_path.emplace_back(350          source_manager.getLocForStartOfFile(source_manager.getMainFileID())351              .getLocWithOffset(m_source_location_index++),352          &m_compiler_instance->getASTContext().Idents.get(353              path_component.GetStringRef()));354    }355  }356 357  StoringDiagnosticConsumer *diagnostic_consumer =358      static_cast<StoringDiagnosticConsumer *>(359          m_compiler_instance->getDiagnostics().getClient());360 361  diagnostic_consumer->ClearDiagnostics();362 363  clang::Module *top_level_module = DoGetModule(clang_path.front(), false);364 365  if (!top_level_module) {366    lldb_private::StreamString error_stream;367    diagnostic_consumer->DumpDiagnostics(error_stream);368 369    return llvm::createStringError(llvm::formatv(370        "couldn't load top-level module {0}:\n{1}",371        module.path.front().GetStringRef(), error_stream.GetString()));372  }373 374  clang::Module *submodule = top_level_module;375 376  for (auto &component : llvm::ArrayRef<ConstString>(module.path).drop_front()) {377    clang::Module *found = submodule->findSubmodule(component.GetStringRef());378    if (!found) {379      lldb_private::StreamString error_stream;380      diagnostic_consumer->DumpDiagnostics(error_stream);381 382      return llvm::createStringError(llvm::formatv(383          "couldn't load submodule '{0}' of module '{1}':\n{2}",384          component.GetStringRef(), submodule->getFullModuleName(),385          error_stream.GetString()));386    }387 388    submodule = found;389  }390 391  // If we didn't make the submodule visible here, Clang wouldn't allow LLDB to392  // pick any of the decls in the submodules during C++ name lookup.393  if (submodule)394    m_compiler_instance->makeModuleVisible(395        submodule, clang::Module::NameVisibilityKind::AllVisible,396        /*ImportLoc=*/{});397 398  clang::Module *requested_module = DoGetModule(clang_path, true);399 400  if (requested_module != nullptr) {401    if (exported_modules)402      ReportModuleExports(*exported_modules, requested_module);403 404    m_imported_modules[imported_module] = requested_module;405 406    m_enabled = true;407 408    return llvm::Error::success();409  }410 411  return llvm::createStringError(412      llvm::formatv("unknown error while loading module {0}\n",413                    module.path.front().GetStringRef()));414}415 416bool ClangModulesDeclVendor::LanguageSupportsClangModules(417    lldb::LanguageType language) {418  switch (language) {419  default:420    return false;421  case lldb::LanguageType::eLanguageTypeC:422  case lldb::LanguageType::eLanguageTypeC11:423  case lldb::LanguageType::eLanguageTypeC89:424  case lldb::LanguageType::eLanguageTypeC99:425  case lldb::LanguageType::eLanguageTypeC_plus_plus:426  case lldb::LanguageType::eLanguageTypeC_plus_plus_03:427  case lldb::LanguageType::eLanguageTypeC_plus_plus_11:428  case lldb::LanguageType::eLanguageTypeC_plus_plus_14:429  case lldb::LanguageType::eLanguageTypeObjC:430  case lldb::LanguageType::eLanguageTypeObjC_plus_plus:431    return true;432  }433}434 435llvm::Error ClangModulesDeclVendorImpl::AddModulesForCompileUnit(436    CompileUnit &cu, ClangModulesDeclVendor::ModuleVector &exported_modules) {437  if (!LanguageSupportsClangModules(cu.GetLanguage()))438    return llvm::Error::success();439 440  llvm::Error errors = llvm::Error::success();441 442  for (auto &imported_module : cu.GetImportedModules())443    if (auto err = AddModule(imported_module, &exported_modules))444      errors = llvm::joinErrors(std::move(errors), std::move(err));445 446  return errors;447}448 449// ClangImporter::lookupValue450 451uint32_t452ClangModulesDeclVendorImpl::FindDecls(ConstString name, bool append,453                                      uint32_t max_matches,454                                      std::vector<CompilerDecl> &decls) {455  if (!m_enabled)456    return 0;457 458  if (!append)459    decls.clear();460 461  clang::IdentifierInfo &ident =462      m_compiler_instance->getASTContext().Idents.get(name.GetStringRef());463 464  clang::LookupResult lookup_result(465      m_compiler_instance->getSema(), clang::DeclarationName(&ident),466      clang::SourceLocation(), clang::Sema::LookupOrdinaryName);467 468  m_compiler_instance->getSema().LookupName(469      lookup_result,470      m_compiler_instance->getSema().getScopeForContext(471          m_compiler_instance->getASTContext().getTranslationUnitDecl()));472 473  uint32_t num_matches = 0;474 475  for (clang::NamedDecl *named_decl : lookup_result) {476    if (num_matches >= max_matches)477      return num_matches;478 479    decls.push_back(m_ast_context->GetCompilerDecl(named_decl));480    ++num_matches;481  }482 483  return num_matches;484}485 486void ClangModulesDeclVendorImpl::ForEachMacro(487    const ClangModulesDeclVendor::ModuleVector &modules,488    std::function<bool(llvm::StringRef, llvm::StringRef)> handler) {489  if (!m_enabled)490    return;491 492  typedef std::map<ModuleID, ssize_t> ModulePriorityMap;493  ModulePriorityMap module_priorities;494 495  ssize_t priority = 0;496 497  for (ModuleID module : modules)498    module_priorities[module] = priority++;499 500  if (m_compiler_instance->getPreprocessor().getExternalSource()) {501    m_compiler_instance->getPreprocessor()502        .getExternalSource()503        ->ReadDefinedMacros();504  }505 506  for (clang::Preprocessor::macro_iterator507           mi = m_compiler_instance->getPreprocessor().macro_begin(),508           me = m_compiler_instance->getPreprocessor().macro_end();509       mi != me; ++mi) {510    const clang::IdentifierInfo *ii = nullptr;511 512    {513      if (clang::IdentifierInfoLookup *lookup =514              m_compiler_instance->getPreprocessor()515                  .getIdentifierTable()516                  .getExternalIdentifierLookup()) {517        lookup->get(mi->first->getName());518      }519      if (!ii)520        ii = mi->first;521    }522 523    ssize_t found_priority = -1;524    clang::MacroInfo *macro_info = nullptr;525 526    for (clang::ModuleMacro *module_macro :527         m_compiler_instance->getPreprocessor().getLeafModuleMacros(ii)) {528      clang::Module *module = module_macro->getOwningModule();529 530      {531        ModulePriorityMap::iterator pi =532            module_priorities.find(reinterpret_cast<ModuleID>(module));533 534        if (pi != module_priorities.end() && pi->second > found_priority) {535          macro_info = module_macro->getMacroInfo();536          found_priority = pi->second;537        }538      }539 540      clang::Module *top_level_module = module->getTopLevelModule();541 542      if (top_level_module != module) {543        ModulePriorityMap::iterator pi = module_priorities.find(544            reinterpret_cast<ModuleID>(top_level_module));545 546        if ((pi != module_priorities.end()) && pi->second > found_priority) {547          macro_info = module_macro->getMacroInfo();548          found_priority = pi->second;549        }550      }551    }552 553    if (macro_info) {554      std::string macro_expansion = "#define ";555      llvm::StringRef macro_identifier = mi->first->getName();556      macro_expansion.append(macro_identifier.str());557 558      {559        if (macro_info->isFunctionLike()) {560          macro_expansion.append("(");561 562          bool first_arg = true;563 564          for (auto pi = macro_info->param_begin(),565                    pe = macro_info->param_end();566               pi != pe; ++pi) {567            if (!first_arg)568              macro_expansion.append(", ");569            else570              first_arg = false;571 572            macro_expansion.append((*pi)->getName().str());573          }574 575          if (macro_info->isC99Varargs()) {576            if (first_arg)577              macro_expansion.append("...");578            else579              macro_expansion.append(", ...");580          } else if (macro_info->isGNUVarargs())581            macro_expansion.append("...");582 583          macro_expansion.append(")");584        }585 586        macro_expansion.append(" ");587 588        bool first_token = true;589 590        for (clang::MacroInfo::const_tokens_iterator591                 ti = macro_info->tokens_begin(),592                 te = macro_info->tokens_end();593             ti != te; ++ti) {594          if (!first_token)595            macro_expansion.append(" ");596          else597            first_token = false;598 599          if (ti->isLiteral()) {600            if (const char *literal_data = ti->getLiteralData()) {601              std::string token_str(literal_data, ti->getLength());602              macro_expansion.append(token_str);603            } else {604              bool invalid = false;605              const char *literal_source =606                  m_compiler_instance->getSourceManager().getCharacterData(607                      ti->getLocation(), &invalid);608 609              if (invalid) {610                lldbassert(0 && "Unhandled token kind");611                macro_expansion.append("<unknown literal value>");612              } else {613                macro_expansion.append(614                    std::string(literal_source, ti->getLength()));615              }616            }617          } else if (const char *punctuator_spelling =618                         clang::tok::getPunctuatorSpelling(ti->getKind())) {619            macro_expansion.append(punctuator_spelling);620          } else if (const char *keyword_spelling =621                         clang::tok::getKeywordSpelling(ti->getKind())) {622            macro_expansion.append(keyword_spelling);623          } else {624            switch (ti->getKind()) {625            case clang::tok::TokenKind::identifier:626              macro_expansion.append(ti->getIdentifierInfo()->getName().str());627              break;628            case clang::tok::TokenKind::raw_identifier:629              macro_expansion.append(ti->getRawIdentifier().str());630              break;631            default:632              macro_expansion.append(ti->getName());633              break;634            }635          }636        }637 638        if (handler(macro_identifier, macro_expansion)) {639          return;640        }641      }642    }643  }644}645 646clang::ModuleLoadResult647ClangModulesDeclVendorImpl::DoGetModule(clang::ModuleIdPath path,648                                        bool make_visible) {649  clang::Module::NameVisibilityKind visibility =650      make_visible ? clang::Module::AllVisible : clang::Module::Hidden;651 652  const bool is_inclusion_directive = false;653 654  return m_compiler_instance->loadModule(path.front().getLoc(), path,655                                         visibility, is_inclusion_directive);656}657 658static const char *ModuleImportBufferName = "LLDBModulesMemoryBuffer";659 660lldb_private::ClangModulesDeclVendor *661ClangModulesDeclVendor::Create(Target &target) {662  // FIXME we should insure programmatically that the expression parser's663  // compiler and the modules runtime's664  // compiler are both initialized in the same way – preferably by the same665  // code.666 667  if (!target.GetPlatform()->SupportsModules())668    return nullptr;669 670  const ArchSpec &arch = target.GetArchitecture();671 672  std::vector<std::string> compiler_invocation_arguments = {673      "clang",674      "-fmodules",675      "-fimplicit-module-maps",676      "-fcxx-modules",677      "-fsyntax-only",678      "-femit-all-decls",679      "-target",680      arch.GetTriple().str(),681      "-fmodules-validate-system-headers",682      "-Werror=non-modular-include-in-framework-module",683      "-Xclang=-fincremental-extensions",684      "-Rmodule-build"};685 686  target.GetPlatform()->AddClangModuleCompilationOptions(687      &target, compiler_invocation_arguments);688 689  compiler_invocation_arguments.push_back(ModuleImportBufferName);690 691  // Add additional search paths with { "-I", path } or { "-F", path } here.692 693  {694    llvm::SmallString<128> path;695    const auto &props = ModuleList::GetGlobalModuleListProperties();696    props.GetClangModulesCachePath().GetPath(path);697    std::string module_cache_argument("-fmodules-cache-path=");698    module_cache_argument.append(std::string(path.str()));699    compiler_invocation_arguments.push_back(module_cache_argument);700  }701 702  FileSpecList module_search_paths = target.GetClangModuleSearchPaths();703 704  for (size_t spi = 0, spe = module_search_paths.GetSize(); spi < spe; ++spi) {705    const FileSpec &search_path = module_search_paths.GetFileSpecAtIndex(spi);706 707    std::string search_path_argument = "-I";708    search_path_argument.append(search_path.GetPath());709 710    compiler_invocation_arguments.push_back(search_path_argument);711  }712 713  {714    FileSpec clang_resource_dir = GetClangResourceDir();715 716    if (FileSystem::Instance().IsDirectory(clang_resource_dir.GetPath())) {717      compiler_invocation_arguments.push_back("-resource-dir");718      compiler_invocation_arguments.push_back(clang_resource_dir.GetPath());719    }720  }721 722  std::vector<const char *> compiler_invocation_argument_cstrs;723  compiler_invocation_argument_cstrs.reserve(724      compiler_invocation_arguments.size());725  for (const std::string &arg : compiler_invocation_arguments)726    compiler_invocation_argument_cstrs.push_back(arg.c_str());727 728  auto diag_options_up =729      clang::CreateAndPopulateDiagOpts(compiler_invocation_argument_cstrs);730  llvm::IntrusiveRefCntPtr<clang::DiagnosticsEngine> diagnostics_engine =731      clang::CompilerInstance::createDiagnostics(732          *FileSystem::Instance().GetVirtualFileSystem(), *diag_options_up,733          new StoringDiagnosticConsumer);734 735  Log *log = GetLog(LLDBLog::Expressions);736  LLDB_LOG(log, "ClangModulesDeclVendor's compiler flags {0:$[ ]}",737           llvm::make_range(compiler_invocation_arguments.begin(),738                            compiler_invocation_arguments.end()));739 740  clang::CreateInvocationOptions CIOpts;741  CIOpts.Diags = diagnostics_engine;742  std::shared_ptr<clang::CompilerInvocation> invocation =743      clang::createInvocation(compiler_invocation_argument_cstrs,744                              std::move(CIOpts));745 746  if (!invocation)747    return nullptr;748 749  std::unique_ptr<llvm::MemoryBuffer> source_buffer =750      llvm::MemoryBuffer::getMemBuffer(751          "extern int __lldb __attribute__((unavailable));",752          ModuleImportBufferName);753 754  invocation->getPreprocessorOpts().addRemappedFile(ModuleImportBufferName,755                                                    source_buffer.release());756 757  auto instance = std::make_unique<clang::CompilerInstance>(invocation);758 759  // Make sure clang uses the same VFS as LLDB.760  instance->setVirtualFileSystem(FileSystem::Instance().GetVirtualFileSystem());761  instance->createFileManager();762  instance->setDiagnostics(diagnostics_engine);763 764  std::unique_ptr<clang::FrontendAction> action(new clang::SyntaxOnlyAction);765 766  instance->setTarget(clang::TargetInfo::CreateTargetInfo(767      *diagnostics_engine, instance->getInvocation().getTargetOpts()));768 769  if (!instance->hasTarget())770    return nullptr;771 772  instance->getTarget().adjust(*diagnostics_engine, instance->getLangOpts(),773                               /*AuxTarget=*/nullptr);774 775  if (!action->BeginSourceFile(*instance,776                               instance->getFrontendOpts().Inputs[0]))777    return nullptr;778 779  instance->createASTReader();780 781  instance->createSema(action->getTranslationUnitKind(), nullptr);782 783  const bool skipFunctionBodies = false;784  std::unique_ptr<clang::Parser> parser(new clang::Parser(785      instance->getPreprocessor(), instance->getSema(), skipFunctionBodies));786 787  instance->getPreprocessor().EnterMainSourceFile();788  parser->Initialize();789 790  clang::Parser::DeclGroupPtrTy parsed;791  auto ImportState = clang::Sema::ModuleImportState::NotACXX20Module;792  while (!parser->ParseTopLevelDecl(parsed, ImportState))793    ;794 795  return new ClangModulesDeclVendorImpl(796      std::move(diag_options_up), std::move(diagnostics_engine),797      std::move(invocation), std::move(instance), std::move(parser));798}799