diff options
Diffstat (limited to 'clang/lib/Frontend/FrontendAction.cpp')
-rw-r--r-- | clang/lib/Frontend/FrontendAction.cpp | 43 |
1 files changed, 42 insertions, 1 deletions
diff --git a/clang/lib/Frontend/FrontendAction.cpp b/clang/lib/Frontend/FrontendAction.cpp index b8f9238..68b8232 100644 --- a/clang/lib/Frontend/FrontendAction.cpp +++ b/clang/lib/Frontend/FrontendAction.cpp @@ -798,7 +798,48 @@ 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; |