From: Steve Naroff Date: Sat, 21 Feb 2009 21:17:01 +0000 (+0000) Subject: More work to integrate newly added ObjCQualifiedClassType into the type system. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f7f52e7bf5a4dc36d45b98531e0b21e343fc19de;p=clang More work to integrate newly added ObjCQualifiedClassType into the type system. This is necessary 'plumbing' to fix Message lookup is sometimes different than gcc's. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@65248 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h index 5dc2c31107..cb34c77f1a 100644 --- a/include/clang/AST/Type.h +++ b/include/clang/AST/Type.h @@ -270,7 +270,7 @@ public: TypeName, Tagged, ExtQual, TemplateTypeParm, ClassTemplateSpecialization, ObjCInterface, ObjCQualifiedInterface, - ObjCQualifiedId, + ObjCQualifiedId, ObjCQualifiedClass, TypeOfExp, TypeOfTyp, // GNU typeof extension. BlockPointer, // C extension FixedWidthInt @@ -1758,7 +1758,7 @@ class ObjCQualifiedClassType : public Type, llvm::SmallVector Protocols; ObjCQualifiedClassType(ObjCProtocolDecl **Protos, unsigned NumP) - : Type(ObjCQualifiedId, QualType()/*these are always canonical*/, + : Type(ObjCQualifiedClass, QualType()/*these are always canonical*/, /*Dependent=*/false), Protocols(Protos, Protos+NumP) { } friend class ASTContext; // ASTContext creates these. @@ -1785,7 +1785,7 @@ public: ObjCProtocolDecl **protocols, unsigned NumProtocols); static bool classof(const Type *T) { - return T->getTypeClass() == ObjCQualifiedId; + return T->getTypeClass() == ObjCQualifiedClass; } static bool classof(const ObjCQualifiedClassType *) { return true; } diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index cdd61cd3f4..605f46b44b 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -2408,7 +2408,7 @@ bool ASTContext::isObjCNSObjectType(QualType Ty) const { /// to struct), Interface* (pointer to ObjCInterfaceType) and id

(qualified /// ID type). bool ASTContext::isObjCObjectPointerType(QualType Ty) const { - if (Ty->isObjCQualifiedIdType()) + if (Ty->isObjCQualifiedIdType() || Ty->isObjCQualifiedClassType()) return true; // Blocks are objects. diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp index ba8b463c27..065b626930 100644 --- a/lib/AST/Type.cpp +++ b/lib/AST/Type.cpp @@ -693,7 +693,8 @@ bool Type::isScalarType() const { isa(CanonicalType) || isa(CanonicalType) || isa(CanonicalType) || - isa(CanonicalType); + isa(CanonicalType) || + isa(CanonicalType); } /// \brief Determines whether the type is a C++ aggregate type or C diff --git a/lib/CodeGen/CodeGenTypes.cpp b/lib/CodeGen/CodeGenTypes.cpp index a385d8c9d2..47ac79f70b 100644 --- a/lib/CodeGen/CodeGenTypes.cpp +++ b/lib/CodeGen/CodeGenTypes.cpp @@ -290,6 +290,7 @@ const llvm::Type *CodeGenTypes::ConvertNewType(QualType T) { } case Type::ObjCQualifiedId: + case Type::ObjCQualifiedClass: // Protocols don't influence the LLVM type. return ConvertTypeRecursive(Context.getObjCIdType()); diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index c390f769f5..b17f7bc1ca 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -2734,7 +2734,9 @@ Sema::CheckSingleAssignmentConstraints(QualType lhsType, Expr *&rExpr) { // C99 6.5.16.1p1: the left operand is a pointer and the right is // a null pointer constant. - if ((lhsType->isPointerType() || lhsType->isObjCQualifiedIdType() || + if ((lhsType->isPointerType() || + lhsType->isObjCQualifiedIdType() || + lhsType->isObjCQualifiedClassType() || lhsType->isBlockPointerType()) && rExpr->isNullPointerConstant(Context)) { ImpCastExprToType(rExpr, lhsType); diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp index 19dc3821c7..afa025552a 100644 --- a/lib/Sema/SemaExprObjC.cpp +++ b/lib/Sema/SemaExprObjC.cpp @@ -391,7 +391,8 @@ Sema::ExprResult Sema::ActOnInstanceMessage(ExprTy *receiver, Selector Sel, // We allow sending a message to a qualified ID ("id"), which is ok as // long as one of the protocols implements the selector (if not, warn). if (ObjCQualifiedIdType *QIT = dyn_cast(ReceiverCType)) { - // Search protocols + // Search protocols for instance methods. + ReceiverCType.dump(); for (unsigned i = 0; i < QIT->getNumProtocols(); i++) { ObjCProtocolDecl *PDecl = QIT->getProtocols(i); if (PDecl && (Method = PDecl->lookupInstanceMethod(Sel))) @@ -400,6 +401,18 @@ Sema::ExprResult Sema::ActOnInstanceMessage(ExprTy *receiver, Selector Sel, if (!Method) Diag(lbrac, diag::warn_method_not_found_in_protocol) << Sel << RExpr->getSourceRange(); + // Check for GCC extension "Class". + } else if (ObjCQualifiedClassType *QIT = + dyn_cast(ReceiverCType)) { + // Search protocols for class methods. + for (unsigned i = 0; i < QIT->getNumProtocols(); i++) { + ObjCProtocolDecl *PDecl = QIT->getProtocols(i); + if (PDecl && (Method = PDecl->lookupClassMethod(Sel))) + break; + } + if (!Method) + Diag(lbrac, diag::warn_method_not_found_in_protocol) + << Sel << RExpr->getSourceRange(); } else if (const ObjCInterfaceType *OCIReceiver = ReceiverCType->getAsPointerToObjCInterfaceType()) { // We allow sending a message to a pointer to an interface (an object).