From 67ef8eaea8a0a2073147a8d863f0e3f30d525802 Mon Sep 17 00:00:00 2001 From: Steve Naroff Date: Mon, 20 Jul 2009 17:56:53 +0000 Subject: [PATCH] 5 cleanups to ObjCObjectPointerType work: - Remove Sema::CheckPointeeTypesForAssignment(), a temporary API I added to ease migration to ObjCObjectPointerType. Convert Sema::CheckAssignmentConstraints() to no longer depend on the temporary API. - Sema::ConvertDeclSpecToType(): Replace a couple FIXME's with an important comment/example. - Sema::GetTypeForDeclarator(): Get the protocol's from the interface, NOT the declspec (to support the following C typedef idiom: "typedef C

T; T *obj"). - Sema::ObjCQualifiedIdTypesAreCompatible(): Removed some dead code. - ASTContext::getObjCEncodingForTypeImpl(): Some minor cleanups. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@76443 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/AST/ASTContext.cpp | 13 +++++-------- lib/Sema/Sema.h | 2 -- lib/Sema/SemaExpr.cpp | 40 ++++++++++++++++++--------------------- lib/Sema/SemaExprObjC.cpp | 28 --------------------------- lib/Sema/SemaType.cpp | 20 ++++++++++++-------- 5 files changed, 35 insertions(+), 68 deletions(-) diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 680ec24eff..05627b47eb 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -2758,10 +2758,9 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S, if (FD || EncodingProperty) { // Note that we do extended encoding of protocol qualifer list // Only when doing ivar or property encoding. - const ObjCObjectPointerType *QIDT = T->getAsObjCQualifiedIdType(); S += '"'; - for (ObjCObjectPointerType::qual_iterator I = QIDT->qual_begin(), - E = QIDT->qual_end(); I != E; ++I) { + for (ObjCObjectPointerType::qual_iterator I = OPT->qual_begin(), + E = OPT->qual_end(); I != E; ++I) { S += '<'; S += (*I)->getNameAsString(); S += '>'; @@ -2786,12 +2785,10 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S, S += '@'; if (FD || EncodingProperty) { - const ObjCInterfaceType *OIT = OPT->getInterfaceType(); - ObjCInterfaceDecl *OI = OIT->getDecl(); S += '"'; - S += OI->getNameAsCString(); - for (ObjCInterfaceType::qual_iterator I = OIT->qual_begin(), - E = OIT->qual_end(); I != E; ++I) { + S += OPT->getInterfaceDecl()->getNameAsCString(); + for (ObjCObjectPointerType::qual_iterator I = OPT->qual_begin(), + E = OPT->qual_end(); I != E; ++I) { S += '<'; S += (*I)->getNameAsString(); S += '>'; diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index 82a8a087d9..837b2c8fec 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -3033,8 +3033,6 @@ public: // Helper function for CheckAssignmentConstraints (C99 6.5.16.1p1) AssignConvertType CheckPointerTypesForAssignment(QualType lhsType, QualType rhsType); - AssignConvertType CheckPointeeTypesForAssignment(QualType lhsType, - QualType rhsType); // Helper function for CheckAssignmentConstraints involving two // block pointer types. diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 35c0ddb06d..7aa66f9b62 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -2398,8 +2398,8 @@ Sema::ActOnMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc, MemberLoc, BaseExpr)); } // Check protocols on qualified interfaces. - for (ObjCObjectPointerType::qual_iterator I = IFaceT->qual_begin(), - E = IFaceT->qual_end(); I != E; ++I) + for (ObjCObjectPointerType::qual_iterator I = OPT->qual_begin(), + E = OPT->qual_end(); I != E; ++I) if (ObjCPropertyDecl *PD = (*I)->FindPropertyDeclaration(&Member)) { // Check whether we can reference this property. if (DiagnoseUseOfDecl(PD, MemberLoc)) @@ -3303,7 +3303,6 @@ Action::OwningExprResult Sema::ActOnConditionalOp(SourceLocation QuestionLoc, RHSExpr, result)); } - // CheckPointerTypesForAssignment - This is a very tricky routine (despite // being closely modeled after the C99 spec:-). The odd characteristic of this // routine is it effectively iqnores the qualifiers on the top level pointee. @@ -3317,11 +3316,6 @@ Sema::CheckPointerTypesForAssignment(QualType lhsType, QualType rhsType) { lhptee = lhsType->getAsPointerType()->getPointeeType(); rhptee = rhsType->getAsPointerType()->getPointeeType(); - return CheckPointeeTypesForAssignment(lhptee, rhptee); -} - -Sema::AssignConvertType -Sema::CheckPointeeTypesForAssignment(QualType lhptee, QualType rhptee) { // make sure we operate on the canonical type lhptee = Context.getCanonicalType(lhptee); rhptee = Context.getCanonicalType(rhptee); @@ -3495,12 +3489,12 @@ Sema::CheckAssignmentConstraints(QualType lhsType, QualType rhsType) { if (isa(rhsType)) return CheckPointerTypesForAssignment(lhsType, rhsType); + // In general, C pointers are not compatible with ObjC object pointers. if (isa(rhsType)) { - QualType rhptee = rhsType->getAsObjCObjectPointerType()->getPointeeType(); - QualType lhptee = lhsType->getAsPointerType()->getPointeeType(); - return CheckPointeeTypesForAssignment(lhptee, rhptee); + if (lhsType->isVoidPointerType()) // an exception to the rule. + return Compatible; + return IncompatiblePointer; } - if (rhsType->getAsBlockPointerType()) { if (lhsType->getAsPointerType()->getPointeeType()->isVoidType()) return Compatible; @@ -3533,18 +3527,19 @@ Sema::CheckAssignmentConstraints(QualType lhsType, QualType rhsType) { if (isa(lhsType)) { if (rhsType->isIntegerType()) return IntToPointer; - + + // In general, C pointers are not compatible with ObjC object pointers. if (isa(rhsType)) { - QualType lhptee = lhsType->getAsObjCObjectPointerType()->getPointeeType(); - QualType rhptee = rhsType->getAsPointerType()->getPointeeType(); - return CheckPointeeTypesForAssignment(lhptee, rhptee); + if (rhsType->isVoidPointerType()) // an exception to the rule. + return Compatible; + return IncompatiblePointer; } if (rhsType->isObjCObjectPointerType()) { if (lhsType->isObjCBuiltinType() || rhsType->isObjCBuiltinType()) return Compatible; - QualType lhptee = lhsType->getAsObjCObjectPointerType()->getPointeeType(); - QualType rhptee = rhsType->getAsObjCObjectPointerType()->getPointeeType(); - return CheckPointeeTypesForAssignment(lhptee, rhptee); + if (Context.typesAreCompatible(lhsType, rhsType)) + return Compatible; + return IncompatiblePointer; } if (const PointerType *RHSPT = rhsType->getAsPointerType()) { if (RHSPT->getPointeeType()->isVoidType()) @@ -3579,10 +3574,11 @@ Sema::CheckAssignmentConstraints(QualType lhsType, QualType rhsType) { if (lhsType->isIntegerType()) return PointerToInt; + // In general, C pointers are not compatible with ObjC object pointers. if (isa(lhsType)) { - QualType rhptee = lhsType->getAsObjCObjectPointerType()->getPointeeType(); - QualType lhptee = rhsType->getAsPointerType()->getPointeeType(); - return CheckPointeeTypesForAssignment(lhptee, rhptee); + if (lhsType->isVoidPointerType()) // an exception to the rule. + return Compatible; + return IncompatiblePointer; } if (isa(lhsType) && rhsType->getAsPointerType()->getPointeeType()->isVoidType()) diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp index 1d995b53e6..66e1beb983 100644 --- a/lib/Sema/SemaExprObjC.cpp +++ b/lib/Sema/SemaExprObjC.cpp @@ -854,34 +854,6 @@ bool Sema::ObjCQualifiedIdTypesAreCompatible(QualType lhs, QualType rhs, } return true; } - // FIXME: The code below will be removed when ObjCQualifiedInterfaceType is - // removed. - if (!lhs->isPointerType()) - return false; - - QualType ltype = lhs->getAsPointerType()->getPointeeType(); - if (const ObjCInterfaceType *lhsQI = - ltype->getAsObjCQualifiedInterfaceType()) { - ObjCObjectPointerType::qual_iterator LHSProtoI = lhsQI->qual_begin(); - ObjCObjectPointerType::qual_iterator LHSProtoE = lhsQI->qual_end(); - for (; LHSProtoI != LHSProtoE; ++LHSProtoI) { - bool match = false; - ObjCProtocolDecl *lhsProto = *LHSProtoI; - for (ObjCObjectPointerType::qual_iterator I = rhsQID->qual_begin(), - E = rhsQID->qual_end(); I != E; ++I) { - ObjCProtocolDecl *rhsProto = *I; - if (ProtocolCompatibleWithProtocol(lhsProto, rhsProto) || - (compare && ProtocolCompatibleWithProtocol(rhsProto, lhsProto))) { - match = true; - break; - } - } - if (!match) - return false; - } - return true; - } - return false; } diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp index 57989a021b..5fbc8e813b 100644 --- a/lib/Sema/SemaType.cpp +++ b/lib/Sema/SemaType.cpp @@ -205,12 +205,16 @@ QualType Sema::ConvertDeclSpecToType(const DeclSpec &DS, Result = QualType::getFromOpaquePtr(DS.getTypeRep()); if (DeclSpec::ProtocolQualifierListTy PQ = DS.getProtocolQualifiers()) { - // FIXME: Adding a TST_objcInterface clause doesn't seem ideal, so we have - // this "hack" for now... if (const ObjCInterfaceType *Interface = Result->getAsObjCInterfaceType()) - // FIXME: Investigate removing the protocol list in ObjCInterfaceType. - // To simply this, Sema::GetTypeForDeclarator() uses the declspec - // protocol list, not the list we are storing here. + // It would be nice if protocol qualifiers were only stored with the + // ObjCObjectPointerType. Unfortunately, this isn't possible due + // to the following typedef idiom (which is uncommon, but allowed): + // + // typedef Foo

T; + // static void func() { + // Foo

*yy; + // T *zz; + // } Result = Context.getObjCInterfaceType(Interface->getDecl(), (ObjCProtocolDecl**)PQ, DS.getNumProtocolQualifiers()); @@ -901,10 +905,10 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S, unsigned Skip, // Build the type anyway. } if (getLangOptions().ObjC1 && T->isObjCInterfaceType()) { - const DeclSpec &DS = D.getDeclSpec(); + const ObjCInterfaceType *OIT = T->getAsObjCInterfaceType(); T = Context.getObjCObjectPointerType(T, - (ObjCProtocolDecl **)DS.getProtocolQualifiers(), - DS.getNumProtocolQualifiers()); + (ObjCProtocolDecl **)OIT->qual_begin(), + OIT->getNumProtocols()); break; } T = BuildPointerType(T, DeclType.Ptr.TypeQuals, DeclType.Loc, Name); -- 2.40.0