aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaType.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/Sema/SemaType.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/Sema/SemaType.cpp')
-rw-r--r--lib/Sema/SemaType.cpp57
1 files changed, 52 insertions, 5 deletions
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index ecae79320d..21db14a2ae 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -287,9 +287,9 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S, unsigned Skip) {
!T->isIncompleteOrObjectType()) {
Diag(DeclType.Loc, diag::err_typecheck_invalid_restrict_invalid_pointee)
<< T;
- DeclType.Ptr.TypeQuals &= QualType::Restrict;
- }
-
+ DeclType.Ptr.TypeQuals &= ~QualType::Restrict;
+ }
+
// Apply the pointer typequals to the pointer object.
T = Context.getPointerType(T).getQualifiedType(DeclType.Ptr.TypeQuals);
break;
@@ -424,7 +424,7 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S, unsigned Skip) {
}
break;
}
- case DeclaratorChunk::Function:
+ case DeclaratorChunk::Function: {
// If the function declarator has a prototype (i.e. it is not () and
// does not have a K&R-style identifier list), then the arguments are part
// of the type, otherwise the argument list is ().
@@ -518,7 +518,54 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S, unsigned Skip) {
}
break;
}
-
+ case DeclaratorChunk::MemberPointer:
+ // The scope spec must refer to a class, or be dependent.
+ DeclContext *DC = static_cast<DeclContext*>(
+ DeclType.Mem.Scope().getScopeRep());
+ QualType ClsType;
+ // FIXME: Extend for dependent types when it's actually supported.
+ // See ActOnCXXNestedNameSpecifier.
+ if (CXXRecordDecl *RD = dyn_cast_or_null<CXXRecordDecl>(DC)) {
+ ClsType = Context.getTagDeclType(RD);
+ } else {
+ if (DC) {
+ Diag(DeclType.Mem.Scope().getBeginLoc(),
+ diag::err_illegal_decl_mempointer_in_nonclass)
+ << (D.getIdentifier() ? D.getIdentifier()->getName() : "type name")
+ << DeclType.Mem.Scope().getRange();
+ }
+ D.setInvalidType(true);
+ ClsType = Context.IntTy;
+ }
+
+ // C++ 8.3.3p3: A pointer to member shall not pointer to ... a member
+ // with reference type, or "cv void."
+ if (T->isReferenceType()) {
+ Diag(DeclType.Loc, diag::err_illegal_decl_pointer_to_reference)
+ << (D.getIdentifier() ? D.getIdentifier()->getName() : "type name");
+ D.setInvalidType(true);
+ T = Context.IntTy;
+ }
+ if (T->isVoidType()) {
+ Diag(DeclType.Loc, diag::err_illegal_decl_mempointer_to_void)
+ << (D.getIdentifier() ? D.getIdentifier()->getName() : "type name");
+ T = Context.IntTy;
+ }
+
+ // Enforce C99 6.7.3p2: "Types other than pointer types derived from
+ // object or incomplete types shall not be restrict-qualified."
+ if ((DeclType.Mem.TypeQuals & QualType::Restrict) &&
+ !T->isIncompleteOrObjectType()) {
+ Diag(DeclType.Loc, diag::err_typecheck_invalid_restrict_invalid_pointee)
+ << T;
+ DeclType.Mem.TypeQuals &= ~QualType::Restrict;
+ }
+
+ T = Context.getMemberPointerType(T, ClsType.getTypePtr());
+
+ break;
+ }
+
// See if there are any attributes on this declarator chunk.
if (const AttributeList *AL = DeclType.getAttrs())
ProcessTypeAttributeList(T, AL);