[cfe-commits] r53841 - in /cfe/trunk: include/clang/AST/Type.h lib/Sema/SemaExprObjC.cpp test/Parser/objc-init.m
Chris Lattner
sabre at nondot.org
Sun Jul 20 23:12:57 PDT 2008
Author: lattner
Date: Mon Jul 21 01:12:56 2008
New Revision: 53841
URL: http://llvm.org/viewvc/llvm-project?rev=53841&view=rev
Log:
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.
Modified:
cfe/trunk/include/clang/AST/Type.h
cfe/trunk/lib/Sema/SemaExprObjC.cpp
cfe/trunk/test/Parser/objc-init.m
Modified: cfe/trunk/include/clang/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=53841&r1=53840&r2=53841&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/trunk/include/clang/AST/Type.h Mon Jul 21 01:12:56 2008
@@ -362,6 +362,10 @@
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 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());
Modified: cfe/trunk/lib/Sema/SemaExprObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprObjC.cpp?rev=53841&r1=53840&r2=53841&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprObjC.cpp Mon Jul 21 01:12:56 2008
@@ -226,14 +226,13 @@
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 @@
// 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 @@
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 @@
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 @@
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) {
Modified: cfe/trunk/test/Parser/objc-init.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/objc-init.m?rev=53841&r1=53840&r2=53841&view=diff
==============================================================================
--- cfe/trunk/test/Parser/objc-init.m (original)
+++ cfe/trunk/test/Parser/objc-init.m Mon Jul 21 01:12:56 2008
@@ -11,13 +11,16 @@
}
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};
}
More information about the cfe-commits
mailing list