def fconstant_cfstrings : Flag<"-fconstant-cfstrings">, Group<f_Group>;
def fconstant_string_class_EQ : Joined<"-fconstant-string-class=">, Group<f_Group>;
def fcreate_profile : Flag<"-fcreate-profile">, Group<f_Group>;
+def fcxx_exceptions: Flag<"-fcxx-exceptions">, Group<f_Group>;
def fdebug_pass_arguments : Flag<"-fdebug-pass-arguments">, Group<f_Group>;
def fdebug_pass_structure : Flag<"-fdebug-pass-structure">, Group<f_Group>;
def fdiagnostics_fixit_info : Flag<"-fdiagnostics-fixit-info">, Group<f_Group>;
def fno_color_diagnostics : Flag<"-fno-color-diagnostics">, Group<f_Group>;
def fno_common : Flag<"-fno-common">, Group<f_Group>;
def fno_constant_cfstrings : Flag<"-fno-constant-cfstrings">, Group<f_Group>;
+def fno_cxx_exceptions: Flag<"-fno-cxx-exceptions">, Group<f_Group>;
def fno_diagnostics_fixit_info : Flag<"-fno-diagnostics-fixit-info">, Group<f_Group>;
def fno_diagnostics_show_option : Flag<"-fno-diagnostics-show-option">, Group<f_Group>;
def fno_dollars_in_identifiers : Flag<"-fno-dollars-in-identifiers">, Group<f_Group>;
Triple.getArch() == llvm::Triple::arm));
}
-static bool needsExceptions(const ArgList &Args, types::ID InputType,
- const llvm::Triple &Triple) {
- // Handle -fno-exceptions.
+/// addExceptionArgs - Adds exception related arguments to the driver command
+/// arguments. There's a master flag, -fexceptions and also language specific
+/// flags to enable/disable C++ and Objective-C exceptions.
+/// This makes it possible to for example disable C++ exceptions but enable
+/// Objective-C exceptions.
+static void addExceptionArgs(const ArgList &Args, types::ID InputType,
+ const llvm::Triple &Triple,
+ bool KernelOrKext, bool IsRewriter,
+ ArgStringList &CmdArgs) {
+ if (KernelOrKext)
+ return;
+
+ // Exceptions are enabled by default.
+ bool ExceptionsEnabled = true;
+
+ // This keeps track of whether exceptions were explicitly turned on or off.
+ bool DidHaveExplicitExceptionFlag = false;
+
if (Arg *A = Args.getLastArg(options::OPT_fexceptions,
options::OPT_fno_exceptions)) {
if (A->getOption().matches(options::OPT_fexceptions))
- return true;
- else
- return false;
+ ExceptionsEnabled = true;
+ else
+ ExceptionsEnabled = false;
+
+ DidHaveExplicitExceptionFlag = true;
}
- // Otherwise, C++ inputs use exceptions.
- if (types::isCXX(InputType))
- return true;
+ bool ShouldUseExceptionTables = false;
+
+ // Exception tables and cleanups can be enabled with -fexceptions even if the
+ // language itself doesn't support exceptions.
+ if (ExceptionsEnabled && DidHaveExplicitExceptionFlag)
+ ShouldUseExceptionTables = true;
- if (types::isObjC(InputType))
- return shouldUseExceptionTablesForObjCExceptions(Args, Triple);
+ if (types::isObjC(InputType)) {
+ bool ObjCExceptionsEnabled = ExceptionsEnabled;
+
+ if (Arg *A = Args.getLastArg(options::OPT_fobjc_exceptions,
+ options::OPT_fno_objc_exceptions,
+ options::OPT_fexceptions,
+ options::OPT_fno_exceptions)) {
+ if (A->getOption().matches(options::OPT_fobjc_exceptions))
+ ObjCExceptionsEnabled = true;
+ else if (A->getOption().matches(options::OPT_fno_objc_exceptions))
+ ObjCExceptionsEnabled = false;
+ }
- return false;
+ if (ObjCExceptionsEnabled) {
+ CmdArgs.push_back("-fobjc-exceptions");
+
+ ShouldUseExceptionTables |=
+ shouldUseExceptionTablesForObjCExceptions(Args, Triple);
+ }
+ }
+
+ if (types::isCXX(InputType)) {
+ bool CXXExceptionsEnabled = ExceptionsEnabled;
+
+ if (Arg *A = Args.getLastArg(options::OPT_fcxx_exceptions,
+ options::OPT_fno_cxx_exceptions,
+ options::OPT_fexceptions,
+ options::OPT_fno_exceptions)) {
+ if (A->getOption().matches(options::OPT_fcxx_exceptions))
+ CXXExceptionsEnabled = true;
+ else
+ CXXExceptionsEnabled = false;
+ }
+
+ if (CXXExceptionsEnabled) {
+ CmdArgs.push_back("-fcxx-exceptions");
+
+ ShouldUseExceptionTables = true;
+ }
+ }
+
+ if (ShouldUseExceptionTables)
+ CmdArgs.push_back("-fexceptions");
}
void Clang::ConstructJob(Compilation &C, const JobAction &JA,
false))
CmdArgs.push_back("-fno-elide-constructors");
- // -fexceptions=0 is default.
- if (!KernelOrKext &&
- needsExceptions(Args, InputType, getToolChain().getTriple()))
- CmdArgs.push_back("-fexceptions");
+ // Add exception args.
+ addExceptionArgs(Args, InputType, getToolChain().getTriple(),
+ KernelOrKext, IsRewriter, CmdArgs);
if (getToolChain().UseSjLjExceptions())
CmdArgs.push_back("-fsjlj-exceptions");
getToolChain().IsObjCDefaultSynthPropertiesDefault())) {
CmdArgs.push_back("-fobjc-default-synthesize-properties");
}
-
- // -fno-objc-exceptions is default.
- if (IsRewriter || Args.hasFlag(options::OPT_fobjc_exceptions,
- options::OPT_fno_objc_exceptions))
- CmdArgs.push_back("-fobjc-exceptions");
}
if (!Args.hasFlag(options::OPT_fassume_sane_operator_new,