summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorReid Kleckner <rnk@google.com>2017-01-09 17:04:37 +0000
committerReid Kleckner <rnk@google.com>2017-01-09 17:04:37 +0000
commitf0e69d8f972711dcdb5faf499480967fdf2e81e7 (patch)
treed6bde2a35c2320c05fac9ace5209bd0a4747d873
parentddb8d277a0b6d804856bc7157a2a342761cdb701 (diff)
[MS] Fix function type mangling of default ctor closures
Use the canonical decl in pointer comparisons with the default constructor closure decl. Otherwise we don't produce the correct "@@QAEXXZ" mangling, which essentially means "void(void) thiscall public instance method". git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@291448 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/AST/MicrosoftMangle.cpp16
-rw-r--r--test/CodeGenCXX/dllexport.cpp6
2 files changed, 16 insertions, 6 deletions
diff --git a/lib/AST/MicrosoftMangle.cpp b/lib/AST/MicrosoftMangle.cpp
index 911b8b471a..8e01c45481 100644
--- a/lib/AST/MicrosoftMangle.cpp
+++ b/lib/AST/MicrosoftMangle.cpp
@@ -109,13 +109,13 @@ static const DeclContext *getEffectiveParentContext(const DeclContext *DC) {
static const FunctionDecl *getStructor(const NamedDecl *ND) {
if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(ND))
- return FTD->getTemplatedDecl();
+ return FTD->getTemplatedDecl()->getCanonicalDecl();
const auto *FD = cast<FunctionDecl>(ND);
if (const auto *FTD = FD->getPrimaryTemplate())
- return FTD->getTemplatedDecl();
+ return FTD->getTemplatedDecl()->getCanonicalDecl();
- return FD;
+ return FD->getCanonicalDecl();
}
/// MicrosoftMangleContextImpl - Overrides the default MangleContext for the
@@ -312,6 +312,10 @@ public:
void mangleNestedName(const NamedDecl *ND);
private:
+ bool isStructorDecl(const NamedDecl *ND) const {
+ return ND == Structor || getStructor(ND) == Structor;
+ }
+
void mangleUnqualifiedName(const NamedDecl *ND) {
mangleUnqualifiedName(ND, ND->getDeclName());
}
@@ -912,7 +916,7 @@ void MicrosoftCXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND,
return;
case DeclarationName::CXXDestructorName:
- if (ND == Structor)
+ if (isStructorDecl(ND))
// If the named decl is the C++ destructor we're mangling,
// use the type we were given.
mangleCXXDtorType(static_cast<CXXDtorType>(StructorType));
@@ -1862,7 +1866,7 @@ void MicrosoftCXXNameMangler::mangleFunctionType(const FunctionType *T,
IsStructor = true;
IsCtorClosure = (StructorType == Ctor_CopyingClosure ||
StructorType == Ctor_DefaultClosure) &&
- getStructor(MD) == Structor;
+ isStructorDecl(MD);
if (IsCtorClosure)
CC = getASTContext().getDefaultCallingConvention(
/*IsVariadic=*/false, /*IsCXXMethod=*/true);
@@ -1883,7 +1887,7 @@ void MicrosoftCXXNameMangler::mangleFunctionType(const FunctionType *T,
// <return-type> ::= <type>
// ::= @ # structors (they have no declared return type)
if (IsStructor) {
- if (isa<CXXDestructorDecl>(D) && D == Structor &&
+ if (isa<CXXDestructorDecl>(D) && isStructorDecl(D) &&
StructorType == Dtor_Deleting) {
// The scalar deleting destructor takes an extra int argument.
// However, the FunctionType generated has 0 arguments.
diff --git a/test/CodeGenCXX/dllexport.cpp b/test/CodeGenCXX/dllexport.cpp
index 116176e2cb..012b6292c6 100644
--- a/test/CodeGenCXX/dllexport.cpp
+++ b/test/CodeGenCXX/dllexport.cpp
@@ -498,6 +498,12 @@ struct CtorWithClosure {
// M32-DAG: ret void
};
+struct CtorWithClosureOutOfLine {
+ __declspec(dllexport) CtorWithClosureOutOfLine(...);
+};
+CtorWithClosureOutOfLine::CtorWithClosureOutOfLine(...) {}
+// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??_FCtorWithClosureOutOfLine@@QAEXXZ"({{.*}}) {{#[0-9]+}} comdat
+
#define DELETE_IMPLICIT_MEMBERS(ClassName) \
ClassName(ClassName &&) = delete; \
ClassName(ClassName &) = delete; \