diff options
Diffstat (limited to 'contrib/llvm-project/clang/lib/Frontend/FrontendAction.cpp')
-rw-r--r-- | contrib/llvm-project/clang/lib/Frontend/FrontendAction.cpp | 81 |
1 files changed, 71 insertions, 10 deletions
diff --git a/contrib/llvm-project/clang/lib/Frontend/FrontendAction.cpp b/contrib/llvm-project/clang/lib/Frontend/FrontendAction.cpp index 089f40b36089..65160dd7e0b1 100644 --- a/contrib/llvm-project/clang/lib/Frontend/FrontendAction.cpp +++ b/contrib/llvm-project/clang/lib/Frontend/FrontendAction.cpp @@ -331,7 +331,7 @@ static std::error_code collectModuleHeaderIncludes( return std::error_code(); // Resolve all lazy header directives to header files. - ModMap.resolveHeaderDirectives(Module); + ModMap.resolveHeaderDirectives(Module, /*File=*/llvm::None); // If any headers are missing, we can't build this module. In most cases, // diagnostics for this should have already been produced; we only get here @@ -413,11 +413,7 @@ static std::error_code collectModuleHeaderIncludes( // Sort header paths and make the header inclusion order deterministic // across different OSs and filesystems. - llvm::sort(Headers.begin(), Headers.end(), []( - const std::pair<std::string, const FileEntry *> &LHS, - const std::pair<std::string, const FileEntry *> &RHS) { - return LHS.first < RHS.first; - }); + llvm::sort(Headers.begin(), Headers.end(), llvm::less_first()); for (auto &H : Headers) { // Include this header as part of the umbrella directory. Module->addTopHeader(H.second); @@ -465,6 +461,15 @@ static bool loadModuleMapForModuleBuild(CompilerInstance &CI, bool IsSystem, if (SrcMgr.getBufferOrFake(ModuleMapID).getBufferSize() == Offset) Offset = 0; + // Infer framework module if possible. + if (HS.getModuleMap().canInferFrameworkModule(ModuleMap->getDir())) { + SmallString<128> InferredFrameworkPath = ModuleMap->getDir()->getName(); + llvm::sys::path::append(InferredFrameworkPath, + CI.getLangOpts().ModuleName + ".framework"); + if (auto Dir = CI.getFileManager().getDirectory(InferredFrameworkPath)) + (void)HS.getModuleMap().inferFrameworkModule(*Dir, IsSystem, nullptr); + } + return false; } @@ -752,10 +757,10 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI, PreprocessorOptions &PPOpts = CI.getPreprocessorOpts(); StringRef PCHInclude = PPOpts.ImplicitPCHInclude; std::string SpecificModuleCachePath = CI.getSpecificModuleCachePath(); - if (auto PCHDir = FileMgr.getDirectory(PCHInclude)) { + if (auto PCHDir = FileMgr.getOptionalDirectoryRef(PCHInclude)) { std::error_code EC; SmallString<128> DirNative; - llvm::sys::path::native((*PCHDir)->getName(), DirNative); + llvm::sys::path::native(PCHDir->getName(), DirNative); bool Found = false; llvm::vfs::FileSystem &FS = FileMgr.getVirtualFileSystem(); for (llvm::vfs::directory_iterator Dir = FS.dir_begin(DirNative, EC), @@ -789,10 +794,66 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI, &CI.getPreprocessor()); HasBegunSourceFile = true; - // Initialize the main file entry. + // Handle C++20 header units. + // Here, the user has the option to specify that the header name should be + // looked up in the pre-processor search paths (and the main filename as + // passed by the driver might therefore be incomplete until that look-up). + if (CI.getLangOpts().CPlusPlusModules && Input.getKind().isHeaderUnit() && + !Input.getKind().isPreprocessed()) { + StringRef FileName = Input.getFile(); + InputKind Kind = Input.getKind(); + if (Kind.getHeaderUnitKind() != InputKind::HeaderUnit_Abs) { + assert(CI.hasPreprocessor() && + "trying to build a header unit without a Pre-processor?"); + HeaderSearch &HS = CI.getPreprocessor().getHeaderSearchInfo(); + // Relative searches begin from CWD. + const DirectoryEntry *Dir = nullptr; + if (auto DirOrErr = CI.getFileManager().getDirectory(".")) + Dir = *DirOrErr; + SmallVector<std::pair<const FileEntry *, const DirectoryEntry *>, 1> CWD; + CWD.push_back({nullptr, Dir}); + Optional<FileEntryRef> FE = + HS.LookupFile(FileName, SourceLocation(), + /*Angled*/ Input.getKind().getHeaderUnitKind() == + InputKind::HeaderUnit_System, + nullptr, nullptr, CWD, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr); + if (!FE) { + CI.getDiagnostics().Report(diag::err_module_header_file_not_found) + << FileName; + return false; + } + // We now have the filename... + FileName = FE->getFileEntry().getName(); + // ... still a header unit, but now use the path as written. + Kind = Input.getKind().withHeaderUnit(InputKind::HeaderUnit_Abs); + Input = FrontendInputFile(FileName, Kind, Input.isSystem()); + } + // Unless the user has overridden the name, the header unit module name is + // the pathname for the file. + if (CI.getLangOpts().ModuleName.empty()) + CI.getLangOpts().ModuleName = std::string(FileName); + CI.getLangOpts().CurrentModule = CI.getLangOpts().ModuleName; + } + if (!CI.InitializeSourceManager(Input)) return false; + if (CI.getLangOpts().CPlusPlusModules && Input.getKind().isHeaderUnit() && + Input.getKind().isPreprocessed() && !usesPreprocessorOnly()) { + // We have an input filename like foo.iih, but we want to find the right + // module name (and original file, to build the map entry). + // Check if the first line specifies the original source file name with a + // linemarker. + std::string PresumedInputFile = std::string(getCurrentFileOrBufferName()); + ReadOriginalFileName(CI, PresumedInputFile); + // Unless the user overrides this, the module name is the name by which the + // original file was known. + if (CI.getLangOpts().ModuleName.empty()) + CI.getLangOpts().ModuleName = std::string(PresumedInputFile); + CI.getLangOpts().CurrentModule = CI.getLangOpts().ModuleName; + } + // For module map files, we first parse the module map and synthesize a // "<module-includes>" buffer before more conventional processing. if (Input.getKind().getFormat() == InputKind::ModuleMap) { @@ -1014,7 +1075,7 @@ void FrontendAction::EndSourceFile() { } if (CI.getFrontendOpts().ShowStats) { - llvm::errs() << "\nSTATISTICS FOR '" << getCurrentFile() << "':\n"; + llvm::errs() << "\nSTATISTICS FOR '" << getCurrentFileOrBufferName() << "':\n"; CI.getPreprocessor().PrintStats(); CI.getPreprocessor().getIdentifierTable().PrintStats(); CI.getPreprocessor().getHeaderSearchInfo().PrintStats(); |