diff options
author | Anders Carlsson <andersca@mac.com> | 2011-02-28 02:27:16 +0000 |
---|---|---|
committer | Anders Carlsson <andersca@mac.com> | 2011-02-28 02:27:16 +0000 |
commit | 15348aeb81285c75b2e92b5bf8d2db3445d147c2 (patch) | |
tree | 4decd60ef2c274e5980a3c659a230c475f42892d /lib | |
parent | 3b368dda700e46ef6002168b92cb5bd18e261a5c (diff) |
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.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@126630 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/CodeGen/CGException.cpp | 4 | ||||
-rw-r--r-- | lib/Driver/Tools.cpp | 95 | ||||
-rw-r--r-- | lib/Sema/SemaExprCXX.cpp | 2 | ||||
-rw-r--r-- | lib/Sema/SemaStmt.cpp | 2 |
4 files changed, 78 insertions, 25 deletions
diff --git a/lib/CodeGen/CGException.cpp b/lib/CodeGen/CGException.cpp index eb907e1fff..0b248bd783 100644 --- a/lib/CodeGen/CGException.cpp +++ b/lib/CodeGen/CGException.cpp @@ -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); diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp index 43ff90da07..475b904b06 100644 --- a/lib/Driver/Tools.cpp +++ b/lib/Driver/Tools.cpp @@ -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; + + // 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, @@ -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, diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index 6dd7aabaa1..bdbb90839a 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -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"; diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp index 89957e60de..a45fa3b7d1 100644 --- a/lib/Sema/SemaStmt.cpp +++ b/lib/Sema/SemaStmt.cpp @@ -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"; |