]> granicus.if.org Git - clang/commitdiff
Add -fseh-exceptions for MinGW-w64
authorReid Kleckner <reid@kleckner.net>
Mon, 15 Sep 2014 17:19:16 +0000 (17:19 +0000)
committerReid Kleckner <reid@kleckner.net>
Mon, 15 Sep 2014 17:19:16 +0000 (17:19 +0000)
This adds a flag called -fseh-exceptions that uses the native Windows
.pdata and .xdata unwind mechanism to throw exceptions. The other EH
possibilities are DWARF and SJLJ exceptions.

Patch by Martell Malone!

Reviewed By: asl, rnk

Differential Revision: http://reviews.llvm.org/D3419

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@217790 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/LangOptions.def
include/clang/Driver/CC1Options.td
include/clang/Driver/ToolChain.h
lib/CodeGen/CGException.cpp
lib/Driver/Tools.cpp
lib/Frontend/CompilerInvocation.cpp
lib/Frontend/InitPreprocessor.cpp
test/CodeGenCXX/mingw-w64-seh-exceptions.cpp [new file with mode: 0644]

index b84b9ac49b2f82b12edb3b15ca1bc961cf584d14..ec451e16e1e4f920e68987481b4028cd9e7fe9f2 100644 (file)
@@ -82,6 +82,7 @@ LANGOPT(Exceptions        , 1, 0, "exception handling")
 LANGOPT(ObjCExceptions    , 1, 0, "Objective-C exceptions")
 LANGOPT(CXXExceptions     , 1, 0, "C++ exceptions")
 LANGOPT(SjLjExceptions    , 1, 0, "setjmp-longjump exception handling")
+LANGOPT(SEHExceptions     , 1, 0, "SEH exception handling")
 LANGOPT(TraditionalCPP    , 1, 0, "traditional CPP emulation")
 LANGOPT(RTTI              , 1, 1, "run-time type information")
 LANGOPT(RTTIData          , 1, 1, "emit run-time type information data")
index a1842d0efce00551d506171600860dd2bf3db220..8d477cc9d9317a918a5dc1110bfd2045ee1eec5a 100644 (file)
@@ -435,6 +435,8 @@ def fblocks_runtime_optional : Flag<["-"], "fblocks-runtime-optional">,
   HelpText<"Weakly link in the blocks runtime">;
 def fsjlj_exceptions : Flag<["-"], "fsjlj-exceptions">,
   HelpText<"Use SjLj style exceptions">;
+def fseh_exceptions : Flag<["-"], "fseh-exceptions">,
+  HelpText<"Use SEH style exceptions">;
 def split_dwarf_file : Separate<["-"], "split-dwarf-file">,
   HelpText<"File name to use for split dwarf debug info output">;
 def fno_wchar : Flag<["-"], "fno-wchar">,
index ea3863fee04a2451d1516408d518e26000408cc7..e9fbe6cd77f43443335b682052c138ebabfb7947 100644 (file)
@@ -248,6 +248,9 @@ public:
   /// UseSjLjExceptions - Does this tool chain use SjLj exceptions.
   virtual bool UseSjLjExceptions() const { return false; }
 
+  /// UseSEHExceptions - Does this tool chain use SEH exceptions.
+  virtual bool UseSEHExceptions() const { return false; }
+
   /// ComputeLLVMTriple - Return the LLVM target triple to use, after taking
   /// command line arguments into account.
   virtual std::string
index 05eb6ebca30b86c2dc68cd8093aa3ee512ab503f..0b7e57a3c5f56d6753b82cc5bf93a3b8889f39e7 100644 (file)
@@ -137,12 +137,14 @@ namespace {
     static const EHPersonality &get(const LangOptions &Lang);
     static const EHPersonality GNU_C;
     static const EHPersonality GNU_C_SJLJ;
+    static const EHPersonality GNU_C_SEH;
     static const EHPersonality GNU_ObjC;
     static const EHPersonality GNUstep_ObjC;
     static const EHPersonality GNU_ObjCXX;
     static const EHPersonality NeXT_ObjC;
     static const EHPersonality GNU_CPlusPlus;
     static const EHPersonality GNU_CPlusPlus_SJLJ;
+    static const EHPersonality GNU_CPlusPlus_SEH;
   };
 }
 
@@ -150,12 +152,16 @@ const EHPersonality EHPersonality::GNU_C = { "__gcc_personality_v0", nullptr };
 const EHPersonality
 EHPersonality::GNU_C_SJLJ = { "__gcc_personality_sj0", nullptr };
 const EHPersonality
+EHPersonality::GNU_C_SEH = { "__gcc_personality_seh0", nullptr };
+const EHPersonality
 EHPersonality::NeXT_ObjC = { "__objc_personality_v0", nullptr };
 const EHPersonality
 EHPersonality::GNU_CPlusPlus = { "__gxx_personality_v0", nullptr };
 const EHPersonality
 EHPersonality::GNU_CPlusPlus_SJLJ = { "__gxx_personality_sj0", nullptr };
 const EHPersonality
+EHPersonality::GNU_CPlusPlus_SEH = { "__gxx_personality_seh0", nullptr };
+const EHPersonality
 EHPersonality::GNU_ObjC = {"__gnu_objc_personality_v0", "objc_exception_throw"};
 const EHPersonality
 EHPersonality::GNU_ObjCXX = { "__gnustep_objcxx_personality_v0", nullptr };
@@ -165,6 +171,8 @@ EHPersonality::GNUstep_ObjC = { "__gnustep_objc_personality_v0", nullptr };
 static const EHPersonality &getCPersonality(const LangOptions &L) {
   if (L.SjLjExceptions)
     return EHPersonality::GNU_C_SJLJ;
+  if (L.SEHExceptions)
+    return EHPersonality::GNU_C_SEH;
   return EHPersonality::GNU_C;
 }
 
@@ -189,6 +197,8 @@ static const EHPersonality &getObjCPersonality(const LangOptions &L) {
 static const EHPersonality &getCXXPersonality(const LangOptions &L) {
   if (L.SjLjExceptions)
     return EHPersonality::GNU_CPlusPlus_SJLJ;
+  else if (L.SEHExceptions)
+    return EHPersonality::GNU_CPlusPlus_SEH;
   else
     return EHPersonality::GNU_CPlusPlus;
 }
index 0e1dea2a97f6a06346e13e2efa3d54c738750bc8..6be498eef57248b8ae7f77dafe4668b21be2dfb6 100644 (file)
@@ -4112,6 +4112,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
 
   if (getToolChain().UseSjLjExceptions())
     CmdArgs.push_back("-fsjlj-exceptions");
+  else if (getToolChain().UseSEHExceptions())
+    CmdArgs.push_back("-fseh-exceptions");
 
   // C++ "sane" operator new.
   if (!Args.hasFlag(options::OPT_fassume_sane_operator_new,
index a8bb13181dcbe713d0482a219fef7d9f65bd822d..0dde41acf2e525e9f5a5205654ac3e05aed7220e 100644 (file)
@@ -1431,6 +1431,7 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
   Opts.ObjCExceptions = Args.hasArg(OPT_fobjc_exceptions);
   Opts.CXXExceptions = Args.hasArg(OPT_fcxx_exceptions);
   Opts.SjLjExceptions = Args.hasArg(OPT_fsjlj_exceptions);
+  Opts.SEHExceptions = Args.hasArg(OPT_fseh_exceptions);
   Opts.TraditionalCPP = Args.hasArg(OPT_traditional_cpp);
 
   Opts.RTTI = !Args.hasArg(OPT_fno_rtti);
index d691d19730b648d7d74388c91fb01a51d6aa679b..daff9ce9114c19be8580a0aa8c6788b1404978e0 100644 (file)
@@ -556,6 +556,8 @@ static void InitializePredefinedMacros(const TargetInfo &TI,
     Builder.defineMacro("__GXX_RTTI");
   if (LangOpts.SjLjExceptions)
     Builder.defineMacro("__USING_SJLJ_EXCEPTIONS__");
+  if (LangOpts.SEHExceptions)
+    Builder.defineMacro("__SEH__");
 
   if (LangOpts.Deprecated)
     Builder.defineMacro("__DEPRECATED");
diff --git a/test/CodeGenCXX/mingw-w64-seh-exceptions.cpp b/test/CodeGenCXX/mingw-w64-seh-exceptions.cpp
new file mode 100644 (file)
index 0000000..f247e99
--- /dev/null
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 %s -fexceptions -fseh-exceptions -emit-llvm -triple x86_64-w64-windows-gnu -o - | FileCheck %s
+
+extern "C" void foo();
+extern "C" void bar();
+
+struct Cleanup {
+  ~Cleanup() {
+    bar();
+  }
+};
+
+extern "C" void test() {
+  Cleanup x;
+  foo();
+}
+
+// CHECK: define void @test()
+// CHECK: invoke void @foo()
+// CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_seh0 to i8*)