r199475 - Revert r199416, "MS ABI: Improve selection of an inheritance model"
NAKAMURA Takumi
geek4civic at gmail.com
Thu Jan 16 23:33:47 PST 2014
Author: chapuni
Date: Fri Jan 17 01:33:47 2014
New Revision: 199475
URL: http://llvm.org/viewvc/llvm-project?rev=199475&view=rev
Log:
Revert r199416, "MS ABI: Improve selection of an inheritance model"
It broke tests for targeting x86_64-pc-win32:
Clang Tools :: clang-modernize/LoopConvert/array.cpp
Clang :: CodeGenCXX/2010-05-10-Var-DbgInfo.cpp
Clang :: CodeGenCXX/member-call-parens.cpp
Clang :: CodeGenCXX/ptr-to-datamember.cpp
Clang :: SemaTemplate/instantiate-function-1.cpp
Removed:
cfe/trunk/test/SemaCXX/microsoft-abi-ptm.cpp
Modified:
cfe/trunk/include/clang/AST/DeclCXX.h
cfe/trunk/include/clang/AST/Type.h
cfe/trunk/include/clang/Basic/Attr.td
cfe/trunk/lib/AST/MicrosoftCXXABI.cpp
cfe/trunk/lib/AST/Type.cpp
cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp
cfe/trunk/lib/Sema/SemaCast.cpp
cfe/trunk/lib/Sema/SemaType.cpp
Modified: cfe/trunk/include/clang/AST/DeclCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclCXX.h?rev=199475&r1=199474&r2=199475&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclCXX.h (original)
+++ cfe/trunk/include/clang/AST/DeclCXX.h Fri Jan 17 01:33:47 2014
@@ -17,7 +17,6 @@
#define LLVM_CLANG_AST_DECLCXX_H
#include "clang/AST/ASTUnresolvedSet.h"
-#include "clang/AST/Attr.h"
#include "clang/AST/Decl.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
@@ -259,6 +258,16 @@ public:
TypeSourceInfo *getTypeSourceInfo() const { return BaseTypeInfo; }
};
+/// The inheritance model to use for member pointers of a given CXXRecordDecl.
+enum MSInheritanceModel {
+ MSIM_Single,
+ MSIM_SinglePolymorphic,
+ MSIM_Multiple,
+ MSIM_MultiplePolymorphic,
+ MSIM_Virtual,
+ MSIM_Unspecified
+};
+
/// \brief Represents a C++ struct/union/class.
///
/// FIXME: This class will disappear once we've properly taught RecordDecl
@@ -1599,9 +1608,7 @@ public:
}
/// \brief Returns the inheritance model used for this record.
- MSInheritanceAttr::Spelling getMSInheritanceModel() const;
- /// \brief Locks-in the inheritance model for this class.
- void setMSInheritanceModel();
+ MSInheritanceModel getMSInheritanceModel() const;
/// \brief Determine whether this lambda expression was known to be dependent
/// at the time it was created, even if its context does not appear to be
Modified: cfe/trunk/include/clang/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=199475&r1=199474&r2=199475&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/trunk/include/clang/AST/Type.h Fri Jan 17 01:33:47 2014
@@ -2205,7 +2205,6 @@ public:
}
const Type *getClass() const { return Class; }
- CXXRecordDecl *getMostRecentCXXRecordDecl() const;
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
Modified: cfe/trunk/include/clang/Basic/Attr.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?rev=199475&r1=199474&r2=199475&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/Attr.td (original)
+++ cfe/trunk/include/clang/Basic/Attr.td Fri Jan 17 01:33:47 2014
@@ -1378,11 +1378,16 @@ def MSInheritance : InheritableAttr {
let Spellings = [Keyword<"__single_inheritance">,
Keyword<"__multiple_inheritance">,
Keyword<"__virtual_inheritance">,
- Keyword<"__unspecified_inheritance">];
+ // We use an empty string to denote an unspecified
+ // inheritance attribute.
+ Keyword<"">];
let Accessors = [Accessor<"IsSingle", [Keyword<"__single_inheritance">]>,
Accessor<"IsMultiple", [Keyword<"__multiple_inheritance">]>,
Accessor<"IsVirtual", [Keyword<"__virtual_inheritance">]>,
- Accessor<"IsUnspecified", [Keyword<"__unspecified_inheritance">]>];
+ Accessor<"IsUnspecified", [Keyword<"">]>];
+ // This index is based off the Spellings list and corresponds to the empty
+ // keyword "spelling."
+ let AdditionalMembers = [{static const int UnspecifiedSpellingIndex = 3;}];
}
def Unaligned : IgnoredAttr {
Modified: cfe/trunk/lib/AST/MicrosoftCXXABI.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/MicrosoftCXXABI.cpp?rev=199475&r1=199474&r2=199475&view=diff
==============================================================================
--- cfe/trunk/lib/AST/MicrosoftCXXABI.cpp (original)
+++ cfe/trunk/lib/AST/MicrosoftCXXABI.cpp Fri Jan 17 01:33:47 2014
@@ -92,43 +92,28 @@ static bool usesMultipleInheritanceModel
return false;
}
-static MSInheritanceAttr::Spelling
-MSInheritanceAttrToModel(const MSInheritanceAttr *Attr) {
+static MSInheritanceModel MSInheritanceAttrToModel(MSInheritanceAttr *Attr) {
if (Attr->IsSingle())
- return MSInheritanceAttr::Keyword_single_inheritance;
+ return MSIM_Single;
else if (Attr->IsMultiple())
- return MSInheritanceAttr::Keyword_multiple_inheritance;
+ return MSIM_Multiple;
else if (Attr->IsVirtual())
- return MSInheritanceAttr::Keyword_virtual_inheritance;
+ return MSIM_Virtual;
assert(Attr->IsUnspecified() && "Expected unspecified inheritance attr");
- return MSInheritanceAttr::Keyword_unspecified_inheritance;
+ return MSIM_Unspecified;
}
-static MSInheritanceAttr::Spelling
-calculateInheritanceModel(const CXXRecordDecl *RD) {
- if (!RD->hasDefinition())
- return MSInheritanceAttr::Keyword_unspecified_inheritance;
- if (RD->getNumVBases() > 0)
- return MSInheritanceAttr::Keyword_virtual_inheritance;
- if (usesMultipleInheritanceModel(RD))
- return MSInheritanceAttr::Keyword_multiple_inheritance;
- return MSInheritanceAttr::Keyword_single_inheritance;
-}
-
-MSInheritanceAttr::Spelling
-CXXRecordDecl::getMSInheritanceModel() const {
- MSInheritanceAttr *IA = getAttr<MSInheritanceAttr>();
- assert(IA && "Expected MSInheritanceAttr on the CXXRecordDecl!");
- return MSInheritanceAttrToModel(IA);
-}
-
-void CXXRecordDecl::setMSInheritanceModel() {
- if (hasAttr<MSInheritanceAttr>())
- return;
-
- addAttr(MSInheritanceAttr::CreateImplicit(
- getASTContext(), calculateInheritanceModel(this), getSourceRange()));
+MSInheritanceModel CXXRecordDecl::getMSInheritanceModel() const {
+ if (MSInheritanceAttr *IA = this->getAttr<MSInheritanceAttr>())
+ return MSInheritanceAttrToModel(IA);
+ // If there was no explicit attribute, the record must be defined already, and
+ // we can figure out the inheritance model from its other properties.
+ if (this->getNumVBases() > 0)
+ return MSIM_Virtual;
+ if (usesMultipleInheritanceModel(this))
+ return this->isPolymorphic() ? MSIM_MultiplePolymorphic : MSIM_Multiple;
+ return this->isPolymorphic() ? MSIM_SinglePolymorphic : MSIM_Single;
}
// Returns the number of pointer and integer slots used to represent a member
@@ -161,9 +146,9 @@ void CXXRecordDecl::setMSInheritanceMode
// };
static std::pair<unsigned, unsigned>
getMSMemberPointerSlots(const MemberPointerType *MPT) {
- const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
- MSInheritanceAttr::Spelling Inheritance = RD->getMSInheritanceModel();
- unsigned Ptrs = 0;
+ const CXXRecordDecl *RD = MPT->getClass()->getAsCXXRecordDecl();
+ MSInheritanceModel Inheritance = RD->getMSInheritanceModel();
+ unsigned Ptrs;
unsigned Ints = 0;
if (MPT->isMemberFunctionPointer()) {
// Member function pointers are a struct of a function pointer followed by a
@@ -171,29 +156,26 @@ getMSMemberPointerSlots(const MemberPoin
// function pointer is a real function if it is non-virtual and a vftable
// slot thunk if it is virtual. The ints select the object base passed for
// the 'this' pointer.
- Ptrs = 1; // First slot is always a function pointer.
+ Ptrs = 1; // First slot is always a function pointer.
switch (Inheritance) {
- case MSInheritanceAttr::Keyword_unspecified_inheritance:
- ++Ints; // VBTableOffset
- case MSInheritanceAttr::Keyword_virtual_inheritance:
- ++Ints; // VirtualBaseAdjustmentOffset
- case MSInheritanceAttr::Keyword_multiple_inheritance:
- ++Ints; // NonVirtualBaseAdjustment
- case MSInheritanceAttr::Keyword_single_inheritance:
- break; // Nothing
+ case MSIM_Unspecified: ++Ints; // VBTableOffset
+ case MSIM_Virtual: ++Ints; // VirtualBaseAdjustmentOffset
+ case MSIM_MultiplePolymorphic:
+ case MSIM_Multiple: ++Ints; // NonVirtualBaseAdjustment
+ case MSIM_SinglePolymorphic:
+ case MSIM_Single: break; // Nothing
}
} else {
// Data pointers are an aggregate of ints. The first int is an offset
// followed by vbtable-related offsets.
- Ints = 1; // We always have a field offset.
+ Ptrs = 0;
switch (Inheritance) {
- case MSInheritanceAttr::Keyword_unspecified_inheritance:
- ++Ints; // VBTableOffset
- case MSInheritanceAttr::Keyword_virtual_inheritance:
- ++Ints; // VirtualBaseAdjustmentOffset
- case MSInheritanceAttr::Keyword_multiple_inheritance:
- case MSInheritanceAttr::Keyword_single_inheritance:
- break; // Nothing
+ case MSIM_Unspecified: ++Ints; // VBTableOffset
+ case MSIM_Virtual: ++Ints; // VirtualBaseAdjustmentOffset
+ case MSIM_MultiplePolymorphic:
+ case MSIM_Multiple: // Nothing
+ case MSIM_SinglePolymorphic:
+ case MSIM_Single: ++Ints; // Field offset
}
}
return std::make_pair(Ptrs, Ints);
Modified: cfe/trunk/lib/AST/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Type.cpp?rev=199475&r1=199474&r2=199475&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Type.cpp (original)
+++ cfe/trunk/lib/AST/Type.cpp Fri Jan 17 01:33:47 2014
@@ -2469,7 +2469,3 @@ QualType::DestructionKind QualType::isDe
return DK_none;
}
-
-CXXRecordDecl *MemberPointerType::getMostRecentCXXRecordDecl() const {
- return getClass()->getAsCXXRecordDecl()->getMostRecentDecl();
-}
Modified: cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp?rev=199475&r1=199474&r2=199475&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp (original)
+++ cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp Fri Jan 17 01:33:47 2014
@@ -1322,29 +1322,25 @@ void MicrosoftCXXABI::EmitGuardedInit(Co
}
// Member pointer helpers.
-static bool hasVBPtrOffsetField(MSInheritanceAttr::Spelling Inheritance) {
- return Inheritance == MSInheritanceAttr::Keyword_unspecified_inheritance;
+static bool hasVBPtrOffsetField(MSInheritanceModel Inheritance) {
+ return Inheritance == MSIM_Unspecified;
}
static bool hasOnlyOneField(bool IsMemberFunction,
- MSInheritanceAttr::Spelling Inheritance) {
- if (IsMemberFunction)
- return Inheritance <= MSInheritanceAttr::Keyword_single_inheritance;
- return Inheritance <= MSInheritanceAttr::Keyword_multiple_inheritance;
+ MSInheritanceModel Inheritance) {
+ return Inheritance <= MSIM_SinglePolymorphic ||
+ (!IsMemberFunction && Inheritance <= MSIM_MultiplePolymorphic);
}
// Only member pointers to functions need a this adjustment, since it can be
// combined with the field offset for data pointers.
-static bool
-hasNonVirtualBaseAdjustmentField(bool IsMemberFunction,
- MSInheritanceAttr::Spelling Inheritance) {
- return IsMemberFunction &&
- Inheritance >= MSInheritanceAttr::Keyword_multiple_inheritance;
+static bool hasNonVirtualBaseAdjustmentField(bool IsMemberFunction,
+ MSInheritanceModel Inheritance) {
+ return (IsMemberFunction && Inheritance >= MSIM_Multiple);
}
-static bool
-hasVirtualBaseAdjustmentField(MSInheritanceAttr::Spelling Inheritance) {
- return Inheritance >= MSInheritanceAttr::Keyword_virtual_inheritance;
+static bool hasVirtualBaseAdjustmentField(MSInheritanceModel Inheritance) {
+ return Inheritance >= MSIM_Virtual;
}
// Use zero for the field offset of a null data member pointer if we can
@@ -1353,10 +1349,8 @@ hasVirtualBaseAdjustmentField(MSInherita
// use zero for null. If there are multiple fields, we can use zero even if it
// is a valid field offset because null-ness testing will check the other
// fields.
-static bool nullFieldOffsetIsZero(const CXXRecordDecl *RD) {
- return RD->getMSInheritanceModel() >=
- MSInheritanceAttr::Keyword_virtual_inheritance ||
- (RD->hasDefinition() && RD->isPolymorphic());
+static bool nullFieldOffsetIsZero(MSInheritanceModel Inheritance) {
+ return Inheritance != MSIM_Multiple && Inheritance != MSIM_Single;
}
bool MicrosoftCXXABI::isZeroInitializable(const MemberPointerType *MPT) {
@@ -1368,16 +1362,16 @@ bool MicrosoftCXXABI::isZeroInitializabl
// The virtual base adjustment field is always -1 for null, so if we have one
// we can't zero initialize. The field offset is sometimes also -1 if 0 is a
// valid field offset.
- const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
- MSInheritanceAttr::Spelling Inheritance = RD->getMSInheritanceModel();
+ const CXXRecordDecl *RD = MPT->getClass()->getAsCXXRecordDecl();
+ MSInheritanceModel Inheritance = RD->getMSInheritanceModel();
return (!hasVirtualBaseAdjustmentField(Inheritance) &&
- nullFieldOffsetIsZero(RD));
+ nullFieldOffsetIsZero(Inheritance));
}
llvm::Type *
MicrosoftCXXABI::ConvertMemberPointerType(const MemberPointerType *MPT) {
- const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
- MSInheritanceAttr::Spelling Inheritance = RD->getMSInheritanceModel();
+ const CXXRecordDecl *RD = MPT->getClass()->getAsCXXRecordDecl();
+ MSInheritanceModel Inheritance = RD->getMSInheritanceModel();
llvm::SmallVector<llvm::Type *, 4> fields;
if (MPT->isMemberFunctionPointer())
fields.push_back(CGM.VoidPtrTy); // FunctionPointerOrVirtualThunk
@@ -1401,13 +1395,13 @@ void MicrosoftCXXABI::
GetNullMemberPointerFields(const MemberPointerType *MPT,
llvm::SmallVectorImpl<llvm::Constant *> &fields) {
assert(fields.empty());
- const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
- MSInheritanceAttr::Spelling Inheritance = RD->getMSInheritanceModel();
+ const CXXRecordDecl *RD = MPT->getClass()->getAsCXXRecordDecl();
+ MSInheritanceModel Inheritance = RD->getMSInheritanceModel();
if (MPT->isMemberFunctionPointer()) {
// FunctionPointerOrVirtualThunk
fields.push_back(llvm::Constant::getNullValue(CGM.VoidPtrTy));
} else {
- if (nullFieldOffsetIsZero(RD))
+ if (nullFieldOffsetIsZero(Inheritance))
fields.push_back(getZeroInt()); // FieldOffset
else
fields.push_back(getAllOnesInt()); // FieldOffset
@@ -1439,7 +1433,7 @@ MicrosoftCXXABI::EmitFullMemberPointer(l
const CXXRecordDecl *RD,
CharUnits NonVirtualBaseAdjustment)
{
- MSInheritanceAttr::Spelling Inheritance = RD->getMSInheritanceModel();
+ MSInheritanceModel Inheritance = RD->getMSInheritanceModel();
// Single inheritance class member pointer are represented as scalars instead
// of aggregates.
@@ -1470,7 +1464,7 @@ MicrosoftCXXABI::EmitFullMemberPointer(l
llvm::Constant *
MicrosoftCXXABI::EmitMemberDataPointer(const MemberPointerType *MPT,
CharUnits offset) {
- const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
+ const CXXRecordDecl *RD = MPT->getClass()->getAsCXXRecordDecl();
llvm::Constant *FirstField =
llvm::ConstantInt::get(CGM.IntTy, offset.getQuantity());
return EmitFullMemberPointer(FirstField, /*IsMemberFunction=*/false, RD,
@@ -1493,8 +1487,8 @@ llvm::Constant *MicrosoftCXXABI::EmitMem
// FIXME PR15713: Support virtual inheritance paths.
if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(MPD))
- return BuildMemberPointer(MPT->getMostRecentCXXRecordDecl(), MD,
- ThisAdjustment);
+ return BuildMemberPointer(MPT->getClass()->getAsCXXRecordDecl(),
+ MD, ThisAdjustment);
CharUnits FieldOffset =
getContext().toCharUnitsFromBits(getContext().getFieldOffset(MPD));
@@ -1507,7 +1501,6 @@ MicrosoftCXXABI::BuildMemberPointer(cons
CharUnits NonVirtualBaseAdjustment) {
assert(MD->isInstance() && "Member function must not be static!");
MD = MD->getCanonicalDecl();
- RD = RD->getMostRecentDecl();
CodeGenTypes &Types = CGM.getTypes();
llvm::Constant *FirstField;
@@ -1585,8 +1578,8 @@ MicrosoftCXXABI::EmitMemberPointerCompar
// If this is a single field member pointer (single inheritance), this is a
// single icmp.
- const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
- MSInheritanceAttr::Spelling Inheritance = RD->getMSInheritanceModel();
+ const CXXRecordDecl *RD = MPT->getClass()->getAsCXXRecordDecl();
+ MSInheritanceModel Inheritance = RD->getMSInheritanceModel();
if (hasOnlyOneField(MPT->isMemberFunctionPointer(), Inheritance))
return Builder.CreateICmp(Eq, L, R);
@@ -1767,8 +1760,8 @@ MicrosoftCXXABI::EmitMemberDataPointerAd
llvm::Type *PType =
CGF.ConvertTypeForMem(MPT->getPointeeType())->getPointerTo(AS);
CGBuilderTy &Builder = CGF.Builder;
- const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
- MSInheritanceAttr::Spelling Inheritance = RD->getMSInheritanceModel();
+ const CXXRecordDecl *RD = MPT->getClass()->getAsCXXRecordDecl();
+ MSInheritanceModel Inheritance = RD->getMSInheritanceModel();
// Extract the fields we need, regardless of model. We'll apply them if we
// have them.
@@ -1802,9 +1795,9 @@ MicrosoftCXXABI::EmitMemberDataPointerAd
return Builder.CreateBitCast(Addr, PType);
}
-static MSInheritanceAttr::Spelling
+static MSInheritanceModel
getInheritanceFromMemptr(const MemberPointerType *MPT) {
- return MPT->getMostRecentCXXRecordDecl()->getMSInheritanceModel();
+ return MPT->getClass()->getAsCXXRecordDecl()->getMSInheritanceModel();
}
llvm::Value *
@@ -1824,17 +1817,15 @@ MicrosoftCXXABI::EmitMemberPointerConver
const MemberPointerType *SrcTy =
E->getSubExpr()->getType()->castAs<MemberPointerType>();
const MemberPointerType *DstTy = E->getType()->castAs<MemberPointerType>();
+ MSInheritanceModel SrcInheritance = getInheritanceFromMemptr(SrcTy);
+ MSInheritanceModel DstInheritance = getInheritanceFromMemptr(DstTy);
bool IsFunc = SrcTy->isMemberFunctionPointer();
// If the classes use the same null representation, reinterpret_cast is a nop.
bool IsReinterpret = E->getCastKind() == CK_ReinterpretMemberPointer;
- if (IsReinterpret && IsFunc)
- return Src;
-
- CXXRecordDecl *SrcRD = SrcTy->getMostRecentCXXRecordDecl();
- CXXRecordDecl *DstRD = DstTy->getMostRecentCXXRecordDecl();
- if (IsReinterpret &&
- nullFieldOffsetIsZero(SrcRD) == nullFieldOffsetIsZero(DstRD))
+ if (IsReinterpret && (IsFunc ||
+ nullFieldOffsetIsZero(SrcInheritance) ==
+ nullFieldOffsetIsZero(DstInheritance)))
return Src;
CGBuilderTy &Builder = CGF.Builder;
@@ -1863,7 +1854,6 @@ MicrosoftCXXABI::EmitMemberPointerConver
llvm::Value *NonVirtualBaseAdjustment = 0;
llvm::Value *VirtualBaseAdjustmentOffset = 0;
llvm::Value *VBPtrOffset = 0;
- MSInheritanceAttr::Spelling SrcInheritance = SrcRD->getMSInheritanceModel();
if (!hasOnlyOneField(IsFunc, SrcInheritance)) {
// We need to extract values.
unsigned I = 0;
@@ -1894,7 +1884,6 @@ MicrosoftCXXABI::EmitMemberPointerConver
// FIXME PR15713: Support conversions through virtually derived classes.
// Recompose dst from the null struct and the adjusted fields from src.
- MSInheritanceAttr::Spelling DstInheritance = DstRD->getMSInheritanceModel();
llvm::Value *Dst;
if (hasOnlyOneField(IsFunc, DstInheritance)) {
Dst = FirstField;
@@ -1940,8 +1929,8 @@ MicrosoftCXXABI::EmitMemberPointerConver
if (E->getCastKind() == CK_ReinterpretMemberPointer)
return Src;
- MSInheritanceAttr::Spelling SrcInheritance = getInheritanceFromMemptr(SrcTy);
- MSInheritanceAttr::Spelling DstInheritance = getInheritanceFromMemptr(DstTy);
+ MSInheritanceModel SrcInheritance = getInheritanceFromMemptr(SrcTy);
+ MSInheritanceModel DstInheritance = getInheritanceFromMemptr(DstTy);
// Decompose src.
llvm::Constant *FirstField = Src;
@@ -2002,13 +1991,13 @@ MicrosoftCXXABI::EmitLoadOfMemberFunctio
assert(MPT->isMemberFunctionPointer());
const FunctionProtoType *FPT =
MPT->getPointeeType()->castAs<FunctionProtoType>();
- const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
+ const CXXRecordDecl *RD = MPT->getClass()->getAsCXXRecordDecl();
llvm::FunctionType *FTy =
CGM.getTypes().GetFunctionType(
CGM.getTypes().arrangeCXXMethodType(RD, FPT));
CGBuilderTy &Builder = CGF.Builder;
- MSInheritanceAttr::Spelling Inheritance = RD->getMSInheritanceModel();
+ MSInheritanceModel Inheritance = RD->getMSInheritanceModel();
// Extract the fields we need, regardless of model. We'll apply them if we
// have them.
Modified: cfe/trunk/lib/Sema/SemaCast.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCast.cpp?rev=199475&r1=199474&r2=199475&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaCast.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCast.cpp Fri Jan 17 01:33:47 2014
@@ -21,7 +21,6 @@
#include "clang/AST/ExprObjC.h"
#include "clang/AST/RecordLayout.h"
#include "clang/Basic/PartialDiagnostic.h"
-#include "clang/Basic/TargetInfo.h"
#include "clang/Sema/Initialization.h"
#include "llvm/ADT/SmallVector.h"
#include <set>
@@ -1780,13 +1779,6 @@ static TryCastResult TryReinterpretCast(
return TC_Failed;
}
- if (Self.Context.getTargetInfo().getCXXABI().isMicrosoft()) {
- // We need to determine the inheritance model that the class will use if
- // haven't yet.
- Self.RequireCompleteType(OpRange.getBegin(), SrcType, 0);
- Self.RequireCompleteType(OpRange.getBegin(), DestType, 0);
- }
-
// Don't allow casting between member pointers of different sizes.
if (Self.Context.getTypeSize(DestMemPtr) !=
Self.Context.getTypeSize(SrcMemPtr)) {
Modified: cfe/trunk/lib/Sema/SemaType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=199475&r1=199474&r2=199475&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaType.cpp (original)
+++ cfe/trunk/lib/Sema/SemaType.cpp Fri Jan 17 01:33:47 2014
@@ -1753,6 +1753,35 @@ QualType Sema::BuildMemberPointerType(Qu
return QualType();
}
+ // C++ allows the class type in a member pointer to be an incomplete type.
+ // In the Microsoft ABI, the size of the member pointer can vary
+ // according to the class type, which means that we really need a
+ // complete type if possible, which means we need to instantiate templates.
+ //
+ // If template instantiation fails or the type is just incomplete, we have to
+ // add an extra slot to the member pointer. Yes, this does cause problems
+ // when passing pointers between TUs that disagree about the size.
+ if (Context.getTargetInfo().getCXXABI().isMicrosoft()) {
+ CXXRecordDecl *RD = Class->getAsCXXRecordDecl();
+ 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->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.
+ for (CXXRecordDecl::redecl_iterator I = RD->redecls_begin(),
+ E = RD->redecls_end(); I != E; ++I) {
+ I->addAttr(::new (Context) MSInheritanceAttr(RD->getSourceRange(),
+ Context,
+ MSInheritanceAttr::UnspecifiedSpellingIndex));
+ }
+ }
+ }
+ }
+
// Adjust the default free function calling convention to the default method
// calling convention.
if (T->isFunctionType())
@@ -5067,18 +5096,6 @@ bool Sema::RequireCompleteTypeImpl(Sourc
}
}
- // We lock in the inheritance model once somebody has asked us to ensure
- // that a pointer-to-member type is complete.
- if (Context.getTargetInfo().getCXXABI().isMicrosoft()) {
- if (const MemberPointerType *MPTy = T->getAs<MemberPointerType>()) {
- if (!MPTy->getClass()->isDependentType()) {
- RequireCompleteType(Loc, QualType(MPTy->getClass(), 0), 0);
-
- MPTy->getMostRecentCXXRecordDecl()->setMSInheritanceModel();
- }
- }
- }
-
return false;
}
Removed: cfe/trunk/test/SemaCXX/microsoft-abi-ptm.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/microsoft-abi-ptm.cpp?rev=199474&view=auto
==============================================================================
--- cfe/trunk/test/SemaCXX/microsoft-abi-ptm.cpp (original)
+++ cfe/trunk/test/SemaCXX/microsoft-abi-ptm.cpp (removed)
@@ -1,24 +0,0 @@
-// RUN: %clang_cc1 -triple %ms_abi_triple -std=c++11 -fsyntax-only -fms-extensions -fms-compatibility %s
-
-namespace Test1 {
-struct A;
-void f(int A::*mp);
-struct A { };
-static_assert(sizeof(int A::*) == sizeof(int), "pointer-to-member should be sizeof(int)");
-}
-
-namespace Test2 {
-struct A;
-void f(int A::*mp);
-static_assert(sizeof(int A::*) == sizeof(int) * 3, "pointer-to-member should be sizeof(int) * 3");
-struct A { };
-static_assert(sizeof(int A::*) == sizeof(int) * 3, "pointer-to-member should still be sizeof(int) * 3");
-}
-
-namespace Test3 {
-struct A;
-typedef int A::*p;
-struct __single_inheritance A;
-p my_ptr;
-static_assert(sizeof(int A::*) == sizeof(int), "pointer-to-member should be sizeof(int)");
-}
More information about the cfe-commits
mailing list