- Addressed review comments.

http://reviews.llvm.org/D8225

Files:
  include/clang/Basic/ABI.h
  lib/AST/ItaniumMangle.cpp
  lib/AST/MicrosoftMangle.cpp
  lib/CodeGen/CodeGenTypes.h
  lib/CodeGen/MicrosoftCXXABI.cpp
  test/CodeGenCXX/microsoft-abi-throw.cpp

EMAIL PREFERENCES
  http://reviews.llvm.org/settings/panel/emailpreferences/
Index: include/clang/Basic/ABI.h
===================================================================
--- include/clang/Basic/ABI.h
+++ include/clang/Basic/ABI.h
@@ -22,10 +22,11 @@
 
 /// \brief C++ constructor types.
 enum CXXCtorType {
-  Ctor_Complete, ///< Complete object ctor
-  Ctor_Base,     ///< Base object ctor
-  Ctor_Comdat,   ///< The COMDAT used for ctors
-  Ctor_Closure,  ///< Closure variant of a ctor
+  Ctor_Complete,       ///< Complete object ctor
+  Ctor_Base,           ///< Base object ctor
+  Ctor_Comdat,         ///< The COMDAT used for ctors
+  Ctor_CopyingClosure, ///< Copying closure variant of a ctor
+  Ctor_DefaultClosure, ///< Default closure variant of a ctor
 };
 
 /// \brief C++ destructor types.
Index: lib/AST/ItaniumMangle.cpp
===================================================================
--- lib/AST/ItaniumMangle.cpp
+++ lib/AST/ItaniumMangle.cpp
@@ -3442,7 +3442,8 @@
   case Ctor_Comdat:
     Out << "C5";
     break;
-  case Ctor_Closure:
+  case Ctor_DefaultClosure:
+  case Ctor_CopyingClosure:
     llvm_unreachable("closure constructors don't exist for the Itanium ABI!");
   }
 }
Index: lib/AST/MicrosoftMangle.cpp
===================================================================
--- lib/AST/MicrosoftMangle.cpp
+++ lib/AST/MicrosoftMangle.cpp
@@ -67,11 +67,15 @@
   return getEffectiveDeclContext(cast<Decl>(DC));
 }
 
-static const FunctionDecl *getStructor(const FunctionDecl *fn) {
-  if (const FunctionTemplateDecl *ftd = fn->getPrimaryTemplate())
-    return ftd->getTemplatedDecl();
+static const FunctionDecl *getStructor(const NamedDecl *ND) {
+  if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(ND))
+    return FTD->getTemplatedDecl();
 
-  return fn;
+  const auto *FD = cast<FunctionDecl>(ND);
+  if (const auto *FTD = FD->getPrimaryTemplate())
+    return FTD->getTemplatedDecl();
+
+  return FD;
 }
 
 static bool isLambda(const NamedDecl *ND) {
@@ -777,19 +781,18 @@
       llvm_unreachable("Can't mangle Objective-C selector names here!");
 
     case DeclarationName::CXXConstructorName:
-      if (Structor == ND && StructorType == Ctor_Closure) {
-        const auto *CD = cast<CXXConstructorDecl>(ND);
-        if (CD->isDefaultConstructor()) {
-          Out << "?_F";
-        } else if (CD->isCopyConstructor()) {
+      if (Structor == getStructor(ND)) {
+        if (StructorType == Ctor_CopyingClosure) {
           Out << "?_O";
-        } else {
-          llvm_unreachable("unexpected constructor closure!");
+          return;
+        }
+        if (StructorType == Ctor_DefaultClosure) {
+          Out << "?_F";
+          return;
         }
-      } else {
-        Out << "?0";
       }
-      break;
+      Out << "?0";
+      return;
 
     case DeclarationName::CXXDestructorName:
       if (ND == Structor)
@@ -1589,7 +1592,9 @@
       IsStructor = true;
     } else if (isa<CXXConstructorDecl>(MD)) {
       IsStructor = true;
-      IsCtorClosure = MD == Structor && StructorType == Ctor_Closure;
+      IsCtorClosure = (StructorType == Ctor_CopyingClosure ||
+                       StructorType == Ctor_DefaultClosure) &&
+                      getStructor(MD) == Structor;
       if (IsCtorClosure)
         CC = getASTContext().getDefaultCallingConvention(
             /*IsVariadic=*/false, /*IsCXXMethod=*/true);
@@ -1620,16 +1625,14 @@
       return;
     }
     if (IsCtorClosure) {
-      const auto *CD = cast<CXXConstructorDecl>(D);
-
       // Default constructor closure and copy constructor closure both return
       // void.
       Out << 'X';
 
-      if (CD->isDefaultConstructor()) {
+      if (StructorType == Ctor_DefaultClosure) {
         // Default constructor closure always has no arguments.
         Out << 'X';
-      } else if (CD->isCopyConstructor()) {
+      } else if (StructorType == Ctor_CopyingClosure) {
         // Copy constructor closure always takes an unqualified reference.
         mangleArgumentType(getASTContext().getLValueReferenceType(
                                Proto->getParamType(0)
Index: lib/CodeGen/CodeGenTypes.h
===================================================================
--- lib/CodeGen/CodeGenTypes.h
+++ lib/CodeGen/CodeGenTypes.h
@@ -82,7 +82,8 @@
     return StructorType::Base;
   case Ctor_Comdat:
     llvm_unreachable("not expecting a COMDAT");
-  case Ctor_Closure:
+  case Ctor_CopyingClosure:
+  case Ctor_DefaultClosure:
     llvm_unreachable("not expecting a closure");
   }
   llvm_unreachable("not a CXXCtorType");
Index: lib/CodeGen/MicrosoftCXXABI.cpp
===================================================================
--- lib/CodeGen/MicrosoftCXXABI.cpp
+++ lib/CodeGen/MicrosoftCXXABI.cpp
@@ -3227,7 +3227,7 @@
   // Calculate the mangled name.
   SmallString<256> ThunkName;
   llvm::raw_svector_ostream Out(ThunkName);
-  getMangleContext().mangleCXXCtor(CD, Ctor_Closure, Out);
+  getMangleContext().mangleCXXCtor(CD, Ctor_CopyingClosure, Out);
   Out.flush();
 
   // If the thunk has been generated previously, just return it.
@@ -3328,13 +3328,10 @@
   if (CD) {
     CallingConv ExpectedCallingConv = getContext().getDefaultCallingConvention(
         /*IsVariadic=*/false, /*IsCXXMethod=*/true);
-    CallingConv ActualCallingConv = CD->getType()
-                                        ->getCanonicalTypeUnqualified()
-                                        .getAs<FunctionProtoType>()
-                                        ->getExtInfo()
-                                        .getCC();
+    CallingConv ActualCallingConv =
+        CD->getType()->getAs<FunctionProtoType>()->getCallConv();
     if (ExpectedCallingConv != ActualCallingConv || CD->getNumParams() != 1)
-      CT = Ctor_Closure;
+      CT = Ctor_CopyingClosure;
   }
 
   uint32_t Size = getContext().getTypeSizeInChars(T).getQuantity();
@@ -3355,7 +3352,7 @@
   // exception is caught by value.
   llvm::Constant *CopyCtor;
   if (CD) {
-    if (CT == Ctor_Closure)
+    if (CT == Ctor_CopyingClosure)
       CopyCtor = getAddrOfCXXCopyCtorClosure(CD);
     else
       CopyCtor = CGM.getAddrOfCXXStructor(CD, StructorType::Complete);
Index: test/CodeGenCXX/microsoft-abi-throw.cpp
===================================================================
--- test/CodeGenCXX/microsoft-abi-throw.cpp
+++ test/CodeGenCXX/microsoft-abi-throw.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm -o - -triple=i386-pc-win32 %s -fcxx-exceptions | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm -o - -triple=i386-pc-win32 -std=c++11 %s -fcxx-exceptions | FileCheck %s
 
 // CHECK-DAG: @"\01??_R0?AUY@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AUY@@\00" }, comdat
 // CHECK-DAG: @"_CT??_R0?AUY@@@8??0Y@@QAE@ABU0@@Z8" = linkonce_odr unnamed_addr constant %eh.CatchableType { i32 4, i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUY@@@8" to i8*), i32 0, i32 -1, i32 0, i32 8, i8* bitcast (%struct.Y* (%struct.Y*, %struct.Y*, i32)* @"\01??0Y@@QAE@ABU0@@Z" to i8*) }, section ".xdata", comdat
@@ -13,6 +13,8 @@
 // CHECK-DAG: @"_CTA5?AUY@@" = linkonce_odr unnamed_addr constant %eh.CatchableTypeArray.5 { i32 5, [5 x %eh.CatchableType*] [%eh.CatchableType* @"_CT??_R0?AUY@@@8??0Y@@QAE@ABU0@@Z8", %eh.CatchableType* @"_CT??_R0?AUZ@@@81", %eh.CatchableType* @"_CT??_R0?AUW@@@8??0W@@QAE@ABU0@@Z44", %eh.CatchableType* @"_CT??_R0?AUM@@@818", %eh.CatchableType* @"_CT??_R0?AUV@@@81044"] }, section ".xdata", comdat
 // CHECK-DAG: @"_TI5?AUY@@" = linkonce_odr unnamed_addr constant %eh.ThrowInfo { i32 0, i8* bitcast (void (%struct.Y*)* @"\01??_DY@@QAE@XZ" to i8*), i8* null, i8* bitcast (%eh.CatchableTypeArray.5* @"_CTA5?AUY@@" to i8*) }, section ".xdata", comdat
 // CHECK-DAG: @"_CT??_R0?AUDefault@@@8??_ODefault@@QAEXAAU0@@Z1" = linkonce_odr unnamed_addr constant %eh.CatchableType { i32 0, i8* bitcast (%rtti.TypeDescriptor13* @"\01??_R0?AUDefault@@@8" to i8*), i32 0, i32 -1, i32 0, i32 1, i8* bitcast (void (%struct.Default*, %struct.Default*)* @"\01??_ODefault@@QAEXAAU0@@Z" to i8*) }, section ".xdata", comdat
+// CHECK-DAG: @"_CT??_R0?AUVariadic@@@8??_OVariadic@@QAEXAAU0@@Z1" = linkonce_odr unnamed_addr constant %eh.CatchableType { i32 0, i8* bitcast (%rtti.TypeDescriptor14* @"\01??_R0?AUVariadic@@@8" to i8*), i32 0, i32 -1, i32 0, i32 1, i8* bitcast (void (%struct.Variadic*, %struct.Variadic*)* @"\01??_OVariadic@@QAEXAAU0@@Z" to i8*) }, section ".xdata", comdat
+// CHECK-DAG: @"_CT??_R0?AUBad@@@8??$?_OH@Bad@@QAEXAAU0@@Z1" = linkonce_odr unnamed_addr constant %eh.CatchableType { i32 0, i8* bitcast (%rtti.TypeDescriptor9* @"\01??_R0?AUBad@@@8" to i8*), i32 0, i32 -1, i32 0, i32 1, i8* bitcast (void (%struct.Bad*, %struct.Bad*)* @"\01??$?_OH@Bad@@QAEXAAU0@@Z" to i8*) }, section ".xdata", comdat
 
 
 struct N { ~N(); };
@@ -54,3 +56,34 @@
 void h(Default &d) {
   throw d;
 }
+
+struct Variadic {
+  Variadic(Variadic &, ...);
+};
+
+void i(Variadic &v) {
+  throw v;
+}
+
+// CHECK-LABEL: @"\01??_OVariadic@@QAEXAAU0@@Z"
+// CHECK:  %[[src_addr:.*]] = alloca
+// CHECK:  %[[this_addr:.*]] = alloca
+// CHECK:  store {{.*}} %src, {{.*}} %[[src_addr:.*]], align
+// CHECK:  store {{.*}} %this, {{.*}} %[[this_addr:.*]], align
+// CHECK:  %[[this:.*]] = load {{.*}} %[[this_addr]]
+// CHECK:  %[[src:.*]] = load {{.*}} %[[src_addr]]
+// CHECK:  %call = call {{.*}} @"\01??0Variadic@@QAA@AAU0@ZZ"({{.*}} %[[this]], {{.*}} %[[src]])
+// CHECK:  ret void
+
+struct Bad {
+  template <typename T>
+  static int f() {
+    return 0;
+  }
+  template <typename T = int>
+  Bad(Bad &, T = f<T>());
+};
+
+void j(Bad &bad) {
+  throw bad;
+}
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to