[ms-cxxabi] Add more tests for r178297

This covers a few cases where the class of a member pointer is not a
CXXRecordDecl.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@178307 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Reid Kleckner 2013-03-28 23:11:29 +00:00
Родитель 4bbae38abf
Коммит e93e2552e7
2 изменённых файлов: 35 добавлений и 2 удалений

Просмотреть файл

@ -1733,12 +1733,12 @@ QualType Sema::BuildMemberPointerType(QualType T, QualType Class,
// when passing pointers between TUs that disagree about the size.
if (Context.getTargetInfo().getCXXABI().isMicrosoft()) {
CXXRecordDecl *RD = Class->getAsCXXRecordDecl();
if (!RD || !RD->hasAttr<MSInheritanceAttr>()) {
if (RD && !RD->hasAttr<MSInheritanceAttr>()) {
// Lock in the inheritance model on the first use of a member pointer.
// Otherwise we may disagree about the size at different points in the TU.
// FIXME: MSVC picks a model on the first use that needs to know the size,
// rather than on the first mention of the type, e.g. typedefs.
if (RequireCompleteType(Loc, Class, 0) && RD && !RD->isBeingDefined()) {
if (RequireCompleteType(Loc, Class, 0) && !RD->isBeingDefined()) {
// We know it doesn't have an attribute and it's incomplete, so use the
// unspecified inheritance model. If we're in the record body, we can
// figure out the inheritance model.

Просмотреть файл

@ -132,3 +132,36 @@ struct MemPtrInBody {
};
static_assert(sizeof(MemPtrInBody::MemPtr) == kSingleDataSize, "");
// Passing a member pointer through a template should get the right size.
template<typename T>
struct SingleTemplate;
template<typename T>
struct SingleTemplate<void (T::*)(void)> {
static_assert(sizeof(int T::*) == kSingleDataSize, "");
static_assert(sizeof(void (T::*)()) == kSingleFunctionSize, "");
};
template<typename T>
struct UnspecTemplate;
template<typename T>
struct UnspecTemplate<void (T::*)(void)> {
static_assert(sizeof(int T::*) == kUnspecifiedDataSize, "");
static_assert(sizeof(void (T::*)()) == kUnspecifiedFunctionSize, "");
};
struct NewUnspecified;
SingleTemplate<void (IncSingle::*)()> tmpl_single;
UnspecTemplate<void (NewUnspecified::*)()> tmpl_unspec;
struct NewUnspecified { };
static_assert(sizeof(void (NewUnspecified::*)()) == kUnspecifiedFunctionSize, "");
template <typename T>
struct MemPtrInTemplate {
// We can't require that the template arg be complete until we're
// instantiated.
int T::*data_ptr;
void (T::*func_ptr)();
};