mirror of
https://github.com/intel/llvm.git
synced 2026-01-24 08:30:34 +08:00
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:
@@ -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>;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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";
|
||||
|
||||
|
||||
@@ -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";
|
||||
|
||||
|
||||
Reference in New Issue
Block a user