diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Frontend/CompilerInstance.cpp')
| -rw-r--r-- | contrib/llvm/tools/clang/lib/Frontend/CompilerInstance.cpp | 205 |
1 files changed, 108 insertions, 97 deletions
diff --git a/contrib/llvm/tools/clang/lib/Frontend/CompilerInstance.cpp b/contrib/llvm/tools/clang/lib/Frontend/CompilerInstance.cpp index 7208177aa012..ecb09da3c1ef 100644 --- a/contrib/llvm/tools/clang/lib/Frontend/CompilerInstance.cpp +++ b/contrib/llvm/tools/clang/lib/Frontend/CompilerInstance.cpp @@ -16,6 +16,7 @@ #include "clang/Basic/FileManager.h" #include "clang/Basic/MemoryBufferCache.h" #include "clang/Basic/SourceManager.h" +#include "clang/Basic/Stack.h" #include "clang/Basic/TargetInfo.h" #include "clang/Basic/Version.h" #include "clang/Config/config.h" @@ -291,7 +292,7 @@ CompilerInstance::createDiagnostics(DiagnosticOptions *Opts, if (!Opts->DiagnosticSerializationFile.empty()) SetupSerializedDiagnostics(Opts, *Diags, Opts->DiagnosticSerializationFile); - + // Configure our handling of diagnostics. ProcessWarningOptions(*Diags, *Opts); @@ -302,11 +303,9 @@ CompilerInstance::createDiagnostics(DiagnosticOptions *Opts, FileManager *CompilerInstance::createFileManager() { if (!hasVirtualFileSystem()) { - if (IntrusiveRefCntPtr<vfs::FileSystem> VFS = - createVFSFromCompilerInvocation(getInvocation(), getDiagnostics())) - setVirtualFileSystem(VFS); - else - return nullptr; + IntrusiveRefCntPtr<vfs::FileSystem> VFS = + createVFSFromCompilerInvocation(getInvocation(), getDiagnostics()); + setVirtualFileSystem(VFS); } FileMgr = new FileManager(getFileSystemOpts(), VirtualFileSystem); return FileMgr.get(); @@ -464,7 +463,7 @@ void CompilerInstance::createPreprocessor(TranslationUnitKind TUKind) { /*ShowDepth=*/false); } - if (DepOpts.PrintShowIncludes) { + if (DepOpts.ShowIncludesDest != ShowIncludesDestination::None) { AttachHeaderIncludeGen(*PP, DepOpts, /*ShowAllHeaders=*/true, /*OutputPath=*/"", /*ShowDepth=*/true, /*MSStyle=*/true); @@ -854,36 +853,7 @@ bool CompilerInstance::InitializeSourceManager( // Figure out where to get and map in the main file. if (InputFile != "-") { - const FileEntry *File; - if (Opts.FindPchSource.empty()) { - File = FileMgr.getFile(InputFile, /*OpenFile=*/true); - } else { - // When building a pch file in clang-cl mode, the .h file is built as if - // it was included by a cc file. Since the driver doesn't know about - // all include search directories, the frontend must search the input - // file through HeaderSearch here, as if it had been included by the - // cc file at Opts.FindPchSource. - const FileEntry *FindFile = FileMgr.getFile(Opts.FindPchSource); - if (!FindFile) { - Diags.Report(diag::err_fe_error_reading) << Opts.FindPchSource; - return false; - } - const DirectoryLookup *UnusedCurDir; - SmallVector<std::pair<const FileEntry *, const DirectoryEntry *>, 16> - Includers; - Includers.push_back(std::make_pair(FindFile, FindFile->getDir())); - File = HS->LookupFile(InputFile, SourceLocation(), /*isAngled=*/false, - /*FromDir=*/nullptr, - /*CurDir=*/UnusedCurDir, Includers, - /*SearchPath=*/nullptr, - /*RelativePath=*/nullptr, - /*RequestingModule=*/nullptr, - /*SuggestedModule=*/nullptr, /*IsMapped=*/nullptr, - /*SkipCache=*/true); - // Also add the header to /showIncludes output. - if (File) - DepOpts.ShowIncludesPretendHeader = File->getName(); - } + const FileEntry *File = FileMgr.getFile(InputFile, /*OpenFile=*/true); if (!File) { Diags.Report(diag::err_fe_error_reading) << InputFile; return false; @@ -965,7 +935,7 @@ bool CompilerInstance::ExecuteAction(FrontendAction &Act) { // Adjust target options based on codegen options. getTarget().adjustTargetOptions(getCodeGenOpts(), getTargetOpts()); - // rewriter project will change target built-in bool type from its default. + // rewriter project will change target built-in bool type from its default. if (getFrontendOpts().ProgramAction == frontend::RewriteObjC) getTarget().noSignedCharForObjCBool(); @@ -1044,7 +1014,7 @@ bool CompilerInstance::ExecuteAction(FrontendAction &Act) { return !getDiagnostics().getClient()->getNumErrors(); } -/// \brief Determine the appropriate source input kind based on language +/// Determine the appropriate source input kind based on language /// options. static InputKind::Language getLanguageFromOptions(const LangOptions &LangOpts) { if (LangOpts.OpenCL) @@ -1056,7 +1026,7 @@ static InputKind::Language getLanguageFromOptions(const LangOptions &LangOpts) { return LangOpts.CPlusPlus ? InputKind::CXX : InputKind::C; } -/// \brief Compile a module file for the given module, using the options +/// Compile a module file for the given module, using the options /// provided by the importing compiler instance. Returns true if the module /// was built without errors. static bool @@ -1072,7 +1042,7 @@ compileModuleImpl(CompilerInstance &ImportingInstance, SourceLocation ImportLoc, std::make_shared<CompilerInvocation>(ImportingInstance.getInvocation()); PreprocessorOptions &PPOpts = Invocation->getPreprocessorOpts(); - + // For any options that aren't intended to affect how a module is built, // reset them to their default values. Invocation->getLangOpts()->resetNonModularOptions(); @@ -1090,6 +1060,10 @@ compileModuleImpl(CompilerInstance &ImportingInstance, SourceLocation ImportLoc, }), PPOpts.Macros.end()); + // If the original compiler invocation had -fmodule-name, pass it through. + Invocation->getLangOpts()->ModuleName = + ImportingInstance.getInvocation().getLangOpts()->ModuleName; + // Note the name of the module we're building. Invocation->getLangOpts()->CurrentModule = ModuleName; @@ -1118,11 +1092,11 @@ compileModuleImpl(CompilerInstance &ImportingInstance, SourceLocation ImportLoc, // Don't free the remapped file buffers; they are owned by our caller. PPOpts.RetainRemappedFileBuffers = true; - + Invocation->getDiagnosticOpts().VerifyDiagnostics = 0; assert(ImportingInstance.getInvocation().getModuleHash() == Invocation->getModuleHash() && "Module hash mismatch!"); - + // Construct a compiler instance that will be used to actually create the // module. Since we're sharing a PCMCache, // CompilerInstance::CompilerInstance is responsible for finalizing the @@ -1162,14 +1136,13 @@ compileModuleImpl(CompilerInstance &ImportingInstance, SourceLocation ImportLoc, // Execute the action to actually build the module in-place. Use a separate // thread so that we get a stack large enough. - const unsigned ThreadStackSize = 8 << 20; llvm::CrashRecoveryContext CRC; CRC.RunSafelyOnThread( [&]() { GenerateModuleFromModuleMapAction Action; Instance.ExecuteAction(Action); }, - ThreadStackSize); + DesiredStackSize); PostBuildStep(Instance); @@ -1186,7 +1159,20 @@ compileModuleImpl(CompilerInstance &ImportingInstance, SourceLocation ImportLoc, return !Instance.getDiagnostics().hasErrorOccurred(); } -/// \brief Compile a module file for the given module, using the options +static const FileEntry *getPublicModuleMap(const FileEntry *File, + FileManager &FileMgr) { + StringRef Filename = llvm::sys::path::filename(File->getName()); + SmallString<128> PublicFilename(File->getDir()->getName()); + if (Filename == "module_private.map") + llvm::sys::path::append(PublicFilename, "module.map"); + else if (Filename == "module.private.modulemap") + llvm::sys::path::append(PublicFilename, "module.modulemap"); + else + return nullptr; + return FileMgr.getFile(PublicFilename); +} + +/// Compile a module file for the given module, using the options /// provided by the importing compiler instance. Returns true if the module /// was built without errors. static bool compileModuleImpl(CompilerInstance &ImportingInstance, @@ -1197,11 +1183,18 @@ static bool compileModuleImpl(CompilerInstance &ImportingInstance, InputKind::ModuleMap); // Get or create the module map that we'll use to build this module. - ModuleMap &ModMap + ModuleMap &ModMap = ImportingInstance.getPreprocessor().getHeaderSearchInfo().getModuleMap(); bool Result; if (const FileEntry *ModuleMapFile = ModMap.getContainingModuleMapFile(Module)) { + // Canonicalize compilation to start with the public module map. This is + // vital for submodules declarations in the private module maps to be + // correctly parsed when depending on a top level module in the public one. + if (const FileEntry *PublicMMFile = getPublicModuleMap( + ModuleMapFile, ImportingInstance.getFileManager())) + ModuleMapFile = PublicMMFile; + // Use the module map where this module resides. Result = compileModuleImpl( ImportingInstance, ImportLoc, Module->getTopLevelModuleName(), @@ -1298,7 +1291,7 @@ static bool compileAndLoadModule(CompilerInstance &ImportingInstance, // case of timeout, build it ourselves. Diags.Report(ModuleNameLoc, diag::remark_module_lock_timeout) << Module->Name; - // Clear the lock file so that future invokations can make progress. + // Clear the lock file so that future invocations can make progress. Locked.unsafeRemoveLockFile(); continue; } @@ -1328,13 +1321,13 @@ static bool compileAndLoadModule(CompilerInstance &ImportingInstance, } } -/// \brief Diagnose differences between the current definition of the given +/// 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, Module *Mod, SourceLocation ImportLoc) { IdentifierInfo *Id = PP.getIdentifierInfo(ConfigMacro); SourceManager &SourceMgr = PP.getSourceManager(); - + // If this identifier has never had a macro definition, then it could // not have changed. if (!Id->hadMacroDefinition()) @@ -1386,13 +1379,13 @@ static void checkConfigMacro(Preprocessor &PP, StringRef ConfigMacro, } } -/// \brief Write a new timestamp file with the given path. +/// Write a new timestamp file with the given path. static void writeTimestampFile(StringRef TimestampFile) { std::error_code EC; llvm::raw_fd_ostream Out(TimestampFile.str(), EC, llvm::sys::fs::F_None); } -/// \brief Prune the module cache of modules that haven't been accessed in +/// Prune the module cache of modules that haven't been accessed in /// a long time. static void pruneModuleCache(const HeaderSearchOptions &HSOpts) { struct stat StatBuf; @@ -1580,15 +1573,22 @@ bool CompilerInstance::loadModuleFile(StringRef FileName) { if (!ModuleManager) createModuleManager(); + // If -Wmodule-file-config-mismatch is mapped as an error or worse, allow the + // ASTReader to diagnose it, since it can produce better errors that we can. + bool ConfigMismatchIsRecoverable = + getDiagnostics().getDiagnosticLevel(diag::warn_module_config_mismatch, + SourceLocation()) + <= DiagnosticsEngine::Warning; + auto Listener = llvm::make_unique<ReadModuleNames>(*this); auto &ListenerRef = *Listener; ASTReader::ListenerScope ReadModuleNamesListener(*ModuleManager, std::move(Listener)); // Try to load the module file. - switch (ModuleManager->ReadAST(FileName, serialization::MK_ExplicitModule, - SourceLocation(), - ASTReader::ARR_ConfigurationMismatch)) { + switch (ModuleManager->ReadAST( + FileName, serialization::MK_ExplicitModule, SourceLocation(), + ConfigMismatchIsRecoverable ? ASTReader::ARR_ConfigurationMismatch : 0)) { case ASTReader::Success: // We successfully loaded the module file; remember the set of provided // modules so that we don't try to load implicit modules for them. @@ -1651,10 +1651,12 @@ CompilerInstance::loadModule(SourceLocation ImportLoc, = KnownModules.find(Path[0].first); if (Known != KnownModules.end()) { // Retrieve the cached top-level module. - Module = Known->second; + Module = Known->second; } else if (ModuleName == getLangOpts().CurrentModule) { - // This is the module we're building. - Module = PP->getHeaderSearchInfo().lookupModule(ModuleName); + // This is the module we're building. + Module = PP->getHeaderSearchInfo().lookupModule( + ModuleName, /*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? //if (Module == nullptr) { @@ -1666,7 +1668,8 @@ CompilerInstance::loadModule(SourceLocation ImportLoc, Known = KnownModules.insert(std::make_pair(Path[0].first, Module)).first; } else { // Search for a module with the given name. - Module = PP->getHeaderSearchInfo().lookupModule(ModuleName); + Module = PP->getHeaderSearchInfo().lookupModule(ModuleName, true, + !IsInclusionDirective); HeaderSearchOptions &HSOpts = PP->getHeaderSearchInfo().getHeaderSearchOpts(); @@ -1743,7 +1746,8 @@ CompilerInstance::loadModule(SourceLocation ImportLoc, ImportLoc, ARRFlags)) { case ASTReader::Success: { if (Source != ModuleCache && !Module) { - Module = PP->getHeaderSearchInfo().lookupModule(ModuleName); + Module = PP->getHeaderSearchInfo().lookupModule(ModuleName, true, + !IsInclusionDirective); if (!Module || !Module->getASTFile() || FileMgr->getFile(ModuleFileName) != Module->getASTFile()) { // Error out if Module does not refer to the file in the prebuilt @@ -1847,7 +1851,7 @@ CompilerInstance::loadModule(SourceLocation ImportLoc, // Cache the result of this top-level module lookup for later. Known = KnownModules.insert(std::make_pair(Path[0].first, Module)).first; } - + // If we never found the module, fail. if (!Module) return ModuleLoadResult(); @@ -1859,40 +1863,6 @@ CompilerInstance::loadModule(SourceLocation ImportLoc, for (unsigned I = 1, N = Path.size(); I != N; ++I) { StringRef Name = Path[I].first->getName(); clang::Module *Sub = Module->findSubmodule(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 (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 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) - << FixItHint::CreateReplacement(SourceRange(Path[I].second), - Best[0]); - - Sub = Module->findSubmodule(Best[0]); - } - } // 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 @@ -1908,7 +1878,8 @@ CompilerInstance::loadModule(SourceLocation ImportLoc, PrivateModule, PP->getIdentifierInfo(Module->Name)->getTokenID()); PrivPath.push_back(std::make_pair(&II, Path[0].second)); - if (PP->getHeaderSearchInfo().lookupModule(PrivateModule)) + if (PP->getHeaderSearchInfo().lookupModule(PrivateModule, true, + !IsInclusionDirective)) Sub = loadModule(ImportLoc, PrivPath, Visibility, IsInclusionDirective); if (Sub) { @@ -1928,6 +1899,40 @@ CompilerInstance::loadModule(SourceLocation ImportLoc, } 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 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) + << FixItHint::CreateReplacement(SourceRange(Path[I].second), + 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) @@ -1935,7 +1940,7 @@ CompilerInstance::loadModule(SourceLocation ImportLoc, << SourceRange(Path[0].second, Path[I-1].second); break; } - + Module = Sub; } } @@ -1977,6 +1982,12 @@ CompilerInstance::loadModule(SourceLocation ImportLoc, Module, ImportLoc); } + // Resolve any remaining module using export_as for this one. + getPreprocessor() + .getHeaderSearchInfo() + .getModuleMap() + .resolveLinkAsDependencies(TopModule); + LastModuleImportLoc = ImportLoc; LastModuleImportResult = ModuleLoadResult(Module); return LastModuleImportResult; |
