aboutsummaryrefslogtreecommitdiff
path: root/lib/Driver/Tools.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Driver/Tools.cpp')
-rw-r--r--lib/Driver/Tools.cpp95
1 files changed, 74 insertions, 21 deletions
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,