aboutsummaryrefslogtreecommitdiff
path: root/lib/AST/ASTContext.cpp
diff options
context:
space:
mode:
authorSebastian Redl <sebastian.redl@getdesigned.at>2009-01-24 21:16:55 +0000
committerSebastian Redl <sebastian.redl@getdesigned.at>2009-01-24 21:16:55 +0000
commitf30208ad5b334e93582e846a2a0c92f38a607b8a (patch)
tree1fba65ee5418c5bcb3eeb1265aae50cffd6474f4 /lib/AST/ASTContext.cpp
parent91daf4da934e10dcbf22697d59e2791420b1507a (diff)
Add support for declaring pointers to members.
Add serialization support for ReferenceType. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@62934 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/ASTContext.cpp')
-rw-r--r--lib/AST/ASTContext.cpp51
1 files changed, 50 insertions, 1 deletions
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index d20387dd95..f3243c25ae 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -85,6 +85,7 @@ void ASTContext::PrintStats() const {
unsigned NumBuiltin = 0, NumPointer = 0, NumArray = 0, NumFunctionP = 0;
unsigned NumVector = 0, NumComplex = 0, NumBlockPointer = 0;
unsigned NumFunctionNP = 0, NumTypeName = 0, NumTagged = 0, NumReference = 0;
+ unsigned NumMemberPointer = 0;
unsigned NumTagStruct = 0, NumTagUnion = 0, NumTagEnum = 0, NumTagClass = 0;
unsigned NumObjCInterfaces = 0, NumObjCQualifiedInterfaces = 0;
@@ -101,6 +102,8 @@ void ASTContext::PrintStats() const {
++NumBlockPointer;
else if (isa<ReferenceType>(T))
++NumReference;
+ else if (isa<MemberPointerType>(T))
+ ++NumMemberPointer;
else if (isa<ComplexType>(T))
++NumComplex;
else if (isa<ArrayType>(T))
@@ -142,6 +145,7 @@ void ASTContext::PrintStats() const {
fprintf(stderr, " %d pointer types\n", NumPointer);
fprintf(stderr, " %d block pointer types\n", NumBlockPointer);
fprintf(stderr, " %d reference types\n", NumReference);
+ fprintf(stderr, " %d member pointer types\n", NumMemberPointer);
fprintf(stderr, " %d complex types\n", NumComplex);
fprintf(stderr, " %d array types\n", NumArray);
fprintf(stderr, " %d vector types\n", NumVector);
@@ -164,6 +168,7 @@ void ASTContext::PrintStats() const {
fprintf(stderr, "Total bytes = %d\n", int(NumBuiltin*sizeof(BuiltinType)+
NumPointer*sizeof(PointerType)+NumArray*sizeof(ArrayType)+
NumComplex*sizeof(ComplexType)+NumVector*sizeof(VectorType)+
+ NumMemberPointer*sizeof(MemberPointerType)+
NumFunctionP*sizeof(FunctionTypeProto)+
NumFunctionNP*sizeof(FunctionTypeNoProto)+
NumTypeName*sizeof(TypedefType)+NumTagged*sizeof(TagType)+
@@ -374,7 +379,19 @@ ASTContext::getTypeInfo(const Type *T) {
// FIXME: This is wrong for struct layout: a reference in a struct has
// pointer size.
return getTypeInfo(cast<ReferenceType>(T)->getPointeeType());
-
+ case Type::MemberPointer: {
+ // Note that this is not only platform- but also ABI-dependent. We follow
+ // the GCC ABI, where pointers to data are one pointer large, pointers to
+ // functions two pointers. But if we want to support ABI compatibility with
+ // other compilers too, we need to delegate this completely to TargetInfo.
+ QualType Pointee = cast<MemberPointerType>(T)->getPointeeType();
+ unsigned AS = Pointee.getAddressSpace();
+ Width = Target.getPointerWidth(AS);
+ if (Pointee->isFunctionType())
+ Width *= 2;
+ Align = Target.getPointerAlign(AS);
+ // GCC aligns at single pointer width.
+ }
case Type::Complex: {
// Complex types have the same alignment as their elements, but twice the
// size.
@@ -808,6 +825,38 @@ QualType ASTContext::getReferenceType(QualType T) {
return QualType(New, 0);
}
+/// getMemberPointerType - Return the uniqued reference to the type for a
+/// member pointer to the specified type, in the specified class.
+QualType ASTContext::getMemberPointerType(QualType T, const Type *Cls)
+{
+ // Unique pointers, to guarantee there is only one pointer of a particular
+ // structure.
+ llvm::FoldingSetNodeID ID;
+ MemberPointerType::Profile(ID, T, Cls);
+
+ void *InsertPos = 0;
+ if (MemberPointerType *PT =
+ MemberPointerTypes.FindNodeOrInsertPos(ID, InsertPos))
+ return QualType(PT, 0);
+
+ // If the pointee or class type isn't canonical, this won't be a canonical
+ // type either, so fill in the canonical type field.
+ QualType Canonical;
+ if (!T->isCanonical()) {
+ Canonical = getMemberPointerType(getCanonicalType(T),getCanonicalType(Cls));
+
+ // Get the new insert position for the node we care about.
+ MemberPointerType *NewIP =
+ MemberPointerTypes.FindNodeOrInsertPos(ID, InsertPos);
+ assert(NewIP == 0 && "Shouldn't be in the map!"); NewIP = NewIP;
+ }
+ void *Mem = Allocator.Allocate(sizeof(MemberPointerType), 8);
+ MemberPointerType *New = new (Mem) MemberPointerType(T, Cls, Canonical);
+ Types.push_back(New);
+ MemberPointerTypes.InsertNode(New, InsertPos);
+ return QualType(New, 0);
+}
+
/// getConstantArrayType - Return the unique reference to the type for an
/// array of the specified element type.
QualType ASTContext::getConstantArrayType(QualType EltTy,