diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2022-03-20 11:40:34 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2022-05-14 11:43:05 +0000 |
commit | 349cc55c9796c4596a5b9904cd3281af295f878f (patch) | |
tree | 410c5a785075730a35f1272ca6a7adf72222ad03 /contrib/llvm-project/clang/lib/Frontend/CompilerInstance.cpp | |
parent | cb2ae6163174b90e999326ecec3699ee093a5d43 (diff) | |
parent | c0981da47d5696fe36474fcf86b4ce03ae3ff818 (diff) | |
download | src-349cc55c9796c4596a5b9904cd3281af295f878f.tar.gz src-349cc55c9796c4596a5b9904cd3281af295f878f.zip |
Diffstat (limited to 'contrib/llvm-project/clang/lib/Frontend/CompilerInstance.cpp')
-rw-r--r-- | contrib/llvm-project/clang/lib/Frontend/CompilerInstance.cpp | 438 |
1 files changed, 259 insertions, 179 deletions
diff --git a/contrib/llvm-project/clang/lib/Frontend/CompilerInstance.cpp b/contrib/llvm-project/clang/lib/Frontend/CompilerInstance.cpp index c642af1849bc..1432607204bd 100644 --- a/contrib/llvm-project/clang/lib/Frontend/CompilerInstance.cpp +++ b/contrib/llvm-project/clang/lib/Frontend/CompilerInstance.cpp @@ -23,6 +23,7 @@ #include "clang/Frontend/FrontendAction.h" #include "clang/Frontend/FrontendActions.h" #include "clang/Frontend/FrontendDiagnostic.h" +#include "clang/Frontend/FrontendPluginRegistry.h" #include "clang/Frontend/LogDiagnosticPrinter.h" #include "clang/Frontend/SerializedDiagnosticPrinter.h" #include "clang/Frontend/TextDiagnosticPrinter.h" @@ -558,6 +559,54 @@ void CompilerInstance::createASTContext() { // ExternalASTSource +namespace { +// Helper to recursively read the module names for all modules we're adding. +// We mark these as known and redirect any attempt to load that module to +// the files we were handed. +struct ReadModuleNames : ASTReaderListener { + Preprocessor &PP; + llvm::SmallVector<std::string, 8> LoadedModules; + + ReadModuleNames(Preprocessor &PP) : PP(PP) {} + + void ReadModuleName(StringRef ModuleName) override { + // Keep the module name as a string for now. It's not safe to create a new + // IdentifierInfo from an ASTReader callback. + LoadedModules.push_back(ModuleName.str()); + } + + void registerAll() { + ModuleMap &MM = PP.getHeaderSearchInfo().getModuleMap(); + for (const std::string &LoadedModule : LoadedModules) + MM.cacheModuleLoad(*PP.getIdentifierInfo(LoadedModule), + MM.findModule(LoadedModule)); + LoadedModules.clear(); + } + + void markAllUnavailable() { + for (const std::string &LoadedModule : LoadedModules) { + if (Module *M = PP.getHeaderSearchInfo().getModuleMap().findModule( + LoadedModule)) { + M->HasIncompatibleModuleFile = true; + + // Mark module as available if the only reason it was unavailable + // was missing headers. + SmallVector<Module *, 2> Stack; + Stack.push_back(M); + while (!Stack.empty()) { + Module *Current = Stack.pop_back_val(); + if (Current->IsUnimportable) continue; + Current->IsAvailable = true; + Stack.insert(Stack.end(), + Current->submodule_begin(), Current->submodule_end()); + } + } + } + LoadedModules.clear(); + } +}; +} // namespace + void CompilerInstance::createPCHExternalASTSource( StringRef Path, DisableValidationForModuleKind DisableValidation, bool AllowPCHWithCompilerErrors, void *DeserializationListener, @@ -602,6 +651,11 @@ IntrusiveRefCntPtr<ASTReader> CompilerInstance::createPCHExternalASTSource( for (auto &Listener : DependencyCollectors) Listener->attachToASTReader(*Reader); + auto Listener = std::make_unique<ReadModuleNames>(PP); + auto &ListenerRef = *Listener; + ASTReader::ListenerScope ReadModuleNamesListener(*Reader, + std::move(Listener)); + switch (Reader->ReadAST(Path, Preamble ? serialization::MK_Preamble : serialization::MK_PCH, @@ -611,6 +665,7 @@ IntrusiveRefCntPtr<ASTReader> CompilerInstance::createPCHExternalASTSource( // Set the predefines buffer as suggested by the PCH reader. Typically, the // predefines buffer will be empty. PP.setPredefines(Reader->getSuggestedPredefines()); + ListenerRef.registerAll(); return Reader; case ASTReader::Failure: @@ -626,6 +681,7 @@ IntrusiveRefCntPtr<ASTReader> CompilerInstance::createPCHExternalASTSource( break; } + ListenerRef.markAllUnavailable(); Context.setExternalSource(nullptr); return nullptr; } @@ -1029,6 +1085,27 @@ bool CompilerInstance::ExecuteAction(FrontendAction &Act) { return !getDiagnostics().getClient()->getNumErrors(); } +void CompilerInstance::LoadRequestedPlugins() { + // Load any requested plugins. + for (const std::string &Path : getFrontendOpts().Plugins) { + std::string Error; + if (llvm::sys::DynamicLibrary::LoadLibraryPermanently(Path.c_str(), &Error)) + getDiagnostics().Report(diag::err_fe_unable_to_load_plugin) + << Path << Error; + } + + // Check if any of the loaded plugins replaces the main AST action + for (const FrontendPluginRegistry::entry &Plugin : + FrontendPluginRegistry::entries()) { + std::unique_ptr<PluginASTAction> P(Plugin.instantiate()); + if (P->getActionType() == PluginASTAction::ReplaceAction) { + getFrontendOpts().ProgramAction = clang::frontend::PluginAction; + getFrontendOpts().ActionName = Plugin.getName().str(); + break; + } + } +} + /// Determine the appropriate source input kind based on language /// options. static Language getLanguageFromOptions(const LangOptions &LangOpts) { @@ -1077,14 +1154,12 @@ compileModuleImpl(CompilerInstance &ImportingInstance, SourceLocation ImportLoc, // Remove any macro definitions that are explicitly ignored by the module. // They aren't supposed to affect how the module is built anyway. HeaderSearchOptions &HSOpts = Invocation->getHeaderSearchOpts(); - PPOpts.Macros.erase( - std::remove_if(PPOpts.Macros.begin(), PPOpts.Macros.end(), - [&HSOpts](const std::pair<std::string, bool> &def) { + llvm::erase_if( + PPOpts.Macros, [&HSOpts](const std::pair<std::string, bool> &def) { StringRef MacroDef = def.first; return HSOpts.ModulesIgnoreMacros.count( llvm::CachedHashString(MacroDef.split('=').first)) > 0; - }), - PPOpts.Macros.end()); + }); // If the original compiler invocation had -fmodule-name, pass it through. Invocation->getLangOpts()->ModuleName = @@ -1264,23 +1339,75 @@ static bool compileModule(CompilerInstance &ImportingInstance, return Result; } +/// Read the AST right after compiling the module. +static bool readASTAfterCompileModule(CompilerInstance &ImportingInstance, + SourceLocation ImportLoc, + SourceLocation ModuleNameLoc, + Module *Module, StringRef ModuleFileName, + bool *OutOfDate) { + DiagnosticsEngine &Diags = ImportingInstance.getDiagnostics(); + + unsigned ModuleLoadCapabilities = ASTReader::ARR_Missing; + if (OutOfDate) + ModuleLoadCapabilities |= ASTReader::ARR_OutOfDate; + + // Try to read the module file, now that we've compiled it. + ASTReader::ASTReadResult ReadResult = + ImportingInstance.getASTReader()->ReadAST( + ModuleFileName, serialization::MK_ImplicitModule, ImportLoc, + ModuleLoadCapabilities); + if (ReadResult == ASTReader::Success) + return true; + + // The caller wants to handle out-of-date failures. + if (OutOfDate && ReadResult == ASTReader::OutOfDate) { + *OutOfDate = true; + return false; + } + + // The ASTReader didn't diagnose the error, so conservatively report it. + if (ReadResult == ASTReader::Missing || !Diags.hasErrorOccurred()) + Diags.Report(ModuleNameLoc, diag::err_module_not_built) + << Module->Name << SourceRange(ImportLoc, ModuleNameLoc); + + return false; +} + /// Compile a module in a separate compiler instance and read the AST, /// returning true if the module compiles without errors. +static bool compileModuleAndReadASTImpl(CompilerInstance &ImportingInstance, + SourceLocation ImportLoc, + SourceLocation ModuleNameLoc, + Module *Module, + StringRef ModuleFileName) { + if (!compileModule(ImportingInstance, ModuleNameLoc, Module, + ModuleFileName)) { + ImportingInstance.getDiagnostics().Report(ModuleNameLoc, + diag::err_module_not_built) + << Module->Name << SourceRange(ImportLoc, ModuleNameLoc); + return false; + } + + return readASTAfterCompileModule(ImportingInstance, ImportLoc, ModuleNameLoc, + Module, ModuleFileName, + /*OutOfDate=*/nullptr); +} + +/// Compile a module in a separate compiler instance and read the AST, +/// returning true if the module compiles without errors, using a lock manager +/// to avoid building the same module in multiple compiler instances. /// /// Uses a lock file manager and exponential backoff to reduce the chances that /// multiple instances will compete to create the same module. On timeout, /// deletes the lock file in order to avoid deadlock from crashing processes or /// bugs in the lock file manager. -static bool compileModuleAndReadAST(CompilerInstance &ImportingInstance, - SourceLocation ImportLoc, - SourceLocation ModuleNameLoc, - Module *Module, StringRef ModuleFileName) { +static bool compileModuleAndReadASTBehindLock( + CompilerInstance &ImportingInstance, SourceLocation ImportLoc, + SourceLocation ModuleNameLoc, Module *Module, StringRef ModuleFileName) { DiagnosticsEngine &Diags = ImportingInstance.getDiagnostics(); - auto diagnoseBuildFailure = [&] { - Diags.Report(ModuleNameLoc, diag::err_module_not_built) - << Module->Name << SourceRange(ImportLoc, ModuleNameLoc); - }; + Diags.Report(ModuleNameLoc, diag::remark_module_lock) + << ModuleFileName << Module->Name; // FIXME: have LockFileManager return an error_code so that we can // avoid the mkdir when the directory already exists. @@ -1288,7 +1415,6 @@ static bool compileModuleAndReadAST(CompilerInstance &ImportingInstance, llvm::sys::fs::create_directories(Dir); while (1) { - unsigned ModuleLoadCapabilities = ASTReader::ARR_Missing; llvm::LockFileManager Locked(ModuleFileName); switch (Locked) { case llvm::LockFileManager::LFS_Error: @@ -1302,58 +1428,64 @@ static bool compileModuleAndReadAST(CompilerInstance &ImportingInstance, LLVM_FALLTHROUGH; case llvm::LockFileManager::LFS_Owned: // We're responsible for building the module ourselves. - if (!compileModule(ImportingInstance, ModuleNameLoc, Module, - ModuleFileName)) { - diagnoseBuildFailure(); - return false; - } - break; + return compileModuleAndReadASTImpl(ImportingInstance, ImportLoc, + ModuleNameLoc, Module, ModuleFileName); case llvm::LockFileManager::LFS_Shared: - // Someone else is responsible for building the module. Wait for them to - // finish. - switch (Locked.waitForUnlock()) { - case llvm::LockFileManager::Res_Success: - ModuleLoadCapabilities |= ASTReader::ARR_OutOfDate; - break; - case llvm::LockFileManager::Res_OwnerDied: - continue; // try again to get the lock. - case llvm::LockFileManager::Res_Timeout: - // Since ModuleCache takes care of correctness, we try waiting for - // another process to complete the build so clang does not do it done - // twice. If case of timeout, build it ourselves. - Diags.Report(ModuleNameLoc, diag::remark_module_lock_timeout) - << Module->Name; - // Clear the lock file so that future invocations can make progress. - Locked.unsafeRemoveLockFile(); - continue; - } - break; + break; // The interesting case. } - // Try to read the module file, now that we've compiled it. - ASTReader::ASTReadResult ReadResult = - ImportingInstance.getASTReader()->ReadAST( - ModuleFileName, serialization::MK_ImplicitModule, ImportLoc, - ModuleLoadCapabilities); - - if (ReadResult == ASTReader::OutOfDate && - Locked == llvm::LockFileManager::LFS_Shared) { - // The module may be out of date in the presence of file system races, - // or if one of its imports depends on header search paths that are not - // consistent with this ImportingInstance. Try again... + // Someone else is responsible for building the module. Wait for them to + // finish. + switch (Locked.waitForUnlock()) { + case llvm::LockFileManager::Res_Success: + break; // The interesting case. + case llvm::LockFileManager::Res_OwnerDied: + continue; // try again to get the lock. + case llvm::LockFileManager::Res_Timeout: + // Since ModuleCache takes care of correctness, we try waiting for + // another process to complete the build so clang does not do it done + // twice. If case of timeout, build it ourselves. + Diags.Report(ModuleNameLoc, diag::remark_module_lock_timeout) + << Module->Name; + // Clear the lock file so that future invocations can make progress. + Locked.unsafeRemoveLockFile(); continue; - } else if (ReadResult == ASTReader::Missing) { - diagnoseBuildFailure(); - } else if (ReadResult != ASTReader::Success && - !Diags.hasErrorOccurred()) { - // The ASTReader didn't diagnose the error, so conservatively report it. - diagnoseBuildFailure(); } - return ReadResult == ASTReader::Success; + + // Read the module that was just written by someone else. + bool OutOfDate = false; + if (readASTAfterCompileModule(ImportingInstance, ImportLoc, ModuleNameLoc, + Module, ModuleFileName, &OutOfDate)) + return true; + if (!OutOfDate) + return false; + + // The module may be out of date in the presence of file system races, + // or if one of its imports depends on header search paths that are not + // consistent with this ImportingInstance. Try again... } } +/// Compile a module in a separate compiler instance and read the AST, +/// returning true if the module compiles without errors, potentially using a +/// lock manager to avoid building the same module in multiple compiler +/// instances. +static bool compileModuleAndReadAST(CompilerInstance &ImportingInstance, + SourceLocation ImportLoc, + SourceLocation ModuleNameLoc, + Module *Module, StringRef ModuleFileName) { + return ImportingInstance.getInvocation() + .getFrontendOpts() + .BuildingImplicitModuleUsesLock + ? compileModuleAndReadASTBehindLock(ImportingInstance, ImportLoc, + ModuleNameLoc, Module, + ModuleFileName) + : compileModuleAndReadASTImpl(ImportingInstance, ImportLoc, + ModuleNameLoc, Module, + ModuleFileName); +} + /// Diagnose differences between the current definition of the given /// configuration macro and the definition provided on the command line. static void checkConfigMacro(Preprocessor &PP, StringRef ConfigMacro, @@ -1555,52 +1687,6 @@ bool CompilerInstance::loadModuleFile(StringRef FileName) { *FrontendTimerGroup); llvm::TimeRegion TimeLoading(FrontendTimerGroup ? &Timer : nullptr); - // Helper to recursively read the module names for all modules we're adding. - // We mark these as known and redirect any attempt to load that module to - // the files we were handed. - struct ReadModuleNames : ASTReaderListener { - CompilerInstance &CI; - llvm::SmallVector<IdentifierInfo*, 8> LoadedModules; - - ReadModuleNames(CompilerInstance &CI) : CI(CI) {} - - void ReadModuleName(StringRef ModuleName) override { - LoadedModules.push_back( - CI.getPreprocessor().getIdentifierInfo(ModuleName)); - } - - void registerAll() { - ModuleMap &MM = CI.getPreprocessor().getHeaderSearchInfo().getModuleMap(); - for (auto *II : LoadedModules) - MM.cacheModuleLoad(*II, MM.findModule(II->getName())); - LoadedModules.clear(); - } - - void markAllUnavailable() { - for (auto *II : LoadedModules) { - if (Module *M = CI.getPreprocessor() - .getHeaderSearchInfo() - .getModuleMap() - .findModule(II->getName())) { - M->HasIncompatibleModuleFile = true; - - // Mark module as available if the only reason it was unavailable - // was missing headers. - SmallVector<Module *, 2> Stack; - Stack.push_back(M); - while (!Stack.empty()) { - Module *Current = Stack.pop_back_val(); - if (Current->IsUnimportable) continue; - Current->IsAvailable = true; - Stack.insert(Stack.end(), - Current->submodule_begin(), Current->submodule_end()); - } - } - } - LoadedModules.clear(); - } - }; - // If we don't already have an ASTReader, create one now. if (!TheASTReader) createASTReader(); @@ -1612,7 +1698,7 @@ bool CompilerInstance::loadModuleFile(StringRef FileName) { SourceLocation()) <= DiagnosticsEngine::Warning; - auto Listener = std::make_unique<ReadModuleNames>(*this); + auto Listener = std::make_unique<ReadModuleNames>(*PP); auto &ListenerRef = *Listener; ASTReader::ListenerScope ReadModuleNamesListener(*TheASTReader, std::move(Listener)); @@ -1691,7 +1777,8 @@ ModuleLoadResult CompilerInstance::findOrCompileModuleAndReadAST( SourceLocation ModuleNameLoc, bool IsInclusionDirective) { // Search for a module with the given name. HeaderSearch &HS = PP->getHeaderSearchInfo(); - Module *M = HS.lookupModule(ModuleName, true, !IsInclusionDirective); + Module *M = + HS.lookupModule(ModuleName, ImportLoc, true, !IsInclusionDirective); // Select the source and filename for loading the named module. std::string ModuleFilename; @@ -1750,7 +1837,7 @@ ModuleLoadResult CompilerInstance::findOrCompileModuleAndReadAST( // A prebuilt module is indexed as a ModuleFile; the Module does not exist // until the first call to ReadAST. Look it up now. - M = HS.lookupModule(ModuleName, true, !IsInclusionDirective); + M = HS.lookupModule(ModuleName, ImportLoc, true, !IsInclusionDirective); // Check whether M refers to the file in the prebuilt module path. if (M && M->getASTFile()) @@ -1873,7 +1960,7 @@ CompilerInstance::loadModule(SourceLocation ImportLoc, } else if (ModuleName == getLangOpts().CurrentModule) { // This is the module we're building. Module = PP->getHeaderSearchInfo().lookupModule( - ModuleName, /*AllowSearch*/ true, + ModuleName, ImportLoc, /*AllowSearch*/ true, /*AllowExtraModuleMapSearch*/ !IsInclusionDirective); /// FIXME: perhaps we should (a) look for a module using the module name // to file map (PrebuiltModuleFiles) and (b) diagnose if still not found? @@ -1903,90 +1990,84 @@ CompilerInstance::loadModule(SourceLocation ImportLoc, // Verify that the rest of the module path actually corresponds to // a submodule. bool MapPrivateSubModToTopLevel = false; - if (Path.size() > 1) { - for (unsigned I = 1, N = Path.size(); I != N; ++I) { - StringRef Name = Path[I].first->getName(); - clang::Module *Sub = Module->findSubmodule(Name); - - // If the user is requesting Foo.Private and it doesn't exist, try to - // match Foo_Private and emit a warning asking for the user to write - // @import Foo_Private instead. FIXME: remove this when existing clients - // migrate off of Foo.Private syntax. - if (!Sub && PP->getLangOpts().ImplicitModules && Name == "Private" && - Module == Module->getTopLevelModule()) { - SmallString<128> PrivateModule(Module->Name); - PrivateModule.append("_Private"); - - SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 2> PrivPath; - auto &II = PP->getIdentifierTable().get( - PrivateModule, PP->getIdentifierInfo(Module->Name)->getTokenID()); - PrivPath.push_back(std::make_pair(&II, Path[0].second)); - - if (PP->getHeaderSearchInfo().lookupModule(PrivateModule, true, - !IsInclusionDirective)) - Sub = - loadModule(ImportLoc, PrivPath, Visibility, IsInclusionDirective); - if (Sub) { - MapPrivateSubModToTopLevel = true; - if (!getDiagnostics().isIgnored( - diag::warn_no_priv_submodule_use_toplevel, ImportLoc)) { - getDiagnostics().Report(Path[I].second, - diag::warn_no_priv_submodule_use_toplevel) - << Path[I].first << Module->getFullModuleName() << PrivateModule - << SourceRange(Path[0].second, Path[I].second) - << FixItHint::CreateReplacement(SourceRange(Path[0].second), - PrivateModule); - getDiagnostics().Report(Sub->DefinitionLoc, - diag::note_private_top_level_defined); - } + for (unsigned I = 1, N = Path.size(); I != N; ++I) { + StringRef Name = Path[I].first->getName(); + clang::Module *Sub = Module->findSubmodule(Name); + + // If the user is requesting Foo.Private and it doesn't exist, try to + // match Foo_Private and emit a warning asking for the user to write + // @import Foo_Private instead. FIXME: remove this when existing clients + // migrate off of Foo.Private syntax. + if (!Sub && PP->getLangOpts().ImplicitModules && Name == "Private" && + Module == Module->getTopLevelModule()) { + SmallString<128> PrivateModule(Module->Name); + PrivateModule.append("_Private"); + + SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 2> PrivPath; + auto &II = PP->getIdentifierTable().get( + PrivateModule, PP->getIdentifierInfo(Module->Name)->getTokenID()); + PrivPath.push_back(std::make_pair(&II, Path[0].second)); + + if (PP->getHeaderSearchInfo().lookupModule(PrivateModule, ImportLoc, true, + !IsInclusionDirective)) + Sub = loadModule(ImportLoc, PrivPath, Visibility, IsInclusionDirective); + if (Sub) { + MapPrivateSubModToTopLevel = true; + if (!getDiagnostics().isIgnored( + diag::warn_no_priv_submodule_use_toplevel, ImportLoc)) { + getDiagnostics().Report(Path[I].second, + diag::warn_no_priv_submodule_use_toplevel) + << Path[I].first << Module->getFullModuleName() << PrivateModule + << SourceRange(Path[0].second, Path[I].second) + << FixItHint::CreateReplacement(SourceRange(Path[0].second), + PrivateModule); + getDiagnostics().Report(Sub->DefinitionLoc, + diag::note_private_top_level_defined); } } + } - if (!Sub) { - // Attempt to perform typo correction to find a module name that works. - SmallVector<StringRef, 2> Best; - unsigned BestEditDistance = (std::numeric_limits<unsigned>::max)(); - - for (clang::Module::submodule_iterator J = Module->submodule_begin(), - JEnd = Module->submodule_end(); - J != JEnd; ++J) { - unsigned ED = Name.edit_distance((*J)->Name, - /*AllowReplacements=*/true, - BestEditDistance); - if (ED <= BestEditDistance) { - if (ED < BestEditDistance) { - Best.clear(); - BestEditDistance = ED; - } - - Best.push_back((*J)->Name); + if (!Sub) { + // Attempt to perform typo correction to find a module name that works. + SmallVector<StringRef, 2> Best; + unsigned BestEditDistance = (std::numeric_limits<unsigned>::max)(); + + for (class Module *SubModule : Module->submodules()) { + unsigned ED = + Name.edit_distance(SubModule->Name, + /*AllowReplacements=*/true, BestEditDistance); + if (ED <= BestEditDistance) { + if (ED < BestEditDistance) { + Best.clear(); + BestEditDistance = ED; } + + Best.push_back(SubModule->Name); } + } - // If there was a clear winner, user it. - if (Best.size() == 1) { - getDiagnostics().Report(Path[I].second, - diag::err_no_submodule_suggest) + // If there was a clear winner, user it. + if (Best.size() == 1) { + getDiagnostics().Report(Path[I].second, diag::err_no_submodule_suggest) << Path[I].first << Module->getFullModuleName() << Best[0] - << SourceRange(Path[0].second, Path[I-1].second) + << SourceRange(Path[0].second, Path[I - 1].second) << FixItHint::CreateReplacement(SourceRange(Path[I].second), Best[0]); - Sub = Module->findSubmodule(Best[0]); - } + Sub = Module->findSubmodule(Best[0]); } + } - if (!Sub) { - // No submodule by this name. Complain, and don't look for further - // submodules. - getDiagnostics().Report(Path[I].second, diag::err_no_submodule) + if (!Sub) { + // No submodule by this name. Complain, and don't look for further + // submodules. + getDiagnostics().Report(Path[I].second, diag::err_no_submodule) << Path[I].first << Module->getFullModuleName() - << SourceRange(Path[0].second, Path[I-1].second); - break; - } - - Module = Sub; + << SourceRange(Path[0].second, Path[I - 1].second); + break; } + + Module = Sub; } // Make the named module visible, if it's not already part of the module @@ -2071,8 +2152,7 @@ void CompilerInstance::createModuleFromSource(SourceLocation ImportLoc, const FileEntry *ModuleMapFile = Other.getFileManager().getVirtualFile( ModuleMapFileName, NullTerminatedSource.size(), 0); Other.getSourceManager().overrideFileContents( - ModuleMapFile, - llvm::MemoryBuffer::getMemBuffer(NullTerminatedSource.c_str())); + ModuleMapFile, llvm::MemoryBuffer::getMemBuffer(NullTerminatedSource)); Other.BuiltModules = std::move(BuiltModules); Other.DeleteBuiltModules = false; |