summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/docs/ClangCommandLineReference.rst8
-rw-r--r--clang/include/clang/Basic/LangOptions.def2
-rw-r--r--clang/include/clang/Driver/Options.td4
-rw-r--r--clang/include/clang/Driver/ToolChain.h7
-rw-r--r--clang/lib/Basic/Targets/ARM.cpp1
-rw-r--r--clang/lib/Basic/Targets/OSTargets.cpp4
-rw-r--r--clang/lib/Basic/Targets/OSTargets.h11
-rw-r--r--clang/lib/Basic/Targets/X86.h13
-rw-r--r--clang/lib/CodeGen/BackendUtil.cpp4
-rw-r--r--clang/lib/CodeGen/CGException.cpp16
-rw-r--r--clang/lib/Driver/ToolChain.cpp9
-rw-r--r--clang/lib/Driver/ToolChains/Clang.cpp30
-rw-r--r--clang/lib/Driver/ToolChains/Darwin.cpp11
-rw-r--r--clang/lib/Driver/ToolChains/Darwin.h8
-rw-r--r--clang/lib/Driver/ToolChains/FreeBSD.cpp12
-rw-r--r--clang/lib/Driver/ToolChains/FreeBSD.h3
-rw-r--r--clang/lib/Driver/ToolChains/MinGW.cpp7
-rw-r--r--clang/lib/Driver/ToolChains/MinGW.h4
-rw-r--r--clang/lib/Driver/ToolChains/NetBSD.cpp8
-rw-r--r--clang/lib/Driver/ToolChains/NetBSD.h3
-rw-r--r--clang/lib/Frontend/CompilerInvocation.cpp13
-rw-r--r--clang/lib/Frontend/InitPreprocessor.cpp6
-rw-r--r--clang/test/CodeGenCXX/mingw-w64-exceptions.c22
-rw-r--r--clang/test/CodeGenCXX/mingw-w64-seh-exceptions.cpp3
-rw-r--r--clang/test/Preprocessor/arm-target-features.c2
-rw-r--r--clang/test/Preprocessor/init.c1
26 files changed, 148 insertions, 64 deletions
diff --git a/clang/docs/ClangCommandLineReference.rst b/clang/docs/ClangCommandLineReference.rst
index 7596afadc88..434297b2c8e 100644
--- a/clang/docs/ClangCommandLineReference.rst
+++ b/clang/docs/ClangCommandLineReference.rst
@@ -1706,10 +1706,18 @@ Which overload candidates to show when overload resolution fails: best\|all; def
Enable C++14 sized global deallocation functions
+.. option:: -fdwarf-exceptions
+
+Use DWARF style exceptions
+
.. option:: -fsjlj-exceptions
Use SjLj style exceptions
+.. option:: -fseh-exceptions
+
+Use SEH style exceptions
+
.. option:: -fslp-vectorize, -fno-slp-vectorize, -ftree-slp-vectorize
Enable the superword-level parallelism vectorization passes
diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def
index 78a743750e7..5388c695fd1 100644
--- a/clang/include/clang/Basic/LangOptions.def
+++ b/clang/include/clang/Basic/LangOptions.def
@@ -124,7 +124,9 @@ LANGOPT(ZVector , 1, 0, "System z vector extensions")
LANGOPT(Exceptions , 1, 0, "exception handling")
LANGOPT(ObjCExceptions , 1, 0, "Objective-C exceptions")
LANGOPT(CXXExceptions , 1, 0, "C++ exceptions")
+LANGOPT(DWARFExceptions , 1, 0, "dwarf exception handling")
LANGOPT(SjLjExceptions , 1, 0, "setjmp-longjump exception handling")
+LANGOPT(SEHExceptions , 1, 0, "SEH .xdata exception handling")
LANGOPT(ExternCNoUnwind , 1, 0, "Assume extern C functions don't unwind")
LANGOPT(TraditionalCPP , 1, 0, "traditional CPP emulation")
LANGOPT(RTTI , 1, 1, "run-time type information")
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 9f8684ddee8..7082fd26774 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -800,8 +800,12 @@ def fencoding_EQ : Joined<["-"], "fencoding=">, Group<f_Group>;
def ferror_limit_EQ : Joined<["-"], "ferror-limit=">, Group<f_Group>, Flags<[CoreOption]>;
def fexceptions : Flag<["-"], "fexceptions">, Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Enable support for exception handling">;
+def fdwarf_exceptions : Flag<["-"], "fdwarf-exceptions">, Group<f_Group>,
+ Flags<[CC1Option]>, HelpText<"Use DWARF style exceptions">;
def fsjlj_exceptions : Flag<["-"], "fsjlj-exceptions">, Group<f_Group>,
Flags<[CC1Option]>, HelpText<"Use SjLj style exceptions">;
+def fseh_exceptions : Flag<["-"], "fseh-exceptions">, Group<f_Group>,
+ Flags<[CC1Option]>, HelpText<"Use SEH style exceptions">;
def fexcess_precision_EQ : Joined<["-"], "fexcess-precision=">,
Group<clang_ignored_gcc_optimization_f_Group>;
def : Flag<["-"], "fexpensive-optimizations">, Group<clang_ignored_gcc_optimization_f_Group>;
diff --git a/clang/include/clang/Driver/ToolChain.h b/clang/include/clang/Driver/ToolChain.h
index bd710387980..95f1461c495 100644
--- a/clang/include/clang/Driver/ToolChain.h
+++ b/clang/include/clang/Driver/ToolChain.h
@@ -397,10 +397,9 @@ public:
return llvm::DebuggerKind::GDB;
}
- /// UseSjLjExceptions - Does this tool chain use SjLj exceptions.
- virtual bool UseSjLjExceptions(const llvm::opt::ArgList &Args) const {
- return false;
- }
+ /// GetExceptionModel - Return the tool chain exception model.
+ virtual llvm::ExceptionHandling
+ GetExceptionModel(const llvm::opt::ArgList &Args) const;
/// SupportsEmbeddedBitcode - Does this tool chain support embedded bitcode.
virtual bool SupportsEmbeddedBitcode() const {
diff --git a/clang/lib/Basic/Targets/ARM.cpp b/clang/lib/Basic/Targets/ARM.cpp
index 77b3f9a5373..fe261b77485 100644
--- a/clang/lib/Basic/Targets/ARM.cpp
+++ b/clang/lib/Basic/Targets/ARM.cpp
@@ -1000,7 +1000,6 @@ void MinGWARMTargetInfo::getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const {
WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
Builder.defineMacro("_ARM_");
- Builder.defineMacro("__ARM_DWARF_EH__");
}
CygwinARMTargetInfo::CygwinARMTargetInfo(const llvm::Triple &Triple,
diff --git a/clang/lib/Basic/Targets/OSTargets.cpp b/clang/lib/Basic/Targets/OSTargets.cpp
index b01e682e64d..50abd4ce0c8 100644
--- a/clang/lib/Basic/Targets/OSTargets.cpp
+++ b/clang/lib/Basic/Targets/OSTargets.cpp
@@ -133,10 +133,6 @@ void getDarwinDefines(MacroBuilder &Builder, const LangOptions &Opts,
if (Triple.isOSDarwin())
Builder.defineMacro("__MACH__");
- // The Watch ABI uses Dwarf EH.
- if (Triple.isWatchABI())
- Builder.defineMacro("__ARM_DWARF_EH__");
-
PlatformMinVersion = VersionTuple(Maj, Min, Rev);
}
} // namespace targets
diff --git a/clang/lib/Basic/Targets/OSTargets.h b/clang/lib/Basic/Targets/OSTargets.h
index cf2905fbb02..d6c64b90a84 100644
--- a/clang/lib/Basic/Targets/OSTargets.h
+++ b/clang/lib/Basic/Targets/OSTargets.h
@@ -358,17 +358,6 @@ protected:
Builder.defineMacro("__ELF__");
if (Opts.POSIXThreads)
Builder.defineMacro("_REENTRANT");
-
- switch (Triple.getArch()) {
- default:
- break;
- case llvm::Triple::arm:
- case llvm::Triple::armeb:
- case llvm::Triple::thumb:
- case llvm::Triple::thumbeb:
- Builder.defineMacro("__ARM_DWARF_EH__");
- break;
- }
}
public:
diff --git a/clang/lib/Basic/Targets/X86.h b/clang/lib/Basic/Targets/X86.h
index 8f4f5dab6af..5a4b6b53b31 100644
--- a/clang/lib/Basic/Targets/X86.h
+++ b/clang/lib/Basic/Targets/X86.h
@@ -710,15 +710,6 @@ public:
LongDoubleFormat = &llvm::APFloat::x87DoubleExtended();
HasFloat128 = true;
}
-
- void getTargetDefines(const LangOptions &Opts,
- MacroBuilder &Builder) const override {
- WindowsX86_64TargetInfo::getTargetDefines(Opts, Builder);
-
- // GCC defines this macro when it is using __gxx_personality_seh0.
- if (!Opts.SjLjExceptions)
- Builder.defineMacro("__SEH__");
- }
};
// x86-64 Cygwin target
@@ -740,10 +731,6 @@ public:
DefineStd(Builder, "unix", Opts);
if (Opts.CPlusPlus)
Builder.defineMacro("_GNU_SOURCE");
-
- // GCC defines this macro when it is using __gxx_personality_seh0.
- if (!Opts.SjLjExceptions)
- Builder.defineMacro("__SEH__");
}
};
diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp
index 5a13f511afc..235ab2db52d 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -424,6 +424,10 @@ static void initTargetOptions(llvm::TargetOptions &Options,
if (LangOpts.SjLjExceptions)
Options.ExceptionModel = llvm::ExceptionHandling::SjLj;
+ if (LangOpts.SEHExceptions)
+ Options.ExceptionModel = llvm::ExceptionHandling::WinEH;
+ if (LangOpts.DWARFExceptions)
+ Options.ExceptionModel = llvm::ExceptionHandling::DwarfCFI;
Options.NoInfsFPMath = CodeGenOpts.NoInfsFPMath;
Options.NoNaNsFPMath = CodeGenOpts.NoNaNsFPMath;
diff --git a/clang/lib/CodeGen/CGException.cpp b/clang/lib/CodeGen/CGException.cpp
index 6a421e81dff..d6a9538bc1f 100644
--- a/clang/lib/CodeGen/CGException.cpp
+++ b/clang/lib/CodeGen/CGException.cpp
@@ -112,17 +112,11 @@ EHPersonality::MSVC_C_specific_handler = { "__C_specific_handler", nullptr };
const EHPersonality
EHPersonality::MSVC_CxxFrameHandler3 = { "__CxxFrameHandler3", nullptr };
-/// On Win64, use libgcc's SEH personality function. We fall back to dwarf on
-/// other platforms, unless the user asked for SjLj exceptions.
-static bool useLibGCCSEHPersonality(const llvm::Triple &T) {
- return T.isOSWindows() && T.getArch() == llvm::Triple::x86_64;
-}
-
static const EHPersonality &getCPersonality(const llvm::Triple &T,
const LangOptions &L) {
if (L.SjLjExceptions)
return EHPersonality::GNU_C_SJLJ;
- else if (useLibGCCSEHPersonality(T))
+ if (L.SEHExceptions)
return EHPersonality::GNU_C_SEH;
return EHPersonality::GNU_C;
}
@@ -144,7 +138,7 @@ static const EHPersonality &getObjCPersonality(const llvm::Triple &T,
case ObjCRuntime::ObjFW:
if (L.SjLjExceptions)
return EHPersonality::GNU_ObjC_SJLJ;
- else if (useLibGCCSEHPersonality(T))
+ if (L.SEHExceptions)
return EHPersonality::GNU_ObjC_SEH;
return EHPersonality::GNU_ObjC;
}
@@ -155,7 +149,7 @@ static const EHPersonality &getCXXPersonality(const llvm::Triple &T,
const LangOptions &L) {
if (L.SjLjExceptions)
return EHPersonality::GNU_CPlusPlus_SJLJ;
- else if (useLibGCCSEHPersonality(T))
+ if (L.SEHExceptions)
return EHPersonality::GNU_CPlusPlus_SEH;
return EHPersonality::GNU_CPlusPlus;
}
@@ -211,6 +205,10 @@ const EHPersonality &EHPersonality::get(CodeGenModule &CGM,
if (T.isWindowsMSVCEnvironment() && !L.ObjC1) {
if (L.SjLjExceptions)
return EHPersonality::GNU_CPlusPlus_SJLJ;
+ if (L.SEHExceptions)
+ return EHPersonality::GNU_CPlusPlus_SEH;
+ if (L.DWARFExceptions)
+ return EHPersonality::GNU_CPlusPlus;
else
return EHPersonality::MSVC_CxxFrameHandler3;
}
diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp
index 741f4284cbb..256fbf5ef2a 100644
--- a/clang/lib/Driver/ToolChain.cpp
+++ b/clang/lib/Driver/ToolChain.cpp
@@ -27,6 +27,8 @@
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
+#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/Support/TargetParser.h"
#include "llvm/Support/TargetRegistry.h"
@@ -449,6 +451,13 @@ ObjCRuntime ToolChain::getDefaultObjCRuntime(bool isNonFragile) const {
VersionTuple());
}
+llvm::ExceptionHandling
+ToolChain::GetExceptionModel(const llvm::opt::ArgList &Args) const {
+ if (Triple.isOSWindows())
+ return llvm::ExceptionHandling::WinEH;
+ return llvm::ExceptionHandling::None;
+}
+
bool ToolChain::isThreadModelSupported(const StringRef Model) const {
if (Model == "single") {
// FIXME: 'single' is only supported on ARM and WebAssembly so far.
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index d96664cf0be..1c90c6e9225 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -4166,9 +4166,33 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
addExceptionArgs(Args, InputType, getToolChain(), KernelOrKext, Runtime,
CmdArgs);
- if (Args.hasArg(options::OPT_fsjlj_exceptions) ||
- getToolChain().UseSjLjExceptions(Args))
- CmdArgs.push_back("-fsjlj-exceptions");
+ // Handle exception personalities
+ Arg *A = Args.getLastArg(options::OPT_fsjlj_exceptions,
+ options::OPT_fseh_exceptions,
+ options::OPT_fdwarf_exceptions);
+ if (A) {
+ const Option &Opt = A->getOption();
+ if (Opt.matches(options::OPT_fsjlj_exceptions))
+ CmdArgs.push_back("-fsjlj-exceptions");
+ if (Opt.matches(options::OPT_fseh_exceptions))
+ CmdArgs.push_back("-fseh-exceptions");
+ if (Opt.matches(options::OPT_fdwarf_exceptions))
+ CmdArgs.push_back("-fdwarf-exceptions");
+ } else {
+ switch(getToolChain().GetExceptionModel(Args)) {
+ default:
+ break;
+ case llvm::ExceptionHandling::DwarfCFI:
+ CmdArgs.push_back("-fdwarf-exceptions");
+ break;
+ case llvm::ExceptionHandling::SjLj:
+ CmdArgs.push_back("-fsjlj-exceptions");
+ break;
+ case llvm::ExceptionHandling::WinEH:
+ CmdArgs.push_back("-fseh-exceptions");
+ break;
+ }
+ }
// C++ "sane" operator new.
if (!Args.hasFlag(options::OPT_fassume_sane_operator_new,
diff --git a/clang/lib/Driver/ToolChains/Darwin.cpp b/clang/lib/Driver/ToolChains/Darwin.cpp
index 5dc8a91bcf1..7c401aa9dd5 100644
--- a/clang/lib/Driver/ToolChains/Darwin.cpp
+++ b/clang/lib/Driver/ToolChains/Darwin.cpp
@@ -1881,7 +1881,7 @@ bool MachO::IsUnwindTablesDefault(const ArgList &Args) const {
// Unwind tables are not emitted if -fno-exceptions is supplied (except when
// targeting x86_64).
return getArch() == llvm::Triple::x86_64 ||
- (!UseSjLjExceptions(Args) &&
+ (GetExceptionModel(Args) != llvm::ExceptionHandling::SjLj &&
Args.hasFlag(options::OPT_fexceptions, options::OPT_fno_exceptions,
true));
}
@@ -1892,15 +1892,18 @@ bool MachO::UseDwarfDebugFlags() const {
return false;
}
-bool Darwin::UseSjLjExceptions(const ArgList &Args) const {
+llvm::ExceptionHandling Darwin::GetExceptionModel(const ArgList &Args) const {
// Darwin uses SjLj exceptions on ARM.
if (getTriple().getArch() != llvm::Triple::arm &&
getTriple().getArch() != llvm::Triple::thumb)
- return false;
+ return llvm::ExceptionHandling::None;
// Only watchOS uses the new DWARF/Compact unwinding method.
llvm::Triple Triple(ComputeLLVMTriple(Args));
- return !Triple.isWatchABI();
+ if(Triple.isWatchABI())
+ return llvm::ExceptionHandling::DwarfCFI;
+
+ return llvm::ExceptionHandling::SjLj;
}
bool Darwin::SupportsEmbeddedBitcode() const {
diff --git a/clang/lib/Driver/ToolChains/Darwin.h b/clang/lib/Driver/ToolChains/Darwin.h
index 2b8477aa275..c861f172fe1 100644
--- a/clang/lib/Driver/ToolChains/Darwin.h
+++ b/clang/lib/Driver/ToolChains/Darwin.h
@@ -247,8 +247,9 @@ public:
bool UseDwarfDebugFlags() const override;
- bool UseSjLjExceptions(const llvm::opt::ArgList &Args) const override {
- return false;
+ llvm::ExceptionHandling
+ GetExceptionModel(const llvm::opt::ArgList &Args) const override {
+ return llvm::ExceptionHandling::None;
}
/// }
@@ -455,7 +456,8 @@ public:
void CheckObjCARC() const override;
- bool UseSjLjExceptions(const llvm::opt::ArgList &Args) const override;
+ llvm::ExceptionHandling GetExceptionModel(
+ const llvm::opt::ArgList &Args) const override;
bool SupportsEmbeddedBitcode() const override;
diff --git a/clang/lib/Driver/ToolChains/FreeBSD.cpp b/clang/lib/Driver/ToolChains/FreeBSD.cpp
index 2f066cf0cc8..025acf15117 100644
--- a/clang/lib/Driver/ToolChains/FreeBSD.cpp
+++ b/clang/lib/Driver/ToolChains/FreeBSD.cpp
@@ -359,17 +359,17 @@ Tool *FreeBSD::buildAssembler() const {
Tool *FreeBSD::buildLinker() const { return new tools::freebsd::Linker(*this); }
-bool FreeBSD::UseSjLjExceptions(const ArgList &Args) const {
+llvm::ExceptionHandling FreeBSD::GetExceptionModel(const ArgList &Args) const {
// FreeBSD uses SjLj exceptions on ARM oabi.
switch (getTriple().getEnvironment()) {
+ default:
+ if (getTriple().getArch() == llvm::Triple::arm ||
+ getTriple().getArch() == llvm::Triple::thumb)
+ return llvm::ExceptionHandling::SjLj;
case llvm::Triple::GNUEABIHF:
case llvm::Triple::GNUEABI:
case llvm::Triple::EABI:
- return false;
-
- default:
- return (getTriple().getArch() == llvm::Triple::arm ||
- getTriple().getArch() == llvm::Triple::thumb);
+ return llvm::ExceptionHandling::None;
}
}
diff --git a/clang/lib/Driver/ToolChains/FreeBSD.h b/clang/lib/Driver/ToolChains/FreeBSD.h
index 25e9df72bc8..2943e1cacfb 100644
--- a/clang/lib/Driver/ToolChains/FreeBSD.h
+++ b/clang/lib/Driver/ToolChains/FreeBSD.h
@@ -66,7 +66,8 @@ public:
void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args,
llvm::opt::ArgStringList &CmdArgs) const override;
- bool UseSjLjExceptions(const llvm::opt::ArgList &Args) const override;
+ llvm::ExceptionHandling GetExceptionModel(
+ const llvm::opt::ArgList &Args) const override;
bool isPIEDefault() const override;
SanitizerMask getSupportedSanitizers() const override;
unsigned GetDefaultDwarfVersion() const override { return 2; }
diff --git a/clang/lib/Driver/ToolChains/MinGW.cpp b/clang/lib/Driver/ToolChains/MinGW.cpp
index 79864eab83e..572ea803f2d 100644
--- a/clang/lib/Driver/ToolChains/MinGW.cpp
+++ b/clang/lib/Driver/ToolChains/MinGW.cpp
@@ -367,8 +367,11 @@ bool toolchains::MinGW::isPICDefaultForced() const {
return getArch() == llvm::Triple::x86_64;
}
-bool toolchains::MinGW::UseSEHExceptions() const {
- return getArch() == llvm::Triple::x86_64;
+llvm::ExceptionHandling
+toolchains::MinGW::GetExceptionModel(const ArgList &Args) const {
+ if (getArch() == llvm::Triple::x86_64)
+ return llvm::ExceptionHandling::WinEH;
+ return llvm::ExceptionHandling::DwarfCFI;
}
void toolchains::MinGW::AddCudaIncludeArgs(const ArgList &DriverArgs,
diff --git a/clang/lib/Driver/ToolChains/MinGW.h b/clang/lib/Driver/ToolChains/MinGW.h
index 9b3d7c553f1..f8dbcae6275 100644
--- a/clang/lib/Driver/ToolChains/MinGW.h
+++ b/clang/lib/Driver/ToolChains/MinGW.h
@@ -64,7 +64,9 @@ public:
bool isPICDefault() const override;
bool isPIEDefault() const override;
bool isPICDefaultForced() const override;
- bool UseSEHExceptions() const;
+
+ llvm::ExceptionHandling GetExceptionModel(
+ const llvm::opt::ArgList &Args) const override;
void
AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
diff --git a/clang/lib/Driver/ToolChains/NetBSD.cpp b/clang/lib/Driver/ToolChains/NetBSD.cpp
index 85bb69cfda0..c0a0808b377 100644
--- a/clang/lib/Driver/ToolChains/NetBSD.cpp
+++ b/clang/lib/Driver/ToolChains/NetBSD.cpp
@@ -416,6 +416,14 @@ void NetBSD::addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,
"", DriverArgs, CC1Args);
}
+llvm::ExceptionHandling NetBSD::GetExceptionModel(const ArgList &Args) const {
+ // NetBSD uses Dwarf exceptions on ARM.
+ if (getTriple().getArch() == llvm::Triple::arm ||
+ getTriple().getArch() == llvm::Triple::thumb)
+ return llvm::ExceptionHandling::DwarfCFI;
+ return llvm::ExceptionHandling::None;
+}
+
SanitizerMask NetBSD::getSupportedSanitizers() const {
const bool IsX86 = getTriple().getArch() == llvm::Triple::x86;
const bool IsX86_64 = getTriple().getArch() == llvm::Triple::x86_64;
diff --git a/clang/lib/Driver/ToolChains/NetBSD.h b/clang/lib/Driver/ToolChains/NetBSD.h
index 5163ff72d81..e98df72ce65 100644
--- a/clang/lib/Driver/ToolChains/NetBSD.h
+++ b/clang/lib/Driver/ToolChains/NetBSD.h
@@ -69,6 +69,9 @@ public:
return true;
}
+ llvm::ExceptionHandling GetExceptionModel(
+ const llvm::opt::ArgList &Args) const override;
+
SanitizerMask getSupportedSanitizers() const override;
protected:
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index 3d484170f82..cdd53608f65 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -2141,7 +2141,18 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
Opts.Exceptions = Args.hasArg(OPT_fexceptions);
Opts.ObjCExceptions = Args.hasArg(OPT_fobjc_exceptions);
Opts.CXXExceptions = Args.hasArg(OPT_fcxx_exceptions);
- Opts.SjLjExceptions = Args.hasArg(OPT_fsjlj_exceptions);
+
+ // Handle exception personalities
+ Arg *A = Args.getLastArg(options::OPT_fsjlj_exceptions,
+ options::OPT_fseh_exceptions,
+ options::OPT_fdwarf_exceptions);
+ if (A) {
+ const Option &Opt = A->getOption();
+ Opts.SjLjExceptions = Opt.matches(options::OPT_fsjlj_exceptions);
+ Opts.SEHExceptions = Opt.matches(options::OPT_fseh_exceptions);
+ Opts.DWARFExceptions = Opt.matches(options::OPT_fdwarf_exceptions);
+ }
+
Opts.ExternCNoUnwind = Args.hasArg(OPT_fexternc_nounwind);
Opts.TraditionalCPP = Args.hasArg(OPT_traditional_cpp);
diff --git a/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp
index 1dfbf187554..67c1faddc3a 100644
--- a/clang/lib/Frontend/InitPreprocessor.cpp
+++ b/clang/lib/Frontend/InitPreprocessor.cpp
@@ -677,8 +677,14 @@ static void InitializePredefinedMacros(const TargetInfo &TI,
Builder.defineMacro("__EXCEPTIONS");
if (!LangOpts.MSVCCompat && LangOpts.RTTI)
Builder.defineMacro("__GXX_RTTI");
+
if (LangOpts.SjLjExceptions)
Builder.defineMacro("__USING_SJLJ_EXCEPTIONS__");
+ else if (LangOpts.SEHExceptions)
+ Builder.defineMacro("__SEH__");
+ else if (LangOpts.DWARFExceptions &&
+ (TI.getTriple().isThumb() || TI.getTriple().isARM()))
+ Builder.defineMacro("__ARM_DWARF_EH__");
if (LangOpts.Deprecated)
Builder.defineMacro("__DEPRECATED");
diff --git a/clang/test/CodeGenCXX/mingw-w64-exceptions.c b/clang/test/CodeGenCXX/mingw-w64-exceptions.c
new file mode 100644
index 00000000000..e980ebd3350
--- /dev/null
+++ b/clang/test/CodeGenCXX/mingw-w64-exceptions.c
@@ -0,0 +1,22 @@
+// RUN: %clang -target x86_64-windows-gnu -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SEH
+// RUN: %clang -target i686-windows-gnu -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-DWARF
+
+// RUN: %clang -target x86_64-windows-gnu -fsjlj-exceptions -c %s -### 2>&1 | \
+// RUN: FileCheck %s --check-prefix=CHECK-SJLJ
+
+// RUN: %clang -target x86_64-windows-gnu -fdwarf-exceptions -c %s -### 2>&1 | \
+// RUN: FileCheck %s --check-prefix=CHECK-DWARF
+
+// RUN: %clang -target x86_64-windows-gnu -fsjlj-exceptions -fseh-exceptions -c %s -### 2>&1 | \
+// RUN: FileCheck %s --check-prefix=CHECK-SEH
+
+// RUN: %clang -target x86_64-windows-gnu -fseh-exceptions -fsjlj-exceptions -c %s -### 2>&1 | \
+// RUN: FileCheck %s --check-prefix=CHECK-SJLJ
+
+// RUN: %clang -target x86_64-windows-gnu -fseh-exceptions -fdwarf-exceptions -c %s -### 2>&1 | \
+// RUN: FileCheck %s --check-prefix=CHECK-DWARF
+
+// CHECK-SEH: "-fseh-exceptions"
+// CHECK-SJLJ: "-fsjlj-exceptions"
+// CHECK-DWARF-NOT: "-fsjlj-exceptions"
+// CHECK-DWARF-NOT: "-fseh-exceptions"
diff --git a/clang/test/CodeGenCXX/mingw-w64-seh-exceptions.cpp b/clang/test/CodeGenCXX/mingw-w64-seh-exceptions.cpp
index 9025f877c55..046c4a815f4 100644
--- a/clang/test/CodeGenCXX/mingw-w64-seh-exceptions.cpp
+++ b/clang/test/CodeGenCXX/mingw-w64-seh-exceptions.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 %s -fexceptions -emit-llvm -triple x86_64-w64-windows-gnu -o - | FileCheck %s --check-prefix=X64
+// RUN: %clang_cc1 %s -fexceptions -fseh-exceptions -emit-llvm -triple x86_64-w64-windows-gnu -o - | FileCheck %s --check-prefix=X64
+// RUN: %clang_cc1 %s -fexceptions -fdwarf-exceptions -emit-llvm -triple i686-w64-windows-gnu -o - | FileCheck %s --check-prefix=X86
// RUN: %clang_cc1 %s -fexceptions -emit-llvm -triple i686-w64-windows-gnu -o - | FileCheck %s --check-prefix=X86
extern "C" void foo();
diff --git a/clang/test/Preprocessor/arm-target-features.c b/clang/test/Preprocessor/arm-target-features.c
index b206e1cf36f..0067e108d33 100644
--- a/clang/test/Preprocessor/arm-target-features.c
+++ b/clang/test/Preprocessor/arm-target-features.c
@@ -214,6 +214,7 @@
// A5:#define __ARM_ARCH_7A__ 1
// A5-NOT:#define __ARM_ARCH_EXT_IDIV__
// A5:#define __ARM_ARCH_PROFILE 'A'
+// A5-NOT:#define __ARM_DWARF_EH__ 1
// A5-NOT: #define __ARM_FEATURE_DIRECTED_ROUNDING
// A5:#define __ARM_FEATURE_DSP 1
// A5-NOT: #define __ARM_FEATURE_NUMERIC_MAXMIN
@@ -225,6 +226,7 @@
// A7:#define __ARM_ARCH 7
// A7:#define __ARM_ARCH_EXT_IDIV__ 1
// A7:#define __ARM_ARCH_PROFILE 'A'
+// A7-NOT:#define __ARM_DWARF_EH__ 1
// A7:#define __ARM_FEATURE_DSP 1
// A7:#define __ARM_FP 0xE
diff --git a/clang/test/Preprocessor/init.c b/clang/test/Preprocessor/init.c
index 5fc568eae58..f767c7ad01a 100644
--- a/clang/test/Preprocessor/init.c
+++ b/clang/test/Preprocessor/init.c
@@ -1442,6 +1442,7 @@
//
// ARM-MSVC: #define _M_ARM_NT 1
// ARM-MSVC: #define _WIN32 1
+// ARM-MSVC-NOT:#define __ARM_DWARF_EH__ 1
// RUN: %clang_cc1 -E -dM -ffreestanding -triple=aarch64-windows-msvc < /dev/null | FileCheck -match-full-lines -check-prefix AARCH64-MSVC %s
//
OpenPOWER on IntegriCloud