diff options
author | David Majnemer <david.majnemer@gmail.com> | 2014-08-07 22:56:13 +0000 |
---|---|---|
committer | David Majnemer <david.majnemer@gmail.com> | 2014-08-07 22:56:13 +0000 |
commit | b3e5654923e074b7f5ebb1e7c54519e2911a06f7 (patch) | |
tree | b6f2c6de7d7d641d4722824956f5e8cb179dd39b /clang/lib/CodeGen | |
parent | 76e8af88b8b4ea8c3381dc5730b27ac6df18bac7 (diff) | |
download | bcm5719-llvm-b3e5654923e074b7f5ebb1e7c54519e2911a06f7.tar.gz bcm5719-llvm-b3e5654923e074b7f5ebb1e7c54519e2911a06f7.zip |
MS ABI: Handle member function pointers returning a member data pointer
MSVC doesn't decide what the inheritance model for a returned member
pointer *until* a call expression returns it.
This fixes PR20017.
llvm-svn: 215164
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r-- | clang/lib/CodeGen/CGCXXABI.h | 5 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenTypes.cpp | 7 | ||||
-rw-r--r-- | clang/lib/CodeGen/MicrosoftCXXABI.cpp | 5 |
3 files changed, 16 insertions, 1 deletions
diff --git a/clang/lib/CodeGen/CGCXXABI.h b/clang/lib/CodeGen/CGCXXABI.h index 91e49707bae..40418b60c1b 100644 --- a/clang/lib/CodeGen/CGCXXABI.h +++ b/clang/lib/CodeGen/CGCXXABI.h @@ -156,6 +156,11 @@ public: /// (in the C++ sense) with an LLVM zeroinitializer. virtual bool isZeroInitializable(const MemberPointerType *MPT); + /// Return whether or not a member pointers type is convertible to an IR type. + virtual bool isMemberPointerConvertible(const MemberPointerType *MPT) const { + return true; + } + /// Create a null member pointer of the given type. virtual llvm::Constant *EmitNullMemberPointer(const MemberPointerType *MPT); diff --git a/clang/lib/CodeGen/CodeGenTypes.cpp b/clang/lib/CodeGen/CodeGenTypes.cpp index d4e22623e02..6b0e4ad8b31 100644 --- a/clang/lib/CodeGen/CodeGenTypes.cpp +++ b/clang/lib/CodeGen/CodeGenTypes.cpp @@ -187,6 +187,11 @@ static bool isSafeToConvert(const RecordDecl *RD, CodeGenTypes &CGT) { /// we've temporarily deferred expanding the type because we're in a recursive /// context. bool CodeGenTypes::isFuncParamTypeConvertible(QualType Ty) { + // Some ABIs cannot have their member pointers represented in IR unless + // certain circumstances have been reached. + if (const auto *MPT = Ty->getAs<MemberPointerType>()) + return getCXXABI().isMemberPointerConvertible(MPT); + // If this isn't a tagged type, we can convert it! const TagType *TT = Ty->getAs<TagType>(); if (!TT) return true; @@ -194,7 +199,7 @@ bool CodeGenTypes::isFuncParamTypeConvertible(QualType Ty) { // Incomplete types cannot be converted. if (TT->isIncompleteType()) return false; - + // If this is an enum, then it is always safe to convert. const RecordType *RT = dyn_cast<RecordType>(TT); if (!RT) return true; diff --git a/clang/lib/CodeGen/MicrosoftCXXABI.cpp b/clang/lib/CodeGen/MicrosoftCXXABI.cpp index 23f9768d4a8..d01fb7bf34f 100644 --- a/clang/lib/CodeGen/MicrosoftCXXABI.cpp +++ b/clang/lib/CodeGen/MicrosoftCXXABI.cpp @@ -482,6 +482,11 @@ public: bool isZeroInitializable(const MemberPointerType *MPT) override; + bool isMemberPointerConvertible(const MemberPointerType *MPT) const override { + const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl(); + return RD->getAttr<MSInheritanceAttr>() != nullptr; + } + llvm::Constant *EmitNullMemberPointer(const MemberPointerType *MPT) override; llvm::Constant *EmitMemberDataPointer(const MemberPointerType *MPT, |