aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Frontend/CompilerInvocation.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2023-02-11 12:38:04 +0000
committerDimitry Andric <dim@FreeBSD.org>2023-02-11 12:38:11 +0000
commite3b557809604d036af6e00c60f012c2025b59a5e (patch)
tree8a11ba2269a3b669601e2fd41145b174008f4da8 /clang/lib/Frontend/CompilerInvocation.cpp
parent08e8dd7b9db7bb4a9de26d44c1cbfd24e869c014 (diff)
Diffstat (limited to 'clang/lib/Frontend/CompilerInvocation.cpp')
-rw-r--r--clang/lib/Frontend/CompilerInvocation.cpp311
1 files changed, 194 insertions, 117 deletions
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index 2dd96e68bb92..0bb9c8c83c63 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -52,8 +52,6 @@
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/FloatingPointMode.h"
#include "llvm/ADT/Hashing.h"
-#include "llvm/ADT/None.h"
-#include "llvm/ADT/Optional.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
@@ -94,8 +92,11 @@
#include <cassert>
#include <cstddef>
#include <cstring>
+#include <ctime>
#include <fstream>
+#include <limits>
#include <memory>
+#include <optional>
#include <string>
#include <tuple>
#include <type_traits>
@@ -113,8 +114,8 @@ using namespace llvm::opt;
// Parse misexpect tolerance argument value.
// Valid option values are integers in the range [0, 100)
-inline Expected<Optional<uint64_t>> parseToleranceOption(StringRef Arg) {
- int64_t Val;
+static Expected<std::optional<uint32_t>> parseToleranceOption(StringRef Arg) {
+ uint32_t Val;
if (Arg.getAsInteger(10, Val))
return llvm::createStringError(llvm::inconvertibleErrorCode(),
"Not an integer: %s", Arg.data());
@@ -168,21 +169,22 @@ CompilerInvocationRefBase::~CompilerInvocationRefBase() = default;
#include "clang/Driver/Options.inc"
#undef SIMPLE_ENUM_VALUE_TABLE
-static llvm::Optional<bool> normalizeSimpleFlag(OptSpecifier Opt,
- unsigned TableIndex,
- const ArgList &Args,
- DiagnosticsEngine &Diags) {
+static std::optional<bool> normalizeSimpleFlag(OptSpecifier Opt,
+ unsigned TableIndex,
+ const ArgList &Args,
+ DiagnosticsEngine &Diags) {
if (Args.hasArg(Opt))
return true;
- return None;
+ return std::nullopt;
}
-static Optional<bool> normalizeSimpleNegativeFlag(OptSpecifier Opt, unsigned,
- const ArgList &Args,
- DiagnosticsEngine &) {
+static std::optional<bool> normalizeSimpleNegativeFlag(OptSpecifier Opt,
+ unsigned,
+ const ArgList &Args,
+ DiagnosticsEngine &) {
if (Args.hasArg(Opt))
return false;
- return None;
+ return std::nullopt;
}
/// The tblgen-erated code passes in a fifth parameter of an arbitrary type, but
@@ -197,18 +199,17 @@ static void denormalizeSimpleFlag(SmallVectorImpl<const char *> &Args,
}
template <typename T> static constexpr bool is_uint64_t_convertible() {
- return !std::is_same<T, uint64_t>::value &&
- llvm::is_integral_or_enum<T>::value;
+ return !std::is_same_v<T, uint64_t> && llvm::is_integral_or_enum<T>::value;
}
template <typename T,
std::enable_if_t<!is_uint64_t_convertible<T>(), bool> = false>
static auto makeFlagToValueNormalizer(T Value) {
return [Value](OptSpecifier Opt, unsigned, const ArgList &Args,
- DiagnosticsEngine &) -> Optional<T> {
+ DiagnosticsEngine &) -> std::optional<T> {
if (Args.hasArg(Opt))
return Value;
- return None;
+ return std::nullopt;
};
}
@@ -220,13 +221,13 @@ static auto makeFlagToValueNormalizer(T Value) {
static auto makeBooleanOptionNormalizer(bool Value, bool OtherValue,
OptSpecifier OtherOpt) {
- return [Value, OtherValue, OtherOpt](OptSpecifier Opt, unsigned,
- const ArgList &Args,
- DiagnosticsEngine &) -> Optional<bool> {
+ return [Value, OtherValue,
+ OtherOpt](OptSpecifier Opt, unsigned, const ArgList &Args,
+ DiagnosticsEngine &) -> std::optional<bool> {
if (const Arg *A = Args.getLastArg(Opt, OtherOpt)) {
return A->getOption().matches(Opt) ? Value : OtherValue;
}
- return None;
+ return std::nullopt;
};
}
@@ -269,34 +270,34 @@ denormalizeString(SmallVectorImpl<const char *> &Args, const char *Spelling,
denormalizeStringImpl(Args, Spelling, SA, OptClass, TableIndex, Twine(Value));
}
-static Optional<SimpleEnumValue>
+static std::optional<SimpleEnumValue>
findValueTableByName(const SimpleEnumValueTable &Table, StringRef Name) {
for (int I = 0, E = Table.Size; I != E; ++I)
if (Name == Table.Table[I].Name)
return Table.Table[I];
- return None;
+ return std::nullopt;
}
-static Optional<SimpleEnumValue>
+static std::optional<SimpleEnumValue>
findValueTableByValue(const SimpleEnumValueTable &Table, unsigned Value) {
for (int I = 0, E = Table.Size; I != E; ++I)
if (Value == Table.Table[I].Value)
return Table.Table[I];
- return None;
+ return std::nullopt;
}
-static llvm::Optional<unsigned> normalizeSimpleEnum(OptSpecifier Opt,
- unsigned TableIndex,
- const ArgList &Args,
- DiagnosticsEngine &Diags) {
+static std::optional<unsigned> normalizeSimpleEnum(OptSpecifier Opt,
+ unsigned TableIndex,
+ const ArgList &Args,
+ DiagnosticsEngine &Diags) {
assert(TableIndex < SimpleEnumValueTablesSize);
const SimpleEnumValueTable &Table = SimpleEnumValueTables[TableIndex];
auto *Arg = Args.getLastArg(Opt);
if (!Arg)
- return None;
+ return std::nullopt;
StringRef ArgValue = Arg->getValue();
if (auto MaybeEnumVal = findValueTableByName(Table, ArgValue))
@@ -304,7 +305,7 @@ static llvm::Optional<unsigned> normalizeSimpleEnum(OptSpecifier Opt,
Diags.Report(diag::err_drv_invalid_value)
<< Arg->getAsString(Args) << ArgValue;
- return None;
+ return std::nullopt;
}
static void denormalizeSimpleEnumImpl(SmallVectorImpl<const char *> &Args,
@@ -333,32 +334,33 @@ static void denormalizeSimpleEnum(SmallVectorImpl<const char *> &Args,
static_cast<unsigned>(Value));
}
-static Optional<std::string> normalizeString(OptSpecifier Opt, int TableIndex,
- const ArgList &Args,
- DiagnosticsEngine &Diags) {
+static std::optional<std::string> normalizeString(OptSpecifier Opt,
+ int TableIndex,
+ const ArgList &Args,
+ DiagnosticsEngine &Diags) {
auto *Arg = Args.getLastArg(Opt);
if (!Arg)
- return None;
+ return std::nullopt;
return std::string(Arg->getValue());
}
template <typename IntTy>
-static Optional<IntTy> normalizeStringIntegral(OptSpecifier Opt, int,
- const ArgList &Args,
- DiagnosticsEngine &Diags) {
+static std::optional<IntTy> normalizeStringIntegral(OptSpecifier Opt, int,
+ const ArgList &Args,
+ DiagnosticsEngine &Diags) {
auto *Arg = Args.getLastArg(Opt);
if (!Arg)
- return None;
+ return std::nullopt;
IntTy Res;
if (StringRef(Arg->getValue()).getAsInteger(0, Res)) {
Diags.Report(diag::err_drv_invalid_int_value)
<< Arg->getAsString(Args) << Arg->getValue();
- return None;
+ return std::nullopt;
}
return Res;
}
-static Optional<std::vector<std::string>>
+static std::optional<std::vector<std::string>>
normalizeStringVector(OptSpecifier Opt, int, const ArgList &Args,
DiagnosticsEngine &) {
return Args.getAllArgValues(Opt);
@@ -396,12 +398,13 @@ static void denormalizeStringVector(SmallVectorImpl<const char *> &Args,
}
}
-static Optional<std::string> normalizeTriple(OptSpecifier Opt, int TableIndex,
- const ArgList &Args,
- DiagnosticsEngine &Diags) {
+static std::optional<std::string> normalizeTriple(OptSpecifier Opt,
+ int TableIndex,
+ const ArgList &Args,
+ DiagnosticsEngine &Diags) {
auto *Arg = Args.getLastArg(Opt);
if (!Arg)
- return None;
+ return std::nullopt;
return llvm::Triple::normalize(Arg->getValue());
}
@@ -490,9 +493,6 @@ static bool FixupInvocation(CompilerInvocation &Invocation,
if (LangOpts.AppleKext && !LangOpts.CPlusPlus)
Diags.Report(diag::warn_c_kext);
- if (Args.hasArg(OPT_fconcepts_ts))
- Diags.Report(diag::warn_fe_concepts_ts_flag);
-
if (LangOpts.NewAlignOverride &&
!llvm::isPowerOf2_32(LangOpts.NewAlignOverride)) {
Arg *A = Args.getLastArg(OPT_fnew_alignment_EQ);
@@ -510,6 +510,10 @@ static bool FixupInvocation(CompilerInvocation &Invocation,
Diags.Report(diag::err_drv_argument_not_allowed_with)
<< "-fgnu89-inline" << GetInputKindName(IK);
+ if (Args.hasArg(OPT_hlsl_entrypoint) && !LangOpts.HLSL)
+ Diags.Report(diag::err_drv_argument_not_allowed_with)
+ << "-hlsl-entry" << GetInputKindName(IK);
+
if (Args.hasArg(OPT_fgpu_allow_device_init) && !LangOpts.HIP)
Diags.Report(diag::warn_ignored_hip_only_option)
<< Args.getLastArg(OPT_fgpu_allow_device_init)->getAsString(Args);
@@ -903,14 +907,6 @@ static bool ParseAnalyzerArgs(AnalyzerOptions &Opts, ArgList &Args,
#include "clang/Driver/Options.inc"
#undef ANALYZER_OPTION_WITH_MARSHALLING
- if (Args.hasArg(OPT_analyzer_store))
- Diags.Report(diag::warn_analyzer_deprecated_option) << "-analyzer-store"
- << "clang-16";
- if (Args.hasArg(OPT_analyzer_opt_analyze_nested_blocks))
- Diags.Report(diag::warn_analyzer_deprecated_option)
- << "-analyzer-opt-analyze-nested-blocks"
- << "clang-16";
-
if (Arg *A = Args.getLastArg(OPT_analyzer_constraints)) {
StringRef Name = A->getValue();
AnalysisConstraints Value = llvm::StringSwitch<AnalysisConstraints>(Name)
@@ -1024,6 +1020,15 @@ static bool ParseAnalyzerArgs(AnalyzerOptions &Opts, ArgList &Args,
A->claim();
Opts.Config[key] = std::string(val);
+
+ // FIXME: Remove this hunk after clang-17 released.
+ constexpr auto SingleFAM =
+ "consider-single-element-arrays-as-flexible-array-members";
+ if (key == SingleFAM) {
+ Diags.Report(diag::warn_analyzer_deprecated_option_with_alternative)
+ << SingleFAM << "clang-17"
+ << "-fstrict-flex-arrays=<N>";
+ }
}
}
@@ -1061,11 +1066,12 @@ static void initOption(AnalyzerOptions::ConfigTable &Config,
static void initOption(AnalyzerOptions::ConfigTable &Config,
DiagnosticsEngine *Diags,
bool &OptionField, StringRef Name, bool DefaultVal) {
- auto PossiblyInvalidVal = llvm::StringSwitch<Optional<bool>>(
- getStringOption(Config, Name, (DefaultVal ? "true" : "false")))
- .Case("true", true)
- .Case("false", false)
- .Default(None);
+ auto PossiblyInvalidVal =
+ llvm::StringSwitch<std::optional<bool>>(
+ getStringOption(Config, Name, (DefaultVal ? "true" : "false")))
+ .Case("true", true)
+ .Case("false", false)
+ .Default(std::nullopt);
if (!PossiblyInvalidVal) {
if (Diags)
@@ -1297,17 +1303,23 @@ static std::string serializeXRayInstrumentationBundle(const XRayInstrSet &S) {
// Set the profile kind using fprofile-instrument-use-path.
static void setPGOUseInstrumentor(CodeGenOptions &Opts,
- const Twine &ProfileName) {
+ const Twine &ProfileName,
+ DiagnosticsEngine &Diags) {
auto ReaderOrErr = llvm::IndexedInstrProfReader::create(ProfileName);
- // In error, return silently and let Clang PGOUse report the error message.
if (auto E = ReaderOrErr.takeError()) {
- llvm::consumeError(std::move(E));
- Opts.setProfileUse(CodeGenOptions::ProfileClangInstr);
+ unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
+ "Error in reading profile %0: %1");
+ llvm::handleAllErrors(std::move(E), [&](const llvm::ErrorInfoBase &EI) {
+ Diags.Report(DiagID) << ProfileName.str() << EI.message();
+ });
return;
}
std::unique_ptr<llvm::IndexedInstrProfReader> PGOReader =
std::move(ReaderOrErr.get());
- if (PGOReader->isIRLevelProfile()) {
+ // Currently memprof profiles are only added at the IR level. Mark the profile
+ // type as IR in that case as well and the subsequent matching needs to detect
+ // which is available (might be one or both).
+ if (PGOReader->isIRLevelProfile() || PGOReader->hasMemoryProfile()) {
if (PGOReader->hasCSIRLevelProfile())
Opts.setProfileUse(CodeGenOptions::ProfileCSIRInstr);
else
@@ -1352,7 +1364,7 @@ void CompilerInvocation::GenerateCodeGenArgs(
else if (!Opts.DirectAccessExternalData && LangOpts->PICLevel == 0)
GenerateArg(Args, OPT_fno_direct_access_external_data, SA);
- Optional<StringRef> DebugInfoVal;
+ std::optional<StringRef> DebugInfoVal;
switch (Opts.DebugInfo) {
case codegenoptions::DebugLineTablesOnly:
DebugInfoVal = "line-tables-only";
@@ -1373,10 +1385,10 @@ void CompilerInvocation::GenerateCodeGenArgs(
DebugInfoVal = "unused-types";
break;
case codegenoptions::NoDebugInfo: // default value
- DebugInfoVal = None;
+ DebugInfoVal = std::nullopt;
break;
case codegenoptions::LocTrackingOnly: // implied value
- DebugInfoVal = None;
+ DebugInfoVal = std::nullopt;
break;
}
if (DebugInfoVal)
@@ -1482,9 +1494,6 @@ void CompilerInvocation::GenerateCodeGenArgs(
else if (Opts.CFProtectionBranch)
GenerateArg(Args, OPT_fcf_protection_EQ, "branch", SA);
- if (Opts.IBTSeal)
- GenerateArg(Args, OPT_mibt_seal, SA);
-
if (Opts.FunctionReturnThunks)
GenerateArg(Args, OPT_mfunction_return_EQ, "thunk-extern", SA);
@@ -1496,13 +1505,8 @@ void CompilerInvocation::GenerateCodeGenArgs(
F.Filename, SA);
}
- // TODO: Consider removing marshalling annotations from f[no_]emulated_tls.
- // That would make it easy to generate the option only **once** if it was
- // explicitly set to non-default value.
- if (Opts.ExplicitEmulatedTLS) {
- GenerateArg(
- Args, Opts.EmulatedTLS ? OPT_femulated_tls : OPT_fno_emulated_tls, SA);
- }
+ GenerateArg(
+ Args, Opts.EmulatedTLS ? OPT_femulated_tls : OPT_fno_emulated_tls, SA);
if (Opts.FPDenormalMode != llvm::DenormalMode::getIEEE())
GenerateArg(Args, OPT_fdenormal_fp_math_EQ, Opts.FPDenormalMode.str(), SA);
@@ -1713,7 +1717,7 @@ bool CompilerInvocation::ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args,
StringRef Value = A->getValue();
if (Value != "simple" && Value != "mangled")
Diags.Report(diag::err_drv_unsupported_option_argument)
- << A->getOption().getName() << A->getValue();
+ << A->getSpelling() << A->getValue();
Opts.setDebugSimpleTemplateNames(
StringRef(A->getValue()) == "simple"
? codegenoptions::DebugTemplateNamesKind::Simple
@@ -1721,7 +1725,7 @@ bool CompilerInvocation::ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args,
}
if (!Opts.ProfileInstrumentUsePath.empty())
- setPGOUseInstrumentor(Opts, Opts.ProfileInstrumentUsePath);
+ setPGOUseInstrumentor(Opts, Opts.ProfileInstrumentUsePath, Diags);
if (const Arg *A = Args.getLastArg(OPT_ftime_report, OPT_ftime_report_EQ)) {
Opts.TimePasses = true;
@@ -1849,9 +1853,6 @@ bool CompilerInvocation::ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args,
Opts.FunctionReturnThunks = static_cast<unsigned>(Val);
}
- if (Opts.PrepareForLTO && Args.hasArg(OPT_mibt_seal))
- Opts.IBTSeal = 1;
-
for (auto *A :
Args.filtered(OPT_mlink_bitcode_file, OPT_mlink_builtin_bitcode)) {
CodeGenOptions::BitcodeFileToLink F;
@@ -1866,9 +1867,9 @@ bool CompilerInvocation::ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args,
Opts.LinkBitcodeFiles.push_back(F);
}
- if (Args.getLastArg(OPT_femulated_tls) ||
- Args.getLastArg(OPT_fno_emulated_tls)) {
- Opts.ExplicitEmulatedTLS = true;
+ if (!Args.getLastArg(OPT_femulated_tls) &&
+ !Args.getLastArg(OPT_fno_emulated_tls)) {
+ Opts.EmulatedTLS = T.hasDefaultEmulatedTLS();
}
if (Arg *A = Args.getLastArg(OPT_ftlsmodel_EQ)) {
@@ -1982,7 +1983,7 @@ bool CompilerInvocation::ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args,
} else {
Opts.DiagnosticsHotnessThreshold = *ResultOrErr;
if ((!Opts.DiagnosticsHotnessThreshold ||
- Opts.DiagnosticsHotnessThreshold.value() > 0) &&
+ *Opts.DiagnosticsHotnessThreshold > 0) &&
!UsingProfile)
Diags.Report(diag::warn_drv_diagnostics_hotness_requires_pgo)
<< "-fdiagnostics-hotness-threshold=";
@@ -1999,7 +2000,7 @@ bool CompilerInvocation::ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args,
} else {
Opts.DiagnosticsMisExpectTolerance = *ResultOrErr;
if ((!Opts.DiagnosticsMisExpectTolerance ||
- Opts.DiagnosticsMisExpectTolerance.value() > 0) &&
+ *Opts.DiagnosticsMisExpectTolerance > 0) &&
!UsingProfile)
Diags.Report(diag::warn_drv_diagnostics_misexpect_requires_pgo)
<< "-fdiagnostics-misexpect-tolerance=";
@@ -2146,6 +2147,16 @@ static bool ParseDependencyOutputArgs(DependencyOutputOptions &Opts,
Opts.ExtraDeps.emplace_back(std::string(Val), EDK_ModuleFile);
}
+ // Check for invalid combinations of header-include-format
+ // and header-include-filtering.
+ if ((Opts.HeaderIncludeFormat == HIFMT_Textual &&
+ Opts.HeaderIncludeFiltering != HIFIL_None) ||
+ (Opts.HeaderIncludeFormat == HIFMT_JSON &&
+ Opts.HeaderIncludeFiltering != HIFIL_Only_Direct_System))
+ Diags.Report(diag::err_drv_print_header_env_var_combination_cc1)
+ << Args.getLastArg(OPT_header_include_format_EQ)->getValue()
+ << Args.getLastArg(OPT_header_include_filtering_EQ)->getValue();
+
return Diags.getNumErrors() == NumErrorsBefore;
}
@@ -2353,7 +2364,7 @@ clang::CreateAndPopulateDiagOpts(ArrayRef<const char *> Argv) {
bool clang::ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args,
DiagnosticsEngine *Diags,
bool DefaultDiagColor) {
- Optional<DiagnosticsEngine> IgnoringDiags;
+ std::optional<DiagnosticsEngine> IgnoringDiags;
if (!Diags) {
IgnoringDiags.emplace(new DiagnosticIDs(), new DiagnosticOptions(),
new IgnoringDiagConsumer());
@@ -2471,7 +2482,6 @@ static const auto &getFrontendActionTable() {
{frontend::GenerateModule, OPT_emit_module},
{frontend::GenerateModuleInterface, OPT_emit_module_interface},
- {frontend::GenerateHeaderModule, OPT_emit_header_module},
{frontend::GenerateHeaderUnit, OPT_emit_header_unit},
{frontend::GeneratePCH, OPT_emit_pch},
{frontend::GenerateInterfaceStubs, OPT_emit_interface_stubs},
@@ -2496,22 +2506,23 @@ static const auto &getFrontendActionTable() {
}
/// Maps command line option to frontend action.
-static Optional<frontend::ActionKind> getFrontendAction(OptSpecifier &Opt) {
+static std::optional<frontend::ActionKind>
+getFrontendAction(OptSpecifier &Opt) {
for (const auto &ActionOpt : getFrontendActionTable())
if (ActionOpt.second == Opt.getID())
return ActionOpt.first;
- return None;
+ return std::nullopt;
}
/// Maps frontend action to command line option.
-static Optional<OptSpecifier>
+static std::optional<OptSpecifier>
getProgramActionOpt(frontend::ActionKind ProgramAction) {
for (const auto &ActionOpt : getFrontendActionTable())
if (ActionOpt.first == ProgramAction)
return OptSpecifier(ActionOpt.second);
- return None;
+ return std::nullopt;
}
static void GenerateFrontendArgs(const FrontendOptions &Opts,
@@ -2530,7 +2541,7 @@ static void GenerateFrontendArgs(const FrontendOptions &Opts,
#include "clang/Driver/Options.inc"
#undef FRONTEND_OPTION_WITH_MARSHALLING
- Optional<OptSpecifier> ProgramActionOpt =
+ std::optional<OptSpecifier> ProgramActionOpt =
getProgramActionOpt(Opts.ProgramAction);
// Generating a simple flag covers most frontend actions.
@@ -2709,7 +2720,7 @@ static bool ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args,
Opts.ProgramAction = frontend::ParseSyntaxOnly;
if (const Arg *A = Args.getLastArg(OPT_Action_Group)) {
OptSpecifier Opt = OptSpecifier(A->getOption().getID());
- Optional<frontend::ActionKind> ProgramAction = getFrontendAction(Opt);
+ std::optional<frontend::ActionKind> ProgramAction = getFrontendAction(Opt);
assert(ProgramAction && "Option specifier not in Action_Group.");
if (ProgramAction == frontend::ASTDump &&
@@ -2982,8 +2993,8 @@ static void GenerateHeaderSearchArgs(HeaderSearchOptions &Opts,
auto Matches = [](const HeaderSearchOptions::Entry &Entry,
llvm::ArrayRef<frontend::IncludeDirGroup> Groups,
- llvm::Optional<bool> IsFramework,
- llvm::Optional<bool> IgnoreSysRoot) {
+ std::optional<bool> IsFramework,
+ std::optional<bool> IgnoreSysRoot) {
return llvm::is_contained(Groups, Entry.Group) &&
(!IsFramework || (Entry.IsFramework == *IsFramework)) &&
(!IgnoreSysRoot || (Entry.IgnoreSysRoot == *IgnoreSysRoot));
@@ -2993,8 +3004,8 @@ static void GenerateHeaderSearchArgs(HeaderSearchOptions &Opts,
auto End = Opts.UserEntries.end();
// Add -I..., -F..., and -index-header-map options in order.
- for (; It < End &&
- Matches(*It, {frontend::IndexHeaderMap, frontend::Angled}, None, true);
+ for (; It < End && Matches(*It, {frontend::IndexHeaderMap, frontend::Angled},
+ std::nullopt, true);
++It) {
OptSpecifier Opt = [It, Matches]() {
if (Matches(*It, frontend::IndexHeaderMap, true, true))
@@ -3032,7 +3043,8 @@ static void GenerateHeaderSearchArgs(HeaderSearchOptions &Opts,
GenerateArg(Args, OPT_idirafter, It->Path, SA);
for (; It < End && Matches(*It, {frontend::Quoted}, false, true); ++It)
GenerateArg(Args, OPT_iquote, It->Path, SA);
- for (; It < End && Matches(*It, {frontend::System}, false, None); ++It)
+ for (; It < End && Matches(*It, {frontend::System}, false, std::nullopt);
+ ++It)
GenerateArg(Args, It->IgnoreSysRoot ? OPT_isystem : OPT_iwithsysroot,
It->Path, SA);
for (; It < End && Matches(*It, {frontend::System}, true, true); ++It)
@@ -3488,9 +3500,6 @@ void CompilerInvocation::GenerateLangArgs(const LangOptions &Opts,
if (Opts.OpenMPCUDAMode)
GenerateArg(Args, OPT_fopenmp_cuda_mode, SA);
- if (Opts.OpenMPCUDAForceFullRuntime)
- GenerateArg(Args, OPT_fopenmp_cuda_force_full_runtime, SA);
-
// The arguments used to set Optimize, OptimizeSize and NoInlineDefine are
// generated from CodeGenOptions.
@@ -3526,6 +3535,8 @@ void CompilerInvocation::GenerateLangArgs(const LangOptions &Opts,
GenerateArg(Args, OPT_fclang_abi_compat_EQ, "12.0", SA);
else if (Opts.getClangABICompat() == LangOptions::ClangABI::Ver14)
GenerateArg(Args, OPT_fclang_abi_compat_EQ, "14.0", SA);
+ else if (Opts.getClangABICompat() == LangOptions::ClangABI::Ver15)
+ GenerateArg(Args, OPT_fclang_abi_compat_EQ, "15.0", SA);
if (Opts.getSignReturnAddressScope() ==
LangOptions::SignReturnAddressScopeKind::All)
@@ -3802,7 +3813,7 @@ bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args,
else
Opts.LongDoubleSize = 0;
}
- if (Opts.FastRelaxedMath)
+ if (Opts.FastRelaxedMath || Opts.CLUnsafeMath)
Opts.setDefaultFPContractMode(LangOptions::FPM_Fast);
llvm::sort(Opts.ModuleFeatures);
@@ -3940,11 +3951,6 @@ bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args,
Opts.OpenMPCUDAMode = Opts.OpenMPIsDevice && (T.isNVPTX() || T.isAMDGCN()) &&
Args.hasArg(options::OPT_fopenmp_cuda_mode);
- // Set CUDA mode for OpenMP target NVPTX/AMDGCN if specified in options
- Opts.OpenMPCUDAForceFullRuntime =
- Opts.OpenMPIsDevice && (T.isNVPTX() || T.isAMDGCN()) &&
- Args.hasArg(options::OPT_fopenmp_cuda_force_full_runtime);
-
// FIXME: Eliminate this dependency.
unsigned Opt = getOptimizationLevel(Args, IK, Diags),
OptSize = getOptimizationLevelSize(Args);
@@ -4018,6 +4024,8 @@ bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args,
Opts.setClangABICompat(LangOptions::ClangABI::Ver12);
else if (Major <= 14)
Opts.setClangABICompat(LangOptions::ClangABI::Ver14);
+ else if (Major <= 15)
+ Opts.setClangABICompat(LangOptions::ClangABI::Ver15);
} else if (Ver != "latest") {
Diags.Report(diag::err_drv_invalid_value)
<< A->getAsString(Args) << A->getValue();
@@ -4107,6 +4115,14 @@ bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args,
if (const Arg *A = Args.getLastArg(OPT_frandomize_layout_seed_EQ))
Opts.RandstructSeed = A->getValue(0);
+ // Validate options for HLSL
+ if (Opts.HLSL) {
+ bool SupportedTarget = T.getArch() == llvm::Triple::dxil &&
+ T.getOS() == llvm::Triple::ShaderModel;
+ if (!SupportedTarget)
+ Diags.Report(diag::err_drv_hlsl_unsupported_target) << T.str();
+ }
+
return Diags.getNumErrors() == NumErrorsBefore;
}
@@ -4127,7 +4143,6 @@ static bool isStrictlyPreprocessorAction(frontend::ActionKind Action) {
case frontend::FixIt:
case frontend::GenerateModule:
case frontend::GenerateModuleInterface:
- case frontend::GenerateHeaderModule:
case frontend::GenerateHeaderUnit:
case frontend::GeneratePCH:
case frontend::GenerateInterfaceStubs:
@@ -4224,6 +4239,9 @@ static void GeneratePreprocessorArgs(PreprocessorOptions &Opts,
for (const auto &RF : Opts.RemappedFiles)
GenerateArg(Args, OPT_remap_file, RF.first + ";" + RF.second, SA);
+ if (Opts.SourceDateEpoch)
+ GenerateArg(Args, OPT_source_date_epoch, Twine(*Opts.SourceDateEpoch), SA);
+
// Don't handle LexEditorPlaceholders. It is implied by the action that is
// generated elsewhere.
}
@@ -4306,6 +4324,22 @@ static bool ParsePreprocessorArgs(PreprocessorOptions &Opts, ArgList &Args,
Opts.addRemappedFile(Split.first, Split.second);
}
+ if (const Arg *A = Args.getLastArg(OPT_source_date_epoch)) {
+ StringRef Epoch = A->getValue();
+ // SOURCE_DATE_EPOCH, if specified, must be a non-negative decimal integer.
+ // On time64 systems, pick 253402300799 (the UNIX timestamp of
+ // 9999-12-31T23:59:59Z) as the upper bound.
+ const uint64_t MaxTimestamp =
+ std::min<uint64_t>(std::numeric_limits<time_t>::max(), 253402300799);
+ uint64_t V;
+ if (Epoch.getAsInteger(10, V) || V > MaxTimestamp) {
+ Diags.Report(diag::err_fe_invalid_source_date_epoch)
+ << Epoch << MaxTimestamp;
+ } else {
+ Opts.SourceDateEpoch = V;
+ }
+ }
+
// Always avoid lexing editor placeholders when we're just running the
// preprocessor as we never want to emit the
// "editor placeholder in source file" error in PP only mode.
@@ -4524,8 +4558,10 @@ bool CompilerInvocation::CreateFromArgsImpl(
}
// Store the command-line for using in the CodeView backend.
- Res.getCodeGenOpts().Argv0 = Argv0;
- append_range(Res.getCodeGenOpts().CommandLineArgs, CommandLineArgs);
+ if (Res.getCodeGenOpts().CodeViewCommandLine) {
+ Res.getCodeGenOpts().Argv0 = Argv0;
+ append_range(Res.getCodeGenOpts().CommandLineArgs, CommandLineArgs);
+ }
FixupInvocation(Res, Diags, Args, DashX);
@@ -4544,7 +4580,10 @@ bool CompilerInvocation::CreateFromArgs(CompilerInvocation &Invocation,
return CreateFromArgsImpl(Invocation, CommandLineArgs, Diags, Argv0);
},
[](CompilerInvocation &Invocation, SmallVectorImpl<const char *> &Args,
- StringAllocator SA) { Invocation.generateCC1CommandLine(Args, SA); },
+ StringAllocator SA) {
+ Args.push_back("-cc1");
+ Invocation.generateCC1CommandLine(Args, SA);
+ },
Invocation, DummyInvocation, CommandLineArgs, Diags, Argv0);
}
@@ -4665,6 +4704,37 @@ void CompilerInvocation::generateCC1CommandLine(
GenerateDependencyOutputArgs(DependencyOutputOpts, Args, SA);
}
+std::vector<std::string> CompilerInvocation::getCC1CommandLine() const {
+ // Set up string allocator.
+ llvm::BumpPtrAllocator Alloc;
+ llvm::StringSaver Strings(Alloc);
+ auto SA = [&Strings](const Twine &Arg) { return Strings.save(Arg).data(); };
+
+ // Synthesize full command line from the CompilerInvocation, including "-cc1".
+ SmallVector<const char *, 32> Args{"-cc1"};
+ generateCC1CommandLine(Args, SA);
+
+ // Convert arguments to the return type.
+ return std::vector<std::string>{Args.begin(), Args.end()};
+}
+
+void CompilerInvocation::resetNonModularOptions() {
+ getLangOpts()->resetNonModularOptions();
+ getPreprocessorOpts().resetNonModularOptions();
+}
+
+void CompilerInvocation::clearImplicitModuleBuildOptions() {
+ getLangOpts()->ImplicitModules = false;
+ getHeaderSearchOpts().ImplicitModuleMaps = false;
+ getHeaderSearchOpts().ModuleCachePath.clear();
+ getHeaderSearchOpts().ModulesValidateOncePerBuildSession = false;
+ getHeaderSearchOpts().BuildSessionTimestamp = 0;
+ // The specific values we canonicalize to for pruning don't affect behaviour,
+ /// so use the default values so they may be dropped from the command-line.
+ getHeaderSearchOpts().ModuleCachePruneInterval = 7 * 24 * 60 * 60;
+ getHeaderSearchOpts().ModuleCachePruneAfter = 31 * 24 * 60 * 60;
+}
+
IntrusiveRefCntPtr<llvm::vfs::FileSystem>
clang::createVFSFromCompilerInvocation(const CompilerInvocation &CI,
DiagnosticsEngine &Diags) {
@@ -4676,12 +4746,19 @@ IntrusiveRefCntPtr<llvm::vfs::FileSystem>
clang::createVFSFromCompilerInvocation(
const CompilerInvocation &CI, DiagnosticsEngine &Diags,
IntrusiveRefCntPtr<llvm::vfs::FileSystem> BaseFS) {
- if (CI.getHeaderSearchOpts().VFSOverlayFiles.empty())
+ return createVFSFromOverlayFiles(CI.getHeaderSearchOpts().VFSOverlayFiles,
+ Diags, std::move(BaseFS));
+}
+
+IntrusiveRefCntPtr<llvm::vfs::FileSystem> clang::createVFSFromOverlayFiles(
+ ArrayRef<std::string> VFSOverlayFiles, DiagnosticsEngine &Diags,
+ IntrusiveRefCntPtr<llvm::vfs::FileSystem> BaseFS) {
+ if (VFSOverlayFiles.empty())
return BaseFS;
IntrusiveRefCntPtr<llvm::vfs::FileSystem> Result = BaseFS;
// earlier vfs files are on the bottom
- for (const auto &File : CI.getHeaderSearchOpts().VFSOverlayFiles) {
+ for (const auto &File : VFSOverlayFiles) {
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Buffer =
Result->getBufferForFile(File);
if (!Buffer) {