aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Frontend/CompilerInvocation.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/CompilerInvocation.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/CompilerInvocation.cpp')
-rw-r--r--clang/lib/Frontend/CompilerInvocation.cpp62
1 files changed, 55 insertions, 7 deletions
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index be7828b..5bb480a 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -2567,6 +2567,20 @@ static void GenerateFrontendArgs(const FrontendOptions &Opts,
StringRef Preprocessed = Opts.DashX.isPreprocessed() ? "-cpp-output" : "";
StringRef ModuleMap =
Opts.DashX.getFormat() == InputKind::ModuleMap ? "-module-map" : "";
+ StringRef HeaderUnit = "";
+ switch (Opts.DashX.getHeaderUnitKind()) {
+ case InputKind::HeaderUnit_None:
+ break;
+ case InputKind::HeaderUnit_User:
+ HeaderUnit = "-user";
+ break;
+ case InputKind::HeaderUnit_System:
+ HeaderUnit = "-system";
+ break;
+ case InputKind::HeaderUnit_Abs:
+ HeaderUnit = "-header-unit";
+ break;
+ }
StringRef Header = IsHeader ? "-header" : "";
StringRef Lang;
@@ -2611,7 +2625,8 @@ static void GenerateFrontendArgs(const FrontendOptions &Opts,
break;
}
- GenerateArg(Args, OPT_x, Lang + Header + ModuleMap + Preprocessed, SA);
+ GenerateArg(Args, OPT_x,
+ Lang + HeaderUnit + Header + ModuleMap + Preprocessed, SA);
}
// OPT_INPUT has a unique class, generate it directly.
@@ -2756,13 +2771,32 @@ static bool ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args,
if (const Arg *A = Args.getLastArg(OPT_x)) {
StringRef XValue = A->getValue();
- // Parse suffixes: '<lang>(-header|[-module-map][-cpp-output])'.
+ // Parse suffixes:
+ // '<lang>(-[{header-unit,user,system}-]header|[-module-map][-cpp-output])'.
// FIXME: Supporting '<lang>-header-cpp-output' would be useful.
bool Preprocessed = XValue.consume_back("-cpp-output");
bool ModuleMap = XValue.consume_back("-module-map");
- IsHeaderFile = !Preprocessed && !ModuleMap &&
- XValue != "precompiled-header" &&
- XValue.consume_back("-header");
+ // Detect and consume the header indicator.
+ bool IsHeader =
+ XValue != "precompiled-header" && XValue.consume_back("-header");
+
+ // If we have c++-{user,system}-header, that indicates a header unit input
+ // likewise, if the user put -fmodule-header together with a header with an
+ // absolute path (header-unit-header).
+ InputKind::HeaderUnitKind HUK = InputKind::HeaderUnit_None;
+ if (IsHeader || Preprocessed) {
+ if (XValue.consume_back("-header-unit"))
+ HUK = InputKind::HeaderUnit_Abs;
+ else if (XValue.consume_back("-system"))
+ HUK = InputKind::HeaderUnit_System;
+ else if (XValue.consume_back("-user"))
+ HUK = InputKind::HeaderUnit_User;
+ }
+
+ // The value set by this processing is an un-preprocessed source which is
+ // not intended to be a module map or header unit.
+ IsHeaderFile = IsHeader && !Preprocessed && !ModuleMap &&
+ HUK == InputKind::HeaderUnit_None;
// Principal languages.
DashX = llvm::StringSwitch<InputKind>(XValue)
@@ -2779,14 +2813,16 @@ static bool ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args,
// "objc[++]-cpp-output" is an acceptable synonym for
// "objective-c[++]-cpp-output".
- if (DashX.isUnknown() && Preprocessed && !IsHeaderFile && !ModuleMap)
+ if (DashX.isUnknown() && Preprocessed && !IsHeaderFile && !ModuleMap &&
+ HUK == InputKind::HeaderUnit_None)
DashX = llvm::StringSwitch<InputKind>(XValue)
.Case("objc", Language::ObjC)
.Case("objc++", Language::ObjCXX)
.Default(Language::Unknown);
// Some special cases cannot be combined with suffixes.
- if (DashX.isUnknown() && !Preprocessed && !ModuleMap && !IsHeaderFile)
+ if (DashX.isUnknown() && !Preprocessed && !IsHeaderFile && !ModuleMap &&
+ HUK == InputKind::HeaderUnit_None)
DashX = llvm::StringSwitch<InputKind>(XValue)
.Case("cpp-output", InputKind(Language::C).getPreprocessed())
.Case("assembler-with-cpp", Language::Asm)
@@ -2801,6 +2837,12 @@ static bool ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args,
if (Preprocessed)
DashX = DashX.getPreprocessed();
+ // A regular header is considered mutually exclusive with a header unit.
+ if (HUK != InputKind::HeaderUnit_None) {
+ DashX = DashX.withHeaderUnit(HUK);
+ IsHeaderFile = true;
+ } else if (IsHeaderFile)
+ DashX = DashX.getHeader();
if (ModuleMap)
DashX = DashX.withFormat(InputKind::ModuleMap);
}
@@ -2810,6 +2852,11 @@ static bool ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args,
Opts.Inputs.clear();
if (Inputs.empty())
Inputs.push_back("-");
+
+ if (DashX.getHeaderUnitKind() != InputKind::HeaderUnit_None &&
+ Inputs.size() > 1)
+ Diags.Report(diag::err_drv_header_unit_extra_inputs) << Inputs[1];
+
for (unsigned i = 0, e = Inputs.size(); i != e; ++i) {
InputKind IK = DashX;
if (IK.isUnknown()) {
@@ -3857,6 +3904,7 @@ bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args,
}
if (Opts.FastRelaxedMath)
Opts.setDefaultFPContractMode(LangOptions::FPM_Fast);
+
llvm::sort(Opts.ModuleFeatures);
// -mrtd option