diff options
author | Iain Sandoe <iain@sandoe.co.uk> | 2021-01-10 13:50:26 +0000 |
---|---|---|
committer | Iain Sandoe <iain@sandoe.co.uk> | 2022-03-26 10:17:17 +0000 |
commit | 0687578728ea1985cbab0de14d4eeb4e89cdf210 (patch) | |
tree | 394c7cecab51f58515de4102d7006cef2fa76415 /clang/lib/Frontend/FrontendAction.cpp | |
parent | 5f543cb0efc90efbf3a69dba19f7487657511981 (diff) | |
download | llvm-0687578728ea1985cbab0de14d4eeb4e89cdf210.zip llvm-0687578728ea1985cbab0de14d4eeb4e89cdf210.tar.gz llvm-0687578728ea1985cbab0de14d4eeb4e89cdf210.tar.bz2 |
[C++20][Modules][HU 2/5] Support searching Header Units in user or system search paths.
This is support for the user-facing options to create importable header units
from headers in the user or system search paths (or to be given an absolute path).
This means that an incomplete header path will be passed by the driver and the
lookup carried out using the search paths present when the front end is run.
To support this, we introduce file fypes for c++-{user,system,header-unit}-header.
These terms are the same as the ones used by GCC, to minimise the differences for
tooling (and users).
The preprocessor checks for headers before issuing a warning for
"#pragma once" in a header build. We ensure that the importable header units
are recognised as headers in order to avoid such warnings.
Differential Revision: https://reviews.llvm.org/D121096
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; |