-
Notifications
You must be signed in to change notification settings - Fork 14.5k
[clang] Move ExceptionHandling
from LangOptions
to CodeGenOptions
#148982
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[clang] Move ExceptionHandling
from LangOptions
to CodeGenOptions
#148982
Conversation
This PR removes the workaround introduced in llvm#146342 by moving `LangOptions::ExceptionHandling` to `CodeGenOptions` that get parsed even for IR input. This got enabled by llvm#146422.
@llvm/pr-subscribers-clang @llvm/pr-subscribers-clang-codegen Author: Jan Svoboda (jansvoboda11) ChangesThis PR removes the command line parsing workaround introduced in #146342 by moving Full diff: https://github.com/llvm/llvm-project/pull/148982.diff 9 Files Affected:
diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def
index a11e12d495cd2..cfffeb71f09d1 100644
--- a/clang/include/clang/Basic/CodeGenOptions.def
+++ b/clang/include/clang/Basic/CodeGenOptions.def
@@ -56,6 +56,8 @@ CODEGENOPT(XCOFFReadOnlyPointers, 1, 0, Benign) ///< Set for -mxcoff-roptr.
CODEGENOPT(AllTocData, 1, 0, Benign) ///< AIX -mtocdata
ENUM_CODEGENOPT(FramePointer, FramePointerKind, 2, FramePointerKind::None, Benign) /// frame-pointer: all,non-leaf,reserved,none
+ENUM_CODEGENOPT(ExceptionHandling, ExceptionHandlingKind, 3, ExceptionHandlingKind::None, NotCompatible)
+
CODEGENOPT(ClearASTBeforeBackend , 1, 0, Benign) ///< Free the AST before running backend code generation. Only works with -disable-free.
CODEGENOPT(DisableFree , 1, 0, Benign) ///< Don't free memory.
CODEGENOPT(DiscardValueNames , 1, 0, Benign) ///< Discard Value Names from the IR (LLVMContext flag)
diff --git a/clang/include/clang/Basic/CodeGenOptions.h b/clang/include/clang/Basic/CodeGenOptions.h
index df4403ace5fe3..cdeedd5b4eac6 100644
--- a/clang/include/clang/Basic/CodeGenOptions.h
+++ b/clang/include/clang/Basic/CodeGenOptions.h
@@ -176,6 +176,9 @@ class CodeGenOptions : public CodeGenOptionsBase {
llvm_unreachable("invalid FramePointerKind");
}
+ /// Possible exception handling behavior.
+ enum class ExceptionHandlingKind { None, SjLj, WinEH, DwarfCFI, Wasm };
+
enum class SwiftAsyncFramePointerKind {
Auto, // Choose Swift async extended frame info based on deployment target.
Always, // Unconditionally emit Swift async extended frame info.
@@ -552,6 +555,22 @@ class CodeGenOptions : public CodeGenOptionsBase {
return NoBuiltinFuncs;
}
+ bool hasSjLjExceptions() const {
+ return getExceptionHandling() == ExceptionHandlingKind::SjLj;
+ }
+
+ bool hasSEHExceptions() const {
+ return getExceptionHandling() == ExceptionHandlingKind::WinEH;
+ }
+
+ bool hasDWARFExceptions() const {
+ return getExceptionHandling() == ExceptionHandlingKind::DwarfCFI;
+ }
+
+ bool hasWasmExceptions() const {
+ return getExceptionHandling() == ExceptionHandlingKind::Wasm;
+ }
+
/// Check if Clang profile instrumenation is on.
bool hasProfileClangInstr() const {
return getProfileInstr() ==
diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def
index 6c47107796236..6ac8d496f1494 100644
--- a/clang/include/clang/Basic/LangOptions.def
+++ b/clang/include/clang/Basic/LangOptions.def
@@ -98,8 +98,6 @@ LANGOPT(Exceptions , 1, 0, NotCompatible, "exception handling")
LANGOPT(ObjCExceptions , 1, 0, NotCompatible, "Objective-C exceptions")
LANGOPT(CXXExceptions , 1, 0, NotCompatible, "C++ exceptions")
LANGOPT(EHAsynch , 1, 0, NotCompatible, "C/C++ EH Asynch exceptions")
-ENUM_LANGOPT(ExceptionHandling, ExceptionHandlingKind, 3,
- ExceptionHandlingKind::None, NotCompatible, "exception handling")
LANGOPT(IgnoreExceptions , 1, 0, NotCompatible, "ignore exceptions")
LANGOPT(ExternCNoUnwind , 1, 0, NotCompatible, "Assume extern C functions don't unwind")
LANGOPT(AssumeNothrowExceptionDtor , 1, 0, NotCompatible, "Assume exception object's destructor is nothrow")
diff --git a/clang/include/clang/Basic/LangOptions.h b/clang/include/clang/Basic/LangOptions.h
index 4c642c9e10c91..937cbff4e3ea3 100644
--- a/clang/include/clang/Basic/LangOptions.h
+++ b/clang/include/clang/Basic/LangOptions.h
@@ -337,9 +337,6 @@ class LangOptionsBase {
enum ExcessPrecisionKind { FPP_Standard, FPP_Fast, FPP_None };
- /// Possible exception handling behavior.
- enum class ExceptionHandlingKind { None, SjLj, WinEH, DwarfCFI, Wasm };
-
enum class LaxVectorConversionKind {
/// Permit no implicit vector bitcasts.
None,
@@ -788,22 +785,6 @@ class LangOptions : public LangOptionsBase {
return getSignReturnAddressScope() == SignReturnAddressScopeKind::All;
}
- bool hasSjLjExceptions() const {
- return getExceptionHandling() == ExceptionHandlingKind::SjLj;
- }
-
- bool hasSEHExceptions() const {
- return getExceptionHandling() == ExceptionHandlingKind::WinEH;
- }
-
- bool hasDWARFExceptions() const {
- return getExceptionHandling() == ExceptionHandlingKind::DwarfCFI;
- }
-
- bool hasWasmExceptions() const {
- return getExceptionHandling() == ExceptionHandlingKind::Wasm;
- }
-
bool isSYCL() const { return SYCLIsDevice || SYCLIsHost; }
bool hasDefaultVisibilityExportMapping() const {
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index bce29a76f3ac7..9ea15de132df1 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -2177,9 +2177,9 @@ def fwasm_exceptions : Flag<["-"], "fwasm-exceptions">, Group<f_Group>,
def exception_model : Separate<["-"], "exception-model">,
Visibility<[CC1Option]>, HelpText<"The exception model">,
Values<"dwarf,sjlj,seh,wasm">,
- NormalizedValuesScope<"LangOptions::ExceptionHandlingKind">,
+ NormalizedValuesScope<"CodeGenOptions::ExceptionHandlingKind">,
NormalizedValues<["DwarfCFI", "SjLj", "WinEH", "Wasm"]>,
- MarshallingInfoEnum<LangOpts<"ExceptionHandling">, "None">;
+ MarshallingInfoEnum<CodeGenOpts<"ExceptionHandling">, "None">;
def exception_model_EQ : Joined<["-"], "exception-model=">,
Visibility<[CC1Option]>, Alias<exception_model>;
def fignore_exceptions : Flag<["-"], "fignore-exceptions">, Group<f_Group>,
diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp
index 2f6d4c414e737..1b7257857dd3b 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -407,13 +407,13 @@ static bool initTargetOptions(const CompilerInstance &CI,
// Set EABI version.
Options.EABIVersion = TargetOpts.EABIVersion;
- if (LangOpts.hasSjLjExceptions())
+ if (CodeGenOpts.hasSjLjExceptions())
Options.ExceptionModel = llvm::ExceptionHandling::SjLj;
- if (LangOpts.hasSEHExceptions())
+ if (CodeGenOpts.hasSEHExceptions())
Options.ExceptionModel = llvm::ExceptionHandling::WinEH;
- if (LangOpts.hasDWARFExceptions())
+ if (CodeGenOpts.hasDWARFExceptions())
Options.ExceptionModel = llvm::ExceptionHandling::DwarfCFI;
- if (LangOpts.hasWasmExceptions())
+ if (CodeGenOpts.hasWasmExceptions())
Options.ExceptionModel = llvm::ExceptionHandling::Wasm;
Options.NoInfsFPMath = LangOpts.NoHonorInfs;
diff --git a/clang/lib/CodeGen/CGException.cpp b/clang/lib/CodeGen/CGException.cpp
index ad138b9876e8c..f86af4581c345 100644
--- a/clang/lib/CodeGen/CGException.cpp
+++ b/clang/lib/CodeGen/CGException.cpp
@@ -131,20 +131,21 @@ const EHPersonality EHPersonality::ZOS_CPlusPlus = {"__zos_cxx_personality_v2",
nullptr};
static const EHPersonality &getCPersonality(const TargetInfo &Target,
- const LangOptions &L) {
+ const CodeGenOptions &CGOpts) {
const llvm::Triple &T = Target.getTriple();
if (T.isWindowsMSVCEnvironment())
return EHPersonality::MSVC_CxxFrameHandler3;
- if (L.hasSjLjExceptions())
+ if (CGOpts.hasSjLjExceptions())
return EHPersonality::GNU_C_SJLJ;
- if (L.hasDWARFExceptions())
+ if (CGOpts.hasDWARFExceptions())
return EHPersonality::GNU_C;
- if (L.hasSEHExceptions())
+ if (CGOpts.hasSEHExceptions())
return EHPersonality::GNU_C_SEH;
return EHPersonality::GNU_C;
}
static const EHPersonality &getObjCPersonality(const TargetInfo &Target,
+ const CodeGenOptions &CGOpts,
const LangOptions &L) {
const llvm::Triple &T = Target.getTriple();
if (T.isWindowsMSVCEnvironment())
@@ -152,7 +153,7 @@ static const EHPersonality &getObjCPersonality(const TargetInfo &Target,
switch (L.ObjCRuntime.getKind()) {
case ObjCRuntime::FragileMacOSX:
- return getCPersonality(Target, L);
+ return getCPersonality(Target, CGOpts);
case ObjCRuntime::MacOSX:
case ObjCRuntime::iOS:
case ObjCRuntime::WatchOS:
@@ -165,9 +166,9 @@ static const EHPersonality &getObjCPersonality(const TargetInfo &Target,
[[fallthrough]];
case ObjCRuntime::GCC:
case ObjCRuntime::ObjFW:
- if (L.hasSjLjExceptions())
+ if (CGOpts.hasSjLjExceptions())
return EHPersonality::GNU_ObjC_SJLJ;
- if (L.hasSEHExceptions())
+ if (CGOpts.hasSEHExceptions())
return EHPersonality::GNU_ObjC_SEH;
return EHPersonality::GNU_ObjC;
}
@@ -175,19 +176,19 @@ static const EHPersonality &getObjCPersonality(const TargetInfo &Target,
}
static const EHPersonality &getCXXPersonality(const TargetInfo &Target,
- const LangOptions &L) {
+ const CodeGenOptions &CGOpts) {
const llvm::Triple &T = Target.getTriple();
if (T.isWindowsMSVCEnvironment())
return EHPersonality::MSVC_CxxFrameHandler3;
if (T.isOSAIX())
return EHPersonality::XL_CPlusPlus;
- if (L.hasSjLjExceptions())
+ if (CGOpts.hasSjLjExceptions())
return EHPersonality::GNU_CPlusPlus_SJLJ;
- if (L.hasDWARFExceptions())
+ if (CGOpts.hasDWARFExceptions())
return EHPersonality::GNU_CPlusPlus;
- if (L.hasSEHExceptions())
+ if (CGOpts.hasSEHExceptions())
return EHPersonality::GNU_CPlusPlus_SEH;
- if (L.hasWasmExceptions())
+ if (CGOpts.hasWasmExceptions())
return EHPersonality::GNU_Wasm_CPlusPlus;
if (T.isOSzOS())
return EHPersonality::ZOS_CPlusPlus;
@@ -197,6 +198,7 @@ static const EHPersonality &getCXXPersonality(const TargetInfo &Target,
/// Determines the personality function to use when both C++
/// and Objective-C exceptions are being caught.
static const EHPersonality &getObjCXXPersonality(const TargetInfo &Target,
+ const CodeGenOptions &CGOpts,
const LangOptions &L) {
if (Target.getTriple().isWindowsMSVCEnvironment())
return EHPersonality::MSVC_CxxFrameHandler3;
@@ -205,7 +207,7 @@ static const EHPersonality &getObjCXXPersonality(const TargetInfo &Target,
// In the fragile ABI, just use C++ exception handling and hope
// they're not doing crazy exception mixing.
case ObjCRuntime::FragileMacOSX:
- return getCXXPersonality(Target, L);
+ return getCXXPersonality(Target, CGOpts);
// The ObjC personality defers to the C++ personality for non-ObjC
// handlers. Unlike the C++ case, we use the same personality
@@ -213,7 +215,7 @@ static const EHPersonality &getObjCXXPersonality(const TargetInfo &Target,
case ObjCRuntime::MacOSX:
case ObjCRuntime::iOS:
case ObjCRuntime::WatchOS:
- return getObjCPersonality(Target, L);
+ return getObjCPersonality(Target, CGOpts, L);
case ObjCRuntime::GNUstep:
return Target.getTriple().isOSCygMing() ? EHPersonality::GNU_CPlusPlus_SEH
@@ -223,7 +225,7 @@ static const EHPersonality &getObjCXXPersonality(const TargetInfo &Target,
// mixed EH. Use the ObjC personality just to avoid returning null.
case ObjCRuntime::GCC:
case ObjCRuntime::ObjFW:
- return getObjCPersonality(Target, L);
+ return getObjCPersonality(Target, CGOpts, L);
}
llvm_unreachable("bad runtime kind");
}
@@ -237,6 +239,7 @@ static const EHPersonality &getSEHPersonalityMSVC(const llvm::Triple &T) {
const EHPersonality &EHPersonality::get(CodeGenModule &CGM,
const FunctionDecl *FD) {
const llvm::Triple &T = CGM.getTarget().getTriple();
+ const CodeGenOptions &CGOpts = CGM.getCodeGenOpts();
const LangOptions &L = CGM.getLangOpts();
const TargetInfo &Target = CGM.getTarget();
@@ -245,10 +248,10 @@ const EHPersonality &EHPersonality::get(CodeGenModule &CGM,
return getSEHPersonalityMSVC(T);
if (L.ObjC)
- return L.CPlusPlus ? getObjCXXPersonality(Target, L)
- : getObjCPersonality(Target, L);
- return L.CPlusPlus ? getCXXPersonality(Target, L)
- : getCPersonality(Target, L);
+ return L.CPlusPlus ? getObjCXXPersonality(Target, CGOpts, L)
+ : getObjCPersonality(Target, CGOpts, L);
+ return L.CPlusPlus ? getCXXPersonality(Target, CGOpts)
+ : getCPersonality(Target, CGOpts);
}
const EHPersonality &EHPersonality::get(CodeGenFunction &CGF) {
@@ -344,7 +347,7 @@ void CodeGenModule::SimplifyPersonality() {
return;
const EHPersonality &ObjCXX = EHPersonality::get(*this, /*FD=*/nullptr);
- const EHPersonality &CXX = getCXXPersonality(getTarget(), LangOpts);
+ const EHPersonality &CXX = getCXXPersonality(getTarget(), CodeGenOpts);
if (&ObjCXX == &CXX)
return;
@@ -500,7 +503,7 @@ void CodeGenFunction::EmitStartEHSpec(const Decl *D) {
// In Wasm EH we currently treat 'throw()' in the same way as 'noexcept'. In
// case of throw with types, we ignore it and print a warning for now.
// TODO Correctly handle exception specification in Wasm EH
- if (CGM.getLangOpts().hasWasmExceptions()) {
+ if (CGM.getCodeGenOpts().hasWasmExceptions()) {
if (EST == EST_DynamicNone)
EHStack.pushTerminate();
else
@@ -515,8 +518,8 @@ void CodeGenFunction::EmitStartEHSpec(const Decl *D) {
// throw with types.
// TODO Correctly handle exception specification in Emscripten EH
if (getTarget().getCXXABI() == TargetCXXABI::WebAssembly &&
- CGM.getLangOpts().getExceptionHandling() ==
- LangOptions::ExceptionHandlingKind::None &&
+ CGM.getCodeGenOpts().getExceptionHandling() ==
+ CodeGenOptions::ExceptionHandlingKind::None &&
EST == EST_Dynamic)
CGM.getDiags().Report(D->getLocation(),
diag::warn_wasm_dynamic_exception_spec_ignored)
@@ -604,7 +607,7 @@ void CodeGenFunction::EmitEndEHSpec(const Decl *D) {
// In wasm we currently treat 'throw()' in the same way as 'noexcept'. In
// case of throw with types, we ignore it and print a warning for now.
// TODO Correctly handle exception specification in wasm
- if (CGM.getLangOpts().hasWasmExceptions()) {
+ if (CGM.getCodeGenOpts().hasWasmExceptions()) {
if (EST == EST_DynamicNone)
EHStack.popTerminate();
return;
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index 56d10ceb986b3..6ab36d8675966 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -593,11 +593,11 @@ static bool FixupInvocation(CompilerInvocation &Invocation,
CodeGenOpts.CodeModel = TargetOpts.CodeModel;
CodeGenOpts.LargeDataThreshold = TargetOpts.LargeDataThreshold;
- if (LangOpts.getExceptionHandling() !=
- LangOptions::ExceptionHandlingKind::None &&
+ if (CodeGenOpts.getExceptionHandling() !=
+ CodeGenOptions::ExceptionHandlingKind::None &&
T.isWindowsMSVCEnvironment())
Diags.Report(diag::err_fe_invalid_exception_model)
- << static_cast<unsigned>(LangOpts.getExceptionHandling()) << T.str();
+ << static_cast<unsigned>(CodeGenOpts.getExceptionHandling()) << T.str();
if (LangOpts.AppleKext && !LangOpts.CPlusPlus)
Diags.Report(diag::warn_c_kext);
@@ -3713,23 +3713,6 @@ static StringRef GetInputKindName(InputKind IK) {
llvm_unreachable("unknown input language");
}
-static StringRef getExceptionHandlingName(unsigned EHK) {
- switch (static_cast<LangOptions::ExceptionHandlingKind>(EHK)) {
- case LangOptions::ExceptionHandlingKind::None:
- return "none";
- case LangOptions::ExceptionHandlingKind::DwarfCFI:
- return "dwarf";
- case LangOptions::ExceptionHandlingKind::SjLj:
- return "sjlj";
- case LangOptions::ExceptionHandlingKind::WinEH:
- return "seh";
- case LangOptions::ExceptionHandlingKind::Wasm:
- return "wasm";
- }
-
- llvm_unreachable("covered switch");
-}
-
void CompilerInvocationBase::GenerateLangArgs(const LangOptions &Opts,
ArgumentConsumer Consumer,
const llvm::Triple &T,
@@ -3745,10 +3728,6 @@ void CompilerInvocationBase::GenerateLangArgs(const LangOptions &Opts,
GenerateArg(Consumer, OPT_pic_is_pie);
for (StringRef Sanitizer : serializeSanitizerKinds(Opts.Sanitize))
GenerateArg(Consumer, OPT_fsanitize_EQ, Sanitizer);
- if (Opts.ExceptionHandling) {
- GenerateArg(Consumer, OPT_exception_model,
- getExceptionHandlingName(Opts.ExceptionHandling));
- }
return;
}
@@ -4057,24 +4036,6 @@ bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args,
parseSanitizerKinds("-fsanitize=", Args.getAllArgValues(OPT_fsanitize_EQ),
Diags, Opts.Sanitize);
- if (const Arg *A = Args.getLastArg(options::OPT_exception_model)) {
- std::optional<LangOptions::ExceptionHandlingKind> EMValue =
- llvm::StringSwitch<std::optional<LangOptions::ExceptionHandlingKind>>(
- A->getValue())
- .Case("dwarf", LangOptions::ExceptionHandlingKind::DwarfCFI)
- .Case("sjlj", LangOptions::ExceptionHandlingKind::SjLj)
- .Case("seh", LangOptions::ExceptionHandlingKind::WinEH)
- .Case("wasm", LangOptions::ExceptionHandlingKind::Wasm)
- .Case("none", LangOptions::ExceptionHandlingKind::None)
- .Default(std::nullopt);
- if (EMValue) {
- Opts.ExceptionHandling = static_cast<unsigned>(*EMValue);
- } else {
- Diags.Report(diag::err_drv_invalid_value)
- << A->getAsString(Args) << A->getValue();
- }
- }
-
return Diags.getNumErrors() == NumErrorsBefore;
}
diff --git a/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp
index 136bc55847cc1..38b2e0cf1ca59 100644
--- a/clang/lib/Frontend/InitPreprocessor.cpp
+++ b/clang/lib/Frontend/InitPreprocessor.cpp
@@ -1032,14 +1032,14 @@ static void InitializePredefinedMacros(const TargetInfo &TI,
if (LangOpts.GNUCVersion && LangOpts.RTTI)
Builder.defineMacro("__GXX_RTTI");
- if (LangOpts.hasSjLjExceptions())
+ if (CGOpts.hasSjLjExceptions())
Builder.defineMacro("__USING_SJLJ_EXCEPTIONS__");
- else if (LangOpts.hasSEHExceptions())
+ else if (CGOpts.hasSEHExceptions())
Builder.defineMacro("__SEH__");
- else if (LangOpts.hasDWARFExceptions() &&
+ else if (CGOpts.hasDWARFExceptions() &&
(TI.getTriple().isThumb() || TI.getTriple().isARM()))
Builder.defineMacro("__ARM_DWARF_EH__");
- else if (LangOpts.hasWasmExceptions() && TI.getTriple().isWasm())
+ else if (CGOpts.hasWasmExceptions() && TI.getTriple().isWasm())
Builder.defineMacro("__WASM_EXCEPTIONS__");
if (LangOpts.Deprecated)
|
This PR removes the command line parsing workaround introduced in #146342 by moving
LangOptions::ExceptionHandling
toCodeGenOptions
that get parsed even for IR input. Additionally, this improves layering, where the codegen library now checksCodeGenOptions
instead ofLangOptions
for exception handling. (This got enabled by #146422.)