Skip to content

Commit 76058c0

Browse files
authored
[clang] Move ExceptionHandling from LangOptions to CodeGenOptions (#148982)
This PR removes the command line parsing workaround introduced in #146342 by moving `LangOptions::ExceptionHandling` to `CodeGenOptions` that get parsed even for IR input. Additionally, this improves layering, where the codegen library now checks `CodeGenOptions` instead of `LangOptions` for exception handling. (This got enabled by #146422.)
1 parent 1600450 commit 76058c0

File tree

9 files changed

+63
-99
lines changed

9 files changed

+63
-99
lines changed

clang/include/clang/Basic/CodeGenOptions.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ CODEGENOPT(XCOFFReadOnlyPointers, 1, 0, Benign) ///< Set for -mxcoff-roptr.
5656
CODEGENOPT(AllTocData, 1, 0, Benign) ///< AIX -mtocdata
5757
ENUM_CODEGENOPT(FramePointer, FramePointerKind, 2, FramePointerKind::None, Benign) /// frame-pointer: all,non-leaf,reserved,none
5858

59+
ENUM_CODEGENOPT(ExceptionHandling, ExceptionHandlingKind, 3, ExceptionHandlingKind::None, NotCompatible)
60+
5961
CODEGENOPT(ClearASTBeforeBackend , 1, 0, Benign) ///< Free the AST before running backend code generation. Only works with -disable-free.
6062
CODEGENOPT(DisableFree , 1, 0, Benign) ///< Don't free memory.
6163
CODEGENOPT(DiscardValueNames , 1, 0, Benign) ///< Discard Value Names from the IR (LLVMContext flag)

clang/include/clang/Basic/CodeGenOptions.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,9 @@ class CodeGenOptions : public CodeGenOptionsBase {
176176
llvm_unreachable("invalid FramePointerKind");
177177
}
178178

179+
/// Possible exception handling behavior.
180+
enum class ExceptionHandlingKind { None, SjLj, WinEH, DwarfCFI, Wasm };
181+
179182
enum class SwiftAsyncFramePointerKind {
180183
Auto, // Choose Swift async extended frame info based on deployment target.
181184
Always, // Unconditionally emit Swift async extended frame info.
@@ -552,6 +555,22 @@ class CodeGenOptions : public CodeGenOptionsBase {
552555
return NoBuiltinFuncs;
553556
}
554557

558+
bool hasSjLjExceptions() const {
559+
return getExceptionHandling() == ExceptionHandlingKind::SjLj;
560+
}
561+
562+
bool hasSEHExceptions() const {
563+
return getExceptionHandling() == ExceptionHandlingKind::WinEH;
564+
}
565+
566+
bool hasDWARFExceptions() const {
567+
return getExceptionHandling() == ExceptionHandlingKind::DwarfCFI;
568+
}
569+
570+
bool hasWasmExceptions() const {
571+
return getExceptionHandling() == ExceptionHandlingKind::Wasm;
572+
}
573+
555574
/// Check if Clang profile instrumenation is on.
556575
bool hasProfileClangInstr() const {
557576
return getProfileInstr() ==

clang/include/clang/Basic/LangOptions.def

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,8 +98,6 @@ LANGOPT(Exceptions , 1, 0, NotCompatible, "exception handling")
9898
LANGOPT(ObjCExceptions , 1, 0, NotCompatible, "Objective-C exceptions")
9999
LANGOPT(CXXExceptions , 1, 0, NotCompatible, "C++ exceptions")
100100
LANGOPT(EHAsynch , 1, 0, NotCompatible, "C/C++ EH Asynch exceptions")
101-
ENUM_LANGOPT(ExceptionHandling, ExceptionHandlingKind, 3,
102-
ExceptionHandlingKind::None, NotCompatible, "exception handling")
103101
LANGOPT(IgnoreExceptions , 1, 0, NotCompatible, "ignore exceptions")
104102
LANGOPT(ExternCNoUnwind , 1, 0, NotCompatible, "Assume extern C functions don't unwind")
105103
LANGOPT(AssumeNothrowExceptionDtor , 1, 0, NotCompatible, "Assume exception object's destructor is nothrow")

clang/include/clang/Basic/LangOptions.h

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -337,9 +337,6 @@ class LangOptionsBase {
337337

338338
enum ExcessPrecisionKind { FPP_Standard, FPP_Fast, FPP_None };
339339

340-
/// Possible exception handling behavior.
341-
enum class ExceptionHandlingKind { None, SjLj, WinEH, DwarfCFI, Wasm };
342-
343340
enum class LaxVectorConversionKind {
344341
/// Permit no implicit vector bitcasts.
345342
None,
@@ -788,22 +785,6 @@ class LangOptions : public LangOptionsBase {
788785
return getSignReturnAddressScope() == SignReturnAddressScopeKind::All;
789786
}
790787

791-
bool hasSjLjExceptions() const {
792-
return getExceptionHandling() == ExceptionHandlingKind::SjLj;
793-
}
794-
795-
bool hasSEHExceptions() const {
796-
return getExceptionHandling() == ExceptionHandlingKind::WinEH;
797-
}
798-
799-
bool hasDWARFExceptions() const {
800-
return getExceptionHandling() == ExceptionHandlingKind::DwarfCFI;
801-
}
802-
803-
bool hasWasmExceptions() const {
804-
return getExceptionHandling() == ExceptionHandlingKind::Wasm;
805-
}
806-
807788
bool isSYCL() const { return SYCLIsDevice || SYCLIsHost; }
808789

809790
bool hasDefaultVisibilityExportMapping() const {

clang/include/clang/Driver/Options.td

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2176,10 +2176,10 @@ def fwasm_exceptions : Flag<["-"], "fwasm-exceptions">, Group<f_Group>,
21762176
HelpText<"Use WebAssembly style exceptions">;
21772177
def exception_model : Separate<["-"], "exception-model">,
21782178
Visibility<[CC1Option]>, HelpText<"The exception model">,
2179-
Values<"dwarf,sjlj,seh,wasm">,
2180-
NormalizedValuesScope<"LangOptions::ExceptionHandlingKind">,
2181-
NormalizedValues<["DwarfCFI", "SjLj", "WinEH", "Wasm"]>,
2182-
MarshallingInfoEnum<LangOpts<"ExceptionHandling">, "None">;
2179+
Values<"dwarf,sjlj,seh,wasm,none">,
2180+
NormalizedValuesScope<"CodeGenOptions::ExceptionHandlingKind">,
2181+
NormalizedValues<["DwarfCFI", "SjLj", "WinEH", "Wasm", "None"]>,
2182+
MarshallingInfoEnum<CodeGenOpts<"ExceptionHandling">, "None">;
21832183
def exception_model_EQ : Joined<["-"], "exception-model=">,
21842184
Visibility<[CC1Option]>, Alias<exception_model>;
21852185
def fignore_exceptions : Flag<["-"], "fignore-exceptions">, Group<f_Group>,

clang/lib/CodeGen/BackendUtil.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -407,13 +407,13 @@ static bool initTargetOptions(const CompilerInstance &CI,
407407
// Set EABI version.
408408
Options.EABIVersion = TargetOpts.EABIVersion;
409409

410-
if (LangOpts.hasSjLjExceptions())
410+
if (CodeGenOpts.hasSjLjExceptions())
411411
Options.ExceptionModel = llvm::ExceptionHandling::SjLj;
412-
if (LangOpts.hasSEHExceptions())
412+
if (CodeGenOpts.hasSEHExceptions())
413413
Options.ExceptionModel = llvm::ExceptionHandling::WinEH;
414-
if (LangOpts.hasDWARFExceptions())
414+
if (CodeGenOpts.hasDWARFExceptions())
415415
Options.ExceptionModel = llvm::ExceptionHandling::DwarfCFI;
416-
if (LangOpts.hasWasmExceptions())
416+
if (CodeGenOpts.hasWasmExceptions())
417417
Options.ExceptionModel = llvm::ExceptionHandling::Wasm;
418418

419419
Options.NoInfsFPMath = LangOpts.NoHonorInfs;

clang/lib/CodeGen/CGException.cpp

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -131,28 +131,29 @@ const EHPersonality EHPersonality::ZOS_CPlusPlus = {"__zos_cxx_personality_v2",
131131
nullptr};
132132

133133
static const EHPersonality &getCPersonality(const TargetInfo &Target,
134-
const LangOptions &L) {
134+
const CodeGenOptions &CGOpts) {
135135
const llvm::Triple &T = Target.getTriple();
136136
if (T.isWindowsMSVCEnvironment())
137137
return EHPersonality::MSVC_CxxFrameHandler3;
138-
if (L.hasSjLjExceptions())
138+
if (CGOpts.hasSjLjExceptions())
139139
return EHPersonality::GNU_C_SJLJ;
140-
if (L.hasDWARFExceptions())
140+
if (CGOpts.hasDWARFExceptions())
141141
return EHPersonality::GNU_C;
142-
if (L.hasSEHExceptions())
142+
if (CGOpts.hasSEHExceptions())
143143
return EHPersonality::GNU_C_SEH;
144144
return EHPersonality::GNU_C;
145145
}
146146

147147
static const EHPersonality &getObjCPersonality(const TargetInfo &Target,
148+
const CodeGenOptions &CGOpts,
148149
const LangOptions &L) {
149150
const llvm::Triple &T = Target.getTriple();
150151
if (T.isWindowsMSVCEnvironment())
151152
return EHPersonality::MSVC_CxxFrameHandler3;
152153

153154
switch (L.ObjCRuntime.getKind()) {
154155
case ObjCRuntime::FragileMacOSX:
155-
return getCPersonality(Target, L);
156+
return getCPersonality(Target, CGOpts);
156157
case ObjCRuntime::MacOSX:
157158
case ObjCRuntime::iOS:
158159
case ObjCRuntime::WatchOS:
@@ -165,29 +166,29 @@ static const EHPersonality &getObjCPersonality(const TargetInfo &Target,
165166
[[fallthrough]];
166167
case ObjCRuntime::GCC:
167168
case ObjCRuntime::ObjFW:
168-
if (L.hasSjLjExceptions())
169+
if (CGOpts.hasSjLjExceptions())
169170
return EHPersonality::GNU_ObjC_SJLJ;
170-
if (L.hasSEHExceptions())
171+
if (CGOpts.hasSEHExceptions())
171172
return EHPersonality::GNU_ObjC_SEH;
172173
return EHPersonality::GNU_ObjC;
173174
}
174175
llvm_unreachable("bad runtime kind");
175176
}
176177

177178
static const EHPersonality &getCXXPersonality(const TargetInfo &Target,
178-
const LangOptions &L) {
179+
const CodeGenOptions &CGOpts) {
179180
const llvm::Triple &T = Target.getTriple();
180181
if (T.isWindowsMSVCEnvironment())
181182
return EHPersonality::MSVC_CxxFrameHandler3;
182183
if (T.isOSAIX())
183184
return EHPersonality::XL_CPlusPlus;
184-
if (L.hasSjLjExceptions())
185+
if (CGOpts.hasSjLjExceptions())
185186
return EHPersonality::GNU_CPlusPlus_SJLJ;
186-
if (L.hasDWARFExceptions())
187+
if (CGOpts.hasDWARFExceptions())
187188
return EHPersonality::GNU_CPlusPlus;
188-
if (L.hasSEHExceptions())
189+
if (CGOpts.hasSEHExceptions())
189190
return EHPersonality::GNU_CPlusPlus_SEH;
190-
if (L.hasWasmExceptions())
191+
if (CGOpts.hasWasmExceptions())
191192
return EHPersonality::GNU_Wasm_CPlusPlus;
192193
if (T.isOSzOS())
193194
return EHPersonality::ZOS_CPlusPlus;
@@ -197,6 +198,7 @@ static const EHPersonality &getCXXPersonality(const TargetInfo &Target,
197198
/// Determines the personality function to use when both C++
198199
/// and Objective-C exceptions are being caught.
199200
static const EHPersonality &getObjCXXPersonality(const TargetInfo &Target,
201+
const CodeGenOptions &CGOpts,
200202
const LangOptions &L) {
201203
if (Target.getTriple().isWindowsMSVCEnvironment())
202204
return EHPersonality::MSVC_CxxFrameHandler3;
@@ -205,15 +207,15 @@ static const EHPersonality &getObjCXXPersonality(const TargetInfo &Target,
205207
// In the fragile ABI, just use C++ exception handling and hope
206208
// they're not doing crazy exception mixing.
207209
case ObjCRuntime::FragileMacOSX:
208-
return getCXXPersonality(Target, L);
210+
return getCXXPersonality(Target, CGOpts);
209211

210212
// The ObjC personality defers to the C++ personality for non-ObjC
211213
// handlers. Unlike the C++ case, we use the same personality
212214
// function on targets using (backend-driven) SJLJ EH.
213215
case ObjCRuntime::MacOSX:
214216
case ObjCRuntime::iOS:
215217
case ObjCRuntime::WatchOS:
216-
return getObjCPersonality(Target, L);
218+
return getObjCPersonality(Target, CGOpts, L);
217219

218220
case ObjCRuntime::GNUstep:
219221
return Target.getTriple().isOSCygMing() ? EHPersonality::GNU_CPlusPlus_SEH
@@ -223,7 +225,7 @@ static const EHPersonality &getObjCXXPersonality(const TargetInfo &Target,
223225
// mixed EH. Use the ObjC personality just to avoid returning null.
224226
case ObjCRuntime::GCC:
225227
case ObjCRuntime::ObjFW:
226-
return getObjCPersonality(Target, L);
228+
return getObjCPersonality(Target, CGOpts, L);
227229
}
228230
llvm_unreachable("bad runtime kind");
229231
}
@@ -237,6 +239,7 @@ static const EHPersonality &getSEHPersonalityMSVC(const llvm::Triple &T) {
237239
const EHPersonality &EHPersonality::get(CodeGenModule &CGM,
238240
const FunctionDecl *FD) {
239241
const llvm::Triple &T = CGM.getTarget().getTriple();
242+
const CodeGenOptions &CGOpts = CGM.getCodeGenOpts();
240243
const LangOptions &L = CGM.getLangOpts();
241244
const TargetInfo &Target = CGM.getTarget();
242245

@@ -245,10 +248,10 @@ const EHPersonality &EHPersonality::get(CodeGenModule &CGM,
245248
return getSEHPersonalityMSVC(T);
246249

247250
if (L.ObjC)
248-
return L.CPlusPlus ? getObjCXXPersonality(Target, L)
249-
: getObjCPersonality(Target, L);
250-
return L.CPlusPlus ? getCXXPersonality(Target, L)
251-
: getCPersonality(Target, L);
251+
return L.CPlusPlus ? getObjCXXPersonality(Target, CGOpts, L)
252+
: getObjCPersonality(Target, CGOpts, L);
253+
return L.CPlusPlus ? getCXXPersonality(Target, CGOpts)
254+
: getCPersonality(Target, CGOpts);
252255
}
253256

254257
const EHPersonality &EHPersonality::get(CodeGenFunction &CGF) {
@@ -344,7 +347,7 @@ void CodeGenModule::SimplifyPersonality() {
344347
return;
345348

346349
const EHPersonality &ObjCXX = EHPersonality::get(*this, /*FD=*/nullptr);
347-
const EHPersonality &CXX = getCXXPersonality(getTarget(), LangOpts);
350+
const EHPersonality &CXX = getCXXPersonality(getTarget(), CodeGenOpts);
348351
if (&ObjCXX == &CXX)
349352
return;
350353

@@ -500,7 +503,7 @@ void CodeGenFunction::EmitStartEHSpec(const Decl *D) {
500503
// In Wasm EH we currently treat 'throw()' in the same way as 'noexcept'. In
501504
// case of throw with types, we ignore it and print a warning for now.
502505
// TODO Correctly handle exception specification in Wasm EH
503-
if (CGM.getLangOpts().hasWasmExceptions()) {
506+
if (CGM.getCodeGenOpts().hasWasmExceptions()) {
504507
if (EST == EST_DynamicNone)
505508
EHStack.pushTerminate();
506509
else
@@ -515,8 +518,8 @@ void CodeGenFunction::EmitStartEHSpec(const Decl *D) {
515518
// throw with types.
516519
// TODO Correctly handle exception specification in Emscripten EH
517520
if (getTarget().getCXXABI() == TargetCXXABI::WebAssembly &&
518-
CGM.getLangOpts().getExceptionHandling() ==
519-
LangOptions::ExceptionHandlingKind::None &&
521+
CGM.getCodeGenOpts().getExceptionHandling() ==
522+
CodeGenOptions::ExceptionHandlingKind::None &&
520523
EST == EST_Dynamic)
521524
CGM.getDiags().Report(D->getLocation(),
522525
diag::warn_wasm_dynamic_exception_spec_ignored)
@@ -604,7 +607,7 @@ void CodeGenFunction::EmitEndEHSpec(const Decl *D) {
604607
// In wasm we currently treat 'throw()' in the same way as 'noexcept'. In
605608
// case of throw with types, we ignore it and print a warning for now.
606609
// TODO Correctly handle exception specification in wasm
607-
if (CGM.getLangOpts().hasWasmExceptions()) {
610+
if (CGM.getCodeGenOpts().hasWasmExceptions()) {
608611
if (EST == EST_DynamicNone)
609612
EHStack.popTerminate();
610613
return;

clang/lib/Frontend/CompilerInvocation.cpp

Lines changed: 3 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -593,11 +593,11 @@ static bool FixupInvocation(CompilerInvocation &Invocation,
593593
CodeGenOpts.CodeModel = TargetOpts.CodeModel;
594594
CodeGenOpts.LargeDataThreshold = TargetOpts.LargeDataThreshold;
595595

596-
if (LangOpts.getExceptionHandling() !=
597-
LangOptions::ExceptionHandlingKind::None &&
596+
if (CodeGenOpts.getExceptionHandling() !=
597+
CodeGenOptions::ExceptionHandlingKind::None &&
598598
T.isWindowsMSVCEnvironment())
599599
Diags.Report(diag::err_fe_invalid_exception_model)
600-
<< static_cast<unsigned>(LangOpts.getExceptionHandling()) << T.str();
600+
<< static_cast<unsigned>(CodeGenOpts.getExceptionHandling()) << T.str();
601601

602602
if (LangOpts.AppleKext && !LangOpts.CPlusPlus)
603603
Diags.Report(diag::warn_c_kext);
@@ -3713,23 +3713,6 @@ static StringRef GetInputKindName(InputKind IK) {
37133713
llvm_unreachable("unknown input language");
37143714
}
37153715

3716-
static StringRef getExceptionHandlingName(unsigned EHK) {
3717-
switch (static_cast<LangOptions::ExceptionHandlingKind>(EHK)) {
3718-
case LangOptions::ExceptionHandlingKind::None:
3719-
return "none";
3720-
case LangOptions::ExceptionHandlingKind::DwarfCFI:
3721-
return "dwarf";
3722-
case LangOptions::ExceptionHandlingKind::SjLj:
3723-
return "sjlj";
3724-
case LangOptions::ExceptionHandlingKind::WinEH:
3725-
return "seh";
3726-
case LangOptions::ExceptionHandlingKind::Wasm:
3727-
return "wasm";
3728-
}
3729-
3730-
llvm_unreachable("covered switch");
3731-
}
3732-
37333716
void CompilerInvocationBase::GenerateLangArgs(const LangOptions &Opts,
37343717
ArgumentConsumer Consumer,
37353718
const llvm::Triple &T,
@@ -3745,10 +3728,6 @@ void CompilerInvocationBase::GenerateLangArgs(const LangOptions &Opts,
37453728
GenerateArg(Consumer, OPT_pic_is_pie);
37463729
for (StringRef Sanitizer : serializeSanitizerKinds(Opts.Sanitize))
37473730
GenerateArg(Consumer, OPT_fsanitize_EQ, Sanitizer);
3748-
if (Opts.ExceptionHandling) {
3749-
GenerateArg(Consumer, OPT_exception_model,
3750-
getExceptionHandlingName(Opts.ExceptionHandling));
3751-
}
37523731

37533732
return;
37543733
}
@@ -4057,24 +4036,6 @@ bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args,
40574036
parseSanitizerKinds("-fsanitize=", Args.getAllArgValues(OPT_fsanitize_EQ),
40584037
Diags, Opts.Sanitize);
40594038

4060-
if (const Arg *A = Args.getLastArg(options::OPT_exception_model)) {
4061-
std::optional<LangOptions::ExceptionHandlingKind> EMValue =
4062-
llvm::StringSwitch<std::optional<LangOptions::ExceptionHandlingKind>>(
4063-
A->getValue())
4064-
.Case("dwarf", LangOptions::ExceptionHandlingKind::DwarfCFI)
4065-
.Case("sjlj", LangOptions::ExceptionHandlingKind::SjLj)
4066-
.Case("seh", LangOptions::ExceptionHandlingKind::WinEH)
4067-
.Case("wasm", LangOptions::ExceptionHandlingKind::Wasm)
4068-
.Case("none", LangOptions::ExceptionHandlingKind::None)
4069-
.Default(std::nullopt);
4070-
if (EMValue) {
4071-
Opts.ExceptionHandling = static_cast<unsigned>(*EMValue);
4072-
} else {
4073-
Diags.Report(diag::err_drv_invalid_value)
4074-
<< A->getAsString(Args) << A->getValue();
4075-
}
4076-
}
4077-
40784039
return Diags.getNumErrors() == NumErrorsBefore;
40794040
}
40804041

clang/lib/Frontend/InitPreprocessor.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1032,14 +1032,14 @@ static void InitializePredefinedMacros(const TargetInfo &TI,
10321032
if (LangOpts.GNUCVersion && LangOpts.RTTI)
10331033
Builder.defineMacro("__GXX_RTTI");
10341034

1035-
if (LangOpts.hasSjLjExceptions())
1035+
if (CGOpts.hasSjLjExceptions())
10361036
Builder.defineMacro("__USING_SJLJ_EXCEPTIONS__");
1037-
else if (LangOpts.hasSEHExceptions())
1037+
else if (CGOpts.hasSEHExceptions())
10381038
Builder.defineMacro("__SEH__");
1039-
else if (LangOpts.hasDWARFExceptions() &&
1039+
else if (CGOpts.hasDWARFExceptions() &&
10401040
(TI.getTriple().isThumb() || TI.getTriple().isARM()))
10411041
Builder.defineMacro("__ARM_DWARF_EH__");
1042-
else if (LangOpts.hasWasmExceptions() && TI.getTriple().isWasm())
1042+
else if (CGOpts.hasWasmExceptions() && TI.getTriple().isWasm())
10431043
Builder.defineMacro("__WASM_EXCEPTIONS__");
10441044

10451045
if (LangOpts.Deprecated)

0 commit comments

Comments
 (0)