diff options
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/AST/ASTContext.cpp | 2 | ||||
| -rw-r--r-- | clang/lib/AST/Type.cpp | 3 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CodeGenTypes.cpp | 1 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 4 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaExprObjC.cpp | 15 |
5 files changed, 21 insertions, 4 deletions
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index cdd61cd3f4a..605f46b44bf 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -2408,7 +2408,7 @@ bool ASTContext::isObjCNSObjectType(QualType Ty) const { /// to struct), Interface* (pointer to ObjCInterfaceType) and id<P> (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/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp index ba8b463c277..065b626930b 100644 --- a/clang/lib/AST/Type.cpp +++ b/clang/lib/AST/Type.cpp @@ -693,7 +693,8 @@ bool Type::isScalarType() const { isa<BlockPointerType>(CanonicalType) || isa<MemberPointerType>(CanonicalType) || isa<ComplexType>(CanonicalType) || - isa<ObjCQualifiedIdType>(CanonicalType); + isa<ObjCQualifiedIdType>(CanonicalType) || + isa<ObjCQualifiedClassType>(CanonicalType); } /// \brief Determines whether the type is a C++ aggregate type or C diff --git a/clang/lib/CodeGen/CodeGenTypes.cpp b/clang/lib/CodeGen/CodeGenTypes.cpp index a385d8c9d29..47ac79f70b5 100644 --- a/clang/lib/CodeGen/CodeGenTypes.cpp +++ b/clang/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/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index c390f769f59..b17f7bc1ca8 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/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/clang/lib/Sema/SemaExprObjC.cpp b/clang/lib/Sema/SemaExprObjC.cpp index 19dc3821c76..afa025552ad 100644 --- a/clang/lib/Sema/SemaExprObjC.cpp +++ b/clang/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<foo>"), which is ok as // long as one of the protocols implements the selector (if not, warn). if (ObjCQualifiedIdType *QIT = dyn_cast<ObjCQualifiedIdType>(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<foo>". + } else if (ObjCQualifiedClassType *QIT = + dyn_cast<ObjCQualifiedClassType>(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). |

