More work to integrate newly added ObjCQualifiedClassType into the type system.
This is necessary 'plumbing' to fix <rdar://problem/6497631> Message lookup is sometimes different than gcc's. llvm-svn: 65248
This commit is contained in:
parent
3283ff5088
commit
8487e3e541
|
@ -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; }
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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());
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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).
|
||||
|
|
Loading…
Reference in New Issue