]> granicus.if.org Git - clang/commitdiff
Add a -fcxx-exceptions flag to the frontend, which can be used to enable
authorAnders Carlsson <andersca@mac.com>
Mon, 28 Feb 2011 02:27:16 +0000 (02:27 +0000)
committerAnders Carlsson <andersca@mac.com>
Mon, 28 Feb 2011 02:27:16 +0000 (02:27 +0000)
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

include/clang/Driver/Options.td
lib/CodeGen/CGException.cpp
lib/Driver/Tools.cpp
lib/Sema/SemaExprCXX.cpp
lib/Sema/SemaStmt.cpp

index 288c10f5235401aaf8d17e51759761a8f815ddf4..1b9d279f577b84719d70048362511a78cd0a363f 100644 (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>;
index eb907e1fff21831afc6e5b2a4f77dbf15bb4fd3a..0b248bd783b98094ac4a1c07a71ab0f041fa7b5b 100644 (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);
index 43ff90da07ee53385c2bd2fdfa23696f41ebe57b..475b904b063429720a8726f3082d160192c081b5 100644 (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;
+
+  // 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,
index 6dd7aabaa1f01a06eeafb4f9d456bebc6b9465aa..bdbb90839af568f6aac5bcdb8470023f83a39528 100644 (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";
 
index 89957e60decaf4fd741c21525bc88294c84829bd..a45fa3b7d1c40bb371a6a890f5976086071231c0 100644 (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";