Add a -fcxx-exceptions flag to the frontend, which can be used to enable

C++ exceptions, even when exceptions have been turned off using -fno-exceptions.
Make the -fobjc-exceptions flag do the same thing, but for Objective-C exceptions.

C++ and Objective-C exceptions can also be disabled using -fno-cxx-excptions and
-fno-objc-exceptions.

llvm-svn: 126630
This commit is contained in:
Anders Carlsson
2011-02-28 02:27:16 +00:00
parent 64965ad75d
commit e96ab55b28
5 changed files with 80 additions and 25 deletions

View File

@@ -264,6 +264,7 @@ def fcompile_resource_EQ : Joined<"-fcompile-resource=">, Group<f_Group>;
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>;
@@ -325,6 +326,7 @@ def fno_caret_diagnostics : Flag<"-fno-caret-diagnostics">, 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>;

View File

@@ -439,7 +439,7 @@ void CodeGenFunction::EmitCXXThrowExpr(const CXXThrowExpr *E) {
}
void CodeGenFunction::EmitStartEHSpec(const Decl *D) {
if (!CGM.getLangOptions().Exceptions)
if (!CGM.getLangOptions().CXXExceptions)
return;
const FunctionDecl* FD = dyn_cast_or_null<FunctionDecl>(D);
@@ -467,7 +467,7 @@ void CodeGenFunction::EmitStartEHSpec(const Decl *D) {
}
void CodeGenFunction::EmitEndEHSpec(const Decl *D) {
if (!CGM.getLangOptions().Exceptions)
if (!CGM.getLangOptions().CXXExceptions)
return;
const FunctionDecl* FD = dyn_cast_or_null<FunctionDecl>(D);

View File

@@ -780,25 +780,84 @@ shouldUseExceptionTablesForObjCExceptions(const ArgList &Args,
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;
if (types::isObjC(InputType))
return shouldUseExceptionTablesForObjCExceptions(Args, Triple);
// Exception tables and cleanups can be enabled with -fexceptions even if the
// language itself doesn't support exceptions.
if (ExceptionsEnabled && DidHaveExplicitExceptionFlag)
ShouldUseExceptionTables = true;
return false;
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;
}
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,
@@ -1416,10 +1475,9 @@ 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");
@@ -1556,11 +1614,6 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
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,

View File

@@ -477,7 +477,7 @@ Sema::ActOnCXXNullPtrLiteral(SourceLocation Loc) {
ExprResult
Sema::ActOnCXXThrow(SourceLocation OpLoc, Expr *Ex) {
// Don't report an error if 'throw' is used in system headers.
if (!getLangOptions().Exceptions &&
if (!getLangOptions().CXXExceptions &&
!getSourceManager().isInSystemHeader(OpLoc))
Diag(OpLoc, diag::err_exceptions_disabled) << "throw";

View File

@@ -1766,7 +1766,7 @@ StmtResult
Sema::ActOnCXXTryBlock(SourceLocation TryLoc, Stmt *TryBlock,
MultiStmtArg RawHandlers) {
// Don't report an error if 'try' is used in system headers.
if (!getLangOptions().Exceptions &&
if (!getLangOptions().CXXExceptions &&
!getSourceManager().isInSystemHeader(TryLoc))
Diag(TryLoc, diag::err_exceptions_disabled) << "try";