SemaExprObjC.cpp revision 55a24334c09425c9fe67d57b3cde3e6ed47c0538
1//===--- SemaExprObjC.cpp - Semantic Analysis for ObjC Expressions --------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file implements semantic analysis for Objective-C expressions. 11// 12//===----------------------------------------------------------------------===// 13 14#include "Sema.h" 15#include "clang/AST/ASTContext.h" 16#include "clang/AST/DeclObjC.h" 17#include "clang/AST/ExprObjC.h" 18using namespace clang; 19 20Sema::ExprResult Sema::ParseObjCStringLiteral(SourceLocation *AtLocs, 21 ExprTy **Strings, 22 unsigned NumStrings) { 23 SourceLocation AtLoc = AtLocs[0]; 24 StringLiteral* S = static_cast<StringLiteral *>(Strings[0]); 25 if (NumStrings > 1) { 26 // Concatenate objc strings. 27 StringLiteral* ES = static_cast<StringLiteral *>(Strings[NumStrings-1]); 28 SourceLocation EndLoc = ES->getSourceRange().getEnd(); 29 unsigned Length = 0; 30 for (unsigned i = 0; i < NumStrings; i++) 31 Length += static_cast<StringLiteral *>(Strings[i])->getByteLength(); 32 char *strBuf = new char [Length]; 33 char *p = strBuf; 34 bool isWide = false; 35 for (unsigned i = 0; i < NumStrings; i++) { 36 S = static_cast<StringLiteral *>(Strings[i]); 37 if (S->isWide()) 38 isWide = true; 39 memcpy(p, S->getStrData(), S->getByteLength()); 40 p += S->getByteLength(); 41 delete S; 42 } 43 S = new StringLiteral(strBuf, Length, 44 isWide, Context.getPointerType(Context.CharTy), 45 AtLoc, EndLoc); 46 } 47 48 if (CheckBuiltinCFStringArgument(S)) 49 return true; 50 51 if (Context.getObjCConstantStringInterface().isNull()) { 52 // Initialize the constant string interface lazily. This assumes 53 // the NSConstantString interface is seen in this translation unit. 54 IdentifierInfo *NSIdent = &Context.Idents.get("NSConstantString"); 55 Decl *IFace = LookupDecl(NSIdent, Decl::IDNS_Ordinary, TUScope); 56 ObjCInterfaceDecl *strIFace = dyn_cast_or_null<ObjCInterfaceDecl>(IFace); 57 if (strIFace) 58 Context.setObjCConstantStringInterface(strIFace); 59 } 60 QualType t = Context.getObjCConstantStringInterface(); 61 // If there is no NSConstantString interface defined then treat constant 62 // strings as untyped objects and let the runtime figure it out later. 63 if (t == QualType()) { 64 t = Context.getObjCIdType(); 65 } else { 66 t = Context.getPointerType(t); 67 } 68 return new ObjCStringLiteral(S, t, AtLoc); 69} 70 71Sema::ExprResult Sema::ParseObjCEncodeExpression(SourceLocation AtLoc, 72 SourceLocation EncodeLoc, 73 SourceLocation LParenLoc, 74 TypeTy *Ty, 75 SourceLocation RParenLoc) { 76 QualType EncodedType = QualType::getFromOpaquePtr(Ty); 77 78 QualType t = Context.getPointerType(Context.CharTy); 79 return new ObjCEncodeExpr(t, EncodedType, AtLoc, RParenLoc); 80} 81 82Sema::ExprResult Sema::ParseObjCSelectorExpression(Selector Sel, 83 SourceLocation AtLoc, 84 SourceLocation SelLoc, 85 SourceLocation LParenLoc, 86 SourceLocation RParenLoc) { 87 QualType t = Context.getObjCSelType(); 88 return new ObjCSelectorExpr(t, Sel, AtLoc, RParenLoc); 89} 90 91Sema::ExprResult Sema::ParseObjCProtocolExpression(IdentifierInfo *ProtocolId, 92 SourceLocation AtLoc, 93 SourceLocation ProtoLoc, 94 SourceLocation LParenLoc, 95 SourceLocation RParenLoc) { 96 ObjCProtocolDecl* PDecl = ObjCProtocols[ProtocolId]; 97 if (!PDecl) { 98 Diag(ProtoLoc, diag::err_undeclared_protocol, ProtocolId->getName()); 99 return true; 100 } 101 102 QualType t = Context.getObjCProtoType(); 103 if (t.isNull()) 104 return true; 105 t = Context.getPointerType(t); 106 return new ObjCProtocolExpr(t, PDecl, AtLoc, RParenLoc); 107} 108 109bool Sema::CheckMessageArgumentTypes(Expr **Args, unsigned NumArgs, 110 ObjCMethodDecl *Method) { 111 bool anyIncompatibleArgs = false; 112 113 for (unsigned i = 0; i < NumArgs; i++) { 114 Expr *argExpr = Args[i]; 115 assert(argExpr && "CheckMessageArgumentTypes(): missing expression"); 116 117 QualType lhsType = Method->getParamDecl(i)->getType(); 118 QualType rhsType = argExpr->getType(); 119 120 // If necessary, apply function/array conversion. C99 6.7.5.3p[7,8]. 121 if (lhsType->isArrayType()) 122 lhsType = Context.getArrayDecayedType(lhsType); 123 else if (lhsType->isFunctionType()) 124 lhsType = Context.getPointerType(lhsType); 125 126 AssignConvertType Result = 127 CheckSingleAssignmentConstraints(lhsType, argExpr); 128 if (Args[i] != argExpr) // The expression was converted. 129 Args[i] = argExpr; // Make sure we store the converted expression. 130 131 anyIncompatibleArgs |= 132 DiagnoseAssignmentResult(Result, argExpr->getLocStart(), lhsType, rhsType, 133 argExpr, "sending"); 134 } 135 return anyIncompatibleArgs; 136} 137 138// ActOnClassMessage - used for both unary and keyword messages. 139// ArgExprs is optional - if it is present, the number of expressions 140// is obtained from Sel.getNumArgs(). 141Sema::ExprResult Sema::ActOnClassMessage( 142 Scope *S, 143 IdentifierInfo *receiverName, Selector Sel, 144 SourceLocation lbrac, SourceLocation rbrac, ExprTy **Args, unsigned NumArgs) 145{ 146 assert(receiverName && "missing receiver class name"); 147 148 Expr **ArgExprs = reinterpret_cast<Expr **>(Args); 149 ObjCInterfaceDecl* ClassDecl = 0; 150 if (!strcmp(receiverName->getName(), "super") && getCurMethodDecl()) { 151 ClassDecl = getCurMethodDecl()->getClassInterface()->getSuperClass(); 152 if (!ClassDecl) 153 return Diag(lbrac, diag::error_no_super_class, 154 getCurMethodDecl()->getClassInterface()->getName()); 155 if (getCurMethodDecl()->isInstance()) { 156 QualType superTy = Context.getObjCInterfaceType(ClassDecl); 157 superTy = Context.getPointerType(superTy); 158 ExprResult ReceiverExpr = new PreDefinedExpr(SourceLocation(), superTy, 159 PreDefinedExpr::ObjCSuper); 160 // We are really in an instance method, redirect. 161 return ActOnInstanceMessage(ReceiverExpr.Val, Sel, lbrac, rbrac, 162 Args, NumArgs); 163 } 164 // We are sending a message to 'super' within a class method. Do nothing, 165 // the receiver will pass through as 'super' (how convenient:-). 166 } else 167 ClassDecl = getObjCInterfaceDecl(receiverName); 168 169 // ClassDecl is null in the following case. 170 // 171 // typedef XCElementDisplayRect XCElementGraphicsRect; 172 // 173 // @implementation XCRASlice 174 // - whatever { // Note that XCElementGraphicsRect is a typedef name. 175 // _sGraphicsDelegate =[[XCElementGraphicsRect alloc] init]; 176 // } 177 // 178 // FIXME: Investigate why GCC allows the above. 179 ObjCMethodDecl *Method = 0; 180 QualType returnType; 181 if (ClassDecl) { 182 Method = ClassDecl->lookupClassMethod(Sel); 183 184 // If we have an implementation in scope, check "private" methods. 185 if (!Method) { 186 if (ObjCImplementationDecl *ImpDecl = 187 ObjCImplementations[ClassDecl->getIdentifier()]) 188 Method = ImpDecl->getClassMethod(Sel); 189 } 190 // Before we give up, check if the selector is an instance method. 191 if (!Method) 192 Method = ClassDecl->lookupInstanceMethod(Sel); 193 } 194 if (!Method) { 195 Diag(lbrac, diag::warn_method_not_found, std::string("+"), Sel.getName(), 196 SourceRange(lbrac, rbrac)); 197 returnType = Context.getObjCIdType(); 198 } else { 199 returnType = Method->getResultType(); 200 if (Sel.getNumArgs()) { 201 if (CheckMessageArgumentTypes(ArgExprs, Sel.getNumArgs(), Method)) 202 return true; 203 } 204 } 205 206 // If we have the ObjCInterfaceDecl* for the class that is receiving 207 // the message, use that to construct the ObjCMessageExpr. Otherwise 208 // pass on the IdentifierInfo* for the class. 209 if (ClassDecl) 210 return new ObjCMessageExpr(ClassDecl, Sel, returnType, Method, 211 lbrac, rbrac, ArgExprs, NumArgs); 212 else 213 return new ObjCMessageExpr(receiverName, Sel, returnType, Method, 214 lbrac, rbrac, ArgExprs, NumArgs); 215} 216 217// ActOnInstanceMessage - used for both unary and keyword messages. 218// ArgExprs is optional - if it is present, the number of expressions 219// is obtained from Sel.getNumArgs(). 220Sema::ExprResult Sema::ActOnInstanceMessage(ExprTy *receiver, Selector Sel, 221 SourceLocation lbrac, SourceLocation rbrac, ExprTy **Args, unsigned NumArgs) 222{ 223 assert(receiver && "missing receiver expression"); 224 225 Expr **ArgExprs = reinterpret_cast<Expr **>(Args); 226 Expr *RExpr = static_cast<Expr *>(receiver); 227 QualType returnType; 228 229 QualType receiverType = 230 RExpr->getType().getCanonicalType().getUnqualifiedType(); 231 232 // Handle messages to id. 233 if (receiverType == Context.getObjCIdType().getCanonicalType()) { 234 ObjCMethodDecl *Method = InstanceMethodPool[Sel].Method; 235 if (!Method) 236 Method = FactoryMethodPool[Sel].Method; 237 if (!Method) { 238 Diag(lbrac, diag::warn_method_not_found, std::string("-"), Sel.getName(), 239 SourceRange(lbrac, rbrac)); 240 returnType = Context.getObjCIdType(); 241 } else { 242 returnType = Method->getResultType(); 243 if (Sel.getNumArgs()) 244 if (CheckMessageArgumentTypes(ArgExprs, Sel.getNumArgs(), Method)) 245 return true; 246 } 247 return new ObjCMessageExpr(RExpr, Sel, returnType, Method, lbrac, rbrac, 248 ArgExprs, NumArgs); 249 } 250 251 // Handle messages to Class. 252 if (receiverType == Context.getObjCClassType().getCanonicalType()) { 253 ObjCMethodDecl *Method = 0; 254 if (ObjCMethodDecl *CurMeth = getCurMethodDecl()) { 255 // If we have an implementation in scope, check "private" methods. 256 if (ObjCInterfaceDecl *ClassDecl = CurMeth->getClassInterface()) 257 if (ObjCImplementationDecl *ImpDecl = 258 ObjCImplementations[ClassDecl->getIdentifier()]) 259 Method = ImpDecl->getClassMethod(Sel); 260 } 261 if (!Method) 262 Method = FactoryMethodPool[Sel].Method; 263 if (!Method) 264 Method = InstanceMethodPool[Sel].Method; 265 if (!Method) { 266 Diag(lbrac, diag::warn_method_not_found, std::string("-"), Sel.getName(), 267 RExpr->getSourceRange()); 268 returnType = Context.getObjCIdType(); 269 } else { 270 returnType = Method->getResultType(); 271 if (Sel.getNumArgs()) 272 if (CheckMessageArgumentTypes(ArgExprs, Sel.getNumArgs(), Method)) 273 return true; 274 } 275 276 return new ObjCMessageExpr(RExpr, Sel, returnType, Method, lbrac, rbrac, 277 ArgExprs, NumArgs); 278 } 279 280 ObjCMethodDecl *Method = 0; 281 ObjCInterfaceDecl* ClassDecl = 0; 282 283 // We allow sending a message to a qualified ID ("id<foo>"), which is ok as 284 // long as one of the protocols implements the selector (if not, warn). 285 if (ObjCQualifiedIdType *QIT = 286 dyn_cast<ObjCQualifiedIdType>(receiverType)) { 287 // Search protocols 288 for (unsigned i = 0; i < QIT->getNumProtocols(); i++) { 289 ObjCProtocolDecl *PDecl = QIT->getProtocols(i); 290 if (PDecl && (Method = PDecl->lookupInstanceMethod(Sel))) 291 break; 292 } 293 if (!Method) 294 Diag(lbrac, diag::warn_method_not_found_in_protocol, 295 std::string("-"), Sel.getName(), 296 RExpr->getSourceRange()); 297 } else if (const ObjCInterfaceType *OCIReceiver = 298 receiverType->getAsPointerToObjCInterfaceType()) { 299 // We allow sending a message to a pointer to an interface (an object). 300 301 ClassDecl = OCIReceiver->getDecl(); 302 // FIXME: consider using InstanceMethodPool, since it will be faster 303 // than the following method (which can do *many* linear searches). The 304 // idea is to add class info to InstanceMethodPool. 305 Method = ClassDecl->lookupInstanceMethod(Sel); 306 307 if (!Method) { 308 // Search protocol qualifiers. 309 for (ObjCQualifiedIdType::qual_iterator QI = OCIReceiver->qual_begin(), 310 E = OCIReceiver->qual_end(); QI != E; ++QI) { 311 if ((Method = (*QI)->lookupInstanceMethod(Sel))) 312 break; 313 } 314 } 315 316 if (!Method && !OCIReceiver->qual_empty()) 317 Diag(lbrac, diag::warn_method_not_found_in_protocol, 318 std::string("-"), Sel.getName(), 319 SourceRange(lbrac, rbrac)); 320 } else { 321 Diag(lbrac, diag::error_bad_receiver_type, 322 RExpr->getType().getAsString(), RExpr->getSourceRange()); 323 return true; 324 } 325 326 if (!Method) { 327 // If we have an implementation in scope, check "private" methods. 328 if (ClassDecl) 329 if (ObjCImplementationDecl *ImpDecl = 330 ObjCImplementations[ClassDecl->getIdentifier()]) 331 Method = ImpDecl->getInstanceMethod(Sel); 332 // If we still haven't found a method, look in the global pool. This 333 // behavior isn't very desirable, however we need it for GCC 334 // compatibility. 335 if (!Method) 336 Method = InstanceMethodPool[Sel].Method; 337 } 338 if (!Method) { 339 Diag(lbrac, diag::warn_method_not_found, std::string("-"), Sel.getName(), 340 SourceRange(lbrac, rbrac)); 341 returnType = Context.getObjCIdType(); 342 } else { 343 returnType = Method->getResultType(); 344 if (Sel.getNumArgs()) 345 if (CheckMessageArgumentTypes(ArgExprs, Sel.getNumArgs(), Method)) 346 return true; 347 } 348 return new ObjCMessageExpr(RExpr, Sel, returnType, Method, lbrac, rbrac, 349 ArgExprs, NumArgs); 350} 351 352//===----------------------------------------------------------------------===// 353// ObjCQualifiedIdTypesAreCompatible - Compatibility testing for qualified id's. 354//===----------------------------------------------------------------------===// 355 356/// ProtocolCompatibleWithProtocol - return 'true' if 'lProto' is in the 357/// inheritance hierarchy of 'rProto'. 358static bool ProtocolCompatibleWithProtocol(ObjCProtocolDecl *lProto, 359 ObjCProtocolDecl *rProto) { 360 if (lProto == rProto) 361 return true; 362 ObjCProtocolDecl** RefPDecl = rProto->getReferencedProtocols(); 363 for (unsigned i = 0; i < rProto->getNumReferencedProtocols(); i++) 364 if (ProtocolCompatibleWithProtocol(lProto, RefPDecl[i])) 365 return true; 366 return false; 367} 368 369/// ClassImplementsProtocol - Checks that 'lProto' protocol 370/// has been implemented in IDecl class, its super class or categories (if 371/// lookupCategory is true). 372static bool ClassImplementsProtocol(ObjCProtocolDecl *lProto, 373 ObjCInterfaceDecl *IDecl, 374 bool lookupCategory, 375 bool RHSIsQualifiedID = false) { 376 377 // 1st, look up the class. 378 ObjCProtocolDecl **protoList = IDecl->getReferencedProtocols(); 379 for (unsigned i = 0; i < IDecl->getNumIntfRefProtocols(); i++) { 380 if (ProtocolCompatibleWithProtocol(lProto, protoList[i])) 381 return true; 382 // This is dubious and is added to be compatible with gcc. 383 // In gcc, it is also allowed assigning a protocol-qualified 'id' 384 // type to a LHS object when protocol in qualified LHS is in list 385 // of protocols in the rhs 'id' object. This IMO, should be a bug. 386 // FIXME: Treat this as an extension, and flag this as an error when 387 // GCC extensions are not enabled. 388 else if (RHSIsQualifiedID && 389 ProtocolCompatibleWithProtocol(protoList[i], lProto)) 390 return true; 391 } 392 393 // 2nd, look up the category. 394 if (lookupCategory) 395 for (ObjCCategoryDecl *CDecl = IDecl->getCategoryList(); CDecl; 396 CDecl = CDecl->getNextClassCategory()) { 397 protoList = CDecl->getReferencedProtocols(); 398 for (unsigned i = 0; i < CDecl->getNumReferencedProtocols(); i++) { 399 if (ProtocolCompatibleWithProtocol(lProto, protoList[i])) 400 return true; 401 } 402 } 403 404 // 3rd, look up the super class(s) 405 if (IDecl->getSuperClass()) 406 return 407 ClassImplementsProtocol(lProto, IDecl->getSuperClass(), lookupCategory, 408 RHSIsQualifiedID); 409 410 return false; 411} 412 413/// ObjCQualifiedIdTypesAreCompatible - We know that one of lhs/rhs is an 414/// ObjCQualifiedIDType. 415bool Sema::ObjCQualifiedIdTypesAreCompatible(QualType lhs, QualType rhs, 416 bool compare) { 417 // Allow id<P..> and an 'id' or void* type in all cases. 418 if (const PointerType *PT = lhs->getAsPointerType()) { 419 QualType PointeeTy = PT->getPointeeType(); 420 if (Context.isObjCIdType(PointeeTy) || PointeeTy->isVoidType()) 421 return true; 422 } else if (const PointerType *PT = rhs->getAsPointerType()) { 423 QualType PointeeTy = PT->getPointeeType(); 424 if (Context.isObjCIdType(PointeeTy) || PointeeTy->isVoidType()) 425 return true; 426 } 427 428 if (const ObjCQualifiedIdType *lhsQID = lhs->getAsObjCQualifiedIdType()) { 429 const ObjCQualifiedIdType *rhsQID = rhs->getAsObjCQualifiedIdType(); 430 const ObjCQualifiedInterfaceType *rhsQI = 0; 431 QualType rtype; 432 433 if (!rhsQID) { 434 // Not comparing two ObjCQualifiedIdType's? 435 if (!rhs->isPointerType()) return false; 436 437 rtype = rhs->getAsPointerType()->getPointeeType(); 438 rhsQI = rtype->getAsObjCQualifiedInterfaceType(); 439 if (rhsQI == 0) { 440 // If the RHS is a unqualified interface pointer "NSString*", 441 // make sure we check the class hierarchy. 442 if (const ObjCInterfaceType *IT = rtype->getAsObjCInterfaceType()) { 443 ObjCInterfaceDecl *rhsID = IT->getDecl(); 444 for (unsigned i = 0; i != lhsQID->getNumProtocols(); ++i) { 445 // when comparing an id<P> on lhs with a static type on rhs, 446 // see if static class implements all of id's protocols, directly or 447 // through its super class and categories. 448 if (!ClassImplementsProtocol(lhsQID->getProtocols(i), rhsID, true)) 449 return false; 450 } 451 return true; 452 } 453 } 454 } 455 456 ObjCQualifiedIdType::qual_iterator RHSProtoI, RHSProtoE; 457 if (rhsQI) { // We have a qualified interface (e.g. "NSObject<Proto> *"). 458 RHSProtoI = rhsQI->qual_begin(); 459 RHSProtoE = rhsQI->qual_end(); 460 } else if (rhsQID) { // We have a qualified id (e.g. "id<Proto> *"). 461 RHSProtoI = rhsQID->qual_begin(); 462 RHSProtoE = rhsQID->qual_end(); 463 } else { 464 return false; 465 } 466 467 for (unsigned i =0; i < lhsQID->getNumProtocols(); i++) { 468 ObjCProtocolDecl *lhsProto = lhsQID->getProtocols(i); 469 bool match = false; 470 471 // when comparing an id<P> on lhs with a static type on rhs, 472 // see if static class implements all of id's protocols, directly or 473 // through its super class and categories. 474 for (; RHSProtoI != RHSProtoE; ++RHSProtoI) { 475 ObjCProtocolDecl *rhsProto = *RHSProtoI; 476 if (ProtocolCompatibleWithProtocol(lhsProto, rhsProto) || 477 compare && ProtocolCompatibleWithProtocol(rhsProto, lhsProto)) { 478 match = true; 479 break; 480 } 481 } 482 if (rhsQI) { 483 // If the RHS is a qualified interface pointer "NSString<P>*", 484 // make sure we check the class hierarchy. 485 if (const ObjCInterfaceType *IT = rtype->getAsObjCInterfaceType()) { 486 ObjCInterfaceDecl *rhsID = IT->getDecl(); 487 for (unsigned i = 0; i != lhsQID->getNumProtocols(); ++i) { 488 // when comparing an id<P> on lhs with a static type on rhs, 489 // see if static class implements all of id's protocols, directly or 490 // through its super class and categories. 491 if (ClassImplementsProtocol(lhsQID->getProtocols(i), rhsID, true)) { 492 match = true; 493 break; 494 } 495 } 496 } 497 } 498 if (!match) 499 return false; 500 } 501 502 return true; 503 } 504 505 const ObjCQualifiedIdType *rhsQID = rhs->getAsObjCQualifiedIdType(); 506 assert(rhsQID && "One of the LHS/RHS should be id<x>"); 507 508 if (!lhs->isPointerType()) 509 return false; 510 511 QualType ltype = lhs->getAsPointerType()->getPointeeType(); 512 if (const ObjCQualifiedInterfaceType *lhsQI = 513 ltype->getAsObjCQualifiedInterfaceType()) { 514 ObjCQualifiedIdType::qual_iterator LHSProtoI = lhsQI->qual_begin(); 515 ObjCQualifiedIdType::qual_iterator LHSProtoE = lhsQI->qual_end(); 516 for (; LHSProtoI != LHSProtoE; ++LHSProtoI) { 517 bool match = false; 518 ObjCProtocolDecl *lhsProto = *LHSProtoI; 519 for (unsigned j = 0; j < rhsQID->getNumProtocols(); j++) { 520 ObjCProtocolDecl *rhsProto = rhsQID->getProtocols(j); 521 if (ProtocolCompatibleWithProtocol(lhsProto, rhsProto) || 522 compare && ProtocolCompatibleWithProtocol(rhsProto, lhsProto)) { 523 match = true; 524 break; 525 } 526 } 527 if (!match) 528 return false; 529 } 530 return true; 531 } 532 533 if (const ObjCInterfaceType *IT = ltype->getAsObjCInterfaceType()) { 534 // for static type vs. qualified 'id' type, check that class implements 535 // all of 'id's protocols. 536 ObjCInterfaceDecl *lhsID = IT->getDecl(); 537 for (unsigned j = 0; j < rhsQID->getNumProtocols(); j++) { 538 ObjCProtocolDecl *rhsProto = rhsQID->getProtocols(j); 539 if (!ClassImplementsProtocol(rhsProto, lhsID, compare, true)) 540 return false; 541 } 542 return true; 543 } 544 return false; 545} 546 547