diff options
Diffstat (limited to 'lib/Driver/Tools.cpp')
-rw-r--r-- | lib/Driver/Tools.cpp | 95 |
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, |