aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Frontend/FrontendAction.cpp
diff options
context:
space:
mode:
authorIain Sandoe <iain@sandoe.co.uk>2021-01-10 13:50:26 +0000
committerIain Sandoe <iain@sandoe.co.uk>2022-03-26 10:17:17 +0000
commit0687578728ea1985cbab0de14d4eeb4e89cdf210 (patch)
tree394c7cecab51f58515de4102d7006cef2fa76415 /clang/lib/Frontend/FrontendAction.cpp
parent5f543cb0efc90efbf3a69dba19f7487657511981 (diff)
downloadllvm-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.cpp43
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;