diff options
| -rw-r--r-- | clang/include/clang/AST/Type.h | 6 | ||||
| -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 | 
6 files changed, 24 insertions, 7 deletions
diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h index 5dc2c311074..cb34c77f1ac 100644 --- a/clang/include/clang/AST/Type.h +++ b/clang/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<ObjCProtocolDecl*, 8> 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/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).  | 

