continue cleaning up code, and disable sending a message directly to an

interface.  This fixes a bug where we used to accept:

void test2(NSNumber x) {
	[x METH];
}

which doesn't make sense and GCC rejects.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@53841 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner 2008-07-21 06:12:56 +00:00
Родитель fe1a553256
Коммит 2b1cc8be4d
3 изменённых файлов: 29 добавлений и 20 удалений

Просмотреть файл

@ -362,6 +362,10 @@ public:
const ObjCQualifiedInterfaceType *getAsObjCQualifiedInterfaceType() const;
const ObjCQualifiedIdType *getAsObjCQualifiedIdType() const;
/// getAsPointerToObjCInterfaceType - If this is a pointer to an ObjC
/// interface, return the interface type, otherwise return null.
const ObjCInterfaceType *getAsPointerToObjCInterfaceType() const;
/// getDesugaredType - Return the specified type with any "sugar" removed from
/// the type. This takes off typedefs, typeof's etc. If the outer level of
@ -1289,6 +1293,12 @@ inline unsigned QualType::getAddressSpace() const {
inline const TypedefType* Type::getAsTypedefType() const {
return dyn_cast<TypedefType>(this);
}
inline const ObjCInterfaceType *Type::getAsPointerToObjCInterfaceType() const {
if (const PointerType *PT = getAsPointerType())
return PT->getPointeeType()->getAsObjCInterfaceType();
return 0;
}
inline bool Type::isFunctionType() const {
return isa<FunctionType>(CanonicalType.getUnqualifiedType());

Просмотреть файл

@ -226,14 +226,13 @@ Sema::ExprResult Sema::ActOnInstanceMessage(
Expr **ArgExprs = reinterpret_cast<Expr **>(Args);
Expr *RExpr = static_cast<Expr *>(receiver);
QualType returnType;
ObjCMethodDecl *Method = 0;
QualType receiverType =
RExpr->getType().getCanonicalType().getUnqualifiedType();
// Handle messages to id.
if (receiverType == Context.getObjCIdType().getCanonicalType()) {
Method = InstanceMethodPool[Sel].Method;
ObjCMethodDecl *Method = InstanceMethodPool[Sel].Method;
if (!Method)
Method = FactoryMethodPool[Sel].Method;
if (!Method) {
@ -252,6 +251,7 @@ Sema::ExprResult Sema::ActOnInstanceMessage(
// Handle messages to Class.
if (receiverType == Context.getObjCClassType().getCanonicalType()) {
ObjCMethodDecl *Method = 0;
if (getCurMethodDecl()) {
ObjCInterfaceDecl* ClassDecl = getCurMethodDecl()->getClassInterface();
// If we have an implementation in scope, check "private" methods.
@ -279,18 +279,14 @@ Sema::ExprResult Sema::ActOnInstanceMessage(
ArgExprs, NumArgs);
}
// We allow sending a message to a qualified ID ("id<foo>") to an interface
// directly ("[NSNumber foo]") and to a pointer to an interface (an object).
if (!isa<ObjCQualifiedIdType>(receiverType) &&
!isa<ObjCInterfaceType>(receiverType))
if (const PointerType *PTy = receiverType->getAsPointerType())
receiverType = PTy->getPointeeType();
// else error, invalid receiver.
ObjCMethodDecl *Method = 0;
ObjCInterfaceDecl* ClassDecl = 0;
// 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>(receiverType)) {
// search protocols
// Search protocols
for (unsigned i = 0; i < QIT->getNumProtocols(); i++) {
ObjCProtocolDecl *PDecl = QIT->getProtocols(i);
if (PDecl && (Method = PDecl->lookupInstanceMethod(Sel)))
@ -300,13 +296,9 @@ Sema::ExprResult Sema::ActOnInstanceMessage(
Diag(lbrac, diag::warn_method_not_found_in_protocol,
std::string("-"), Sel.getName(),
SourceRange(lbrac, rbrac));
} else {
ObjCInterfaceType *OCIReceiver =dyn_cast<ObjCInterfaceType>(receiverType);
if (OCIReceiver == 0) {
Diag(lbrac, diag::error_bad_receiver_type,
RExpr->getType().getAsString());
return true;
}
} else if (const ObjCInterfaceType *OCIReceiver =
receiverType->getAsPointerToObjCInterfaceType()) {
// We allow sending a message to a pointer to an interface (an object).
ClassDecl = OCIReceiver->getDecl();
// FIXME: consider using InstanceMethodPool, since it will be faster
@ -327,6 +319,10 @@ Sema::ExprResult Sema::ActOnInstanceMessage(
Diag(lbrac, diag::warn_method_not_found_in_protocol,
std::string("-"), Sel.getName(),
SourceRange(lbrac, rbrac));
} else {
Diag(lbrac, diag::error_bad_receiver_type,
RExpr->getType().getAsString());
return true;
}
if (!Method) {

Просмотреть файл

@ -11,13 +11,16 @@ void test1() {
}
void test2(NSNumber x) {
id objects[] = {[x METH]}; // expected-error {{bad receiver type}}
}
void test3(NSNumber *x) {
id objects[] = {[x METH]};
return 0;
}
// rdar://5977581
void test3() {
void test4() {
unsigned x[] = {[NSNumber METH2]+2};
}