- 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