SemaExprObjC.cpp revision b327ce02959d4e6224732e1c362e7f8e0688581f
1269f91e066c5991a4d4aa2945ea2c285f8589b12Greg Clayton//===--- SemaExprObjC.cpp - Semantic Analysis for ObjC Expressions --------===// 2363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton// 3363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton// The LLVM Compiler Infrastructure 4363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton// 5363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton// This file is distributed under the University of Illinois Open Source 6363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton// License. See LICENSE.TXT for details. 7363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton// 8363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton//===----------------------------------------------------------------------===// 9363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton// 10363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton// This file implements semantic analysis for Objective-C expressions. 11363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton// 12363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton//===----------------------------------------------------------------------===// 13363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton 14fac2e62f08719ba800a440b7ad0d5a55a26dc620Jason Molenda#include "Sema.h" 15363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton#include "clang/AST/ASTContext.h" 16363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton#include "clang/AST/DeclObjC.h" 17363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton#include "clang/AST/Expr.h" 18363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Claytonusing namespace clang; 190fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton 200fa512447e00da09d300fbabd18b5ce94f52fdaaGreg ClaytonSema::ExprResult Sema::ParseObjCStringLiteral(SourceLocation *AtLocs, 21363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton ExprTy **Strings, 22d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton unsigned NumStrings) { 231e5b02176d6952d0679479926fa557534313472bGreg Clayton SourceLocation AtLoc = AtLocs[0]; 24363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton StringLiteral* S = static_cast<StringLiteral *>(Strings[0]); 250fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton if (NumStrings > 1) { 26fac2e62f08719ba800a440b7ad0d5a55a26dc620Jason Molenda // Concatenate objc strings. 27363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton StringLiteral* ES = static_cast<StringLiteral *>(Strings[NumStrings-1]); 28363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton SourceLocation EndLoc = ES->getSourceRange().getEnd(); 29363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton unsigned Length = 0; 30363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton for (unsigned i = 0; i < NumStrings; i++) 31363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton Length += static_cast<StringLiteral *>(Strings[i])->getByteLength(); 32363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton char *strBuf = new char [Length]; 33363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton char *p = strBuf; 34363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton bool isWide = false; 35363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton for (unsigned i = 0; i < NumStrings; i++) { 36363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton S = static_cast<StringLiteral *>(Strings[i]); 37363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton if (S->isWide()) 38363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton isWide = true; 39363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton memcpy(p, S->getStrData(), S->getByteLength()); 40363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton p += S->getByteLength(); 41363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton delete S; 42363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton } 430fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton S = new StringLiteral(strBuf, Length, 44d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton isWide, Context.getPointerType(Context.CharTy), 4552fbbd224d4ba741d5f717e1683c5daa21fe8710Jason Molenda AtLoc, EndLoc); 46363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton } 473acaa926c8f0d32da48db61a5fcb95276e6a4006Greg Clayton 48d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton if (CheckBuiltinCFStringArgument(S)) 49d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton return true; 50d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton 51d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton if (Context.getObjCConstantStringInterface().isNull()) { 52d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton // Initialize the constant string interface lazily. This assumes 53d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton // the NSConstantString interface is seen in this translation unit. 54d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton IdentifierInfo *NSIdent = &Context.Idents.get("NSConstantString"); 55d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton Decl *IFace = LookupDecl(NSIdent, Decl::IDNS_Ordinary, TUScope); 56363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton ObjCInterfaceDecl *strIFace = dyn_cast_or_null<ObjCInterfaceDecl>(IFace); 57363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton if (!strIFace) 58363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton return Diag(S->getLocStart(), diag::err_undef_interface, 59363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton NSIdent->getName()); 60363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton Context.setObjCConstantStringInterface(strIFace); 61363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton } 62363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton QualType t = Context.getObjCConstantStringInterface(); 63363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton t = Context.getPointerType(t); 64363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton return new ObjCStringLiteral(S, t, AtLoc); 65363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton} 66363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton 67363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg ClaytonSema::ExprResult Sema::ParseObjCEncodeExpression(SourceLocation AtLoc, 68363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton SourceLocation EncodeLoc, 69363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton SourceLocation LParenLoc, 701e5b02176d6952d0679479926fa557534313472bGreg Clayton TypeTy *Ty, 71d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton SourceLocation RParenLoc) { 72363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton QualType EncodedType = QualType::getFromOpaquePtr(Ty); 73363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton 741e5b02176d6952d0679479926fa557534313472bGreg Clayton QualType t = Context.getPointerType(Context.CharTy); 75363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton return new ObjCEncodeExpr(t, EncodedType, AtLoc, RParenLoc); 76363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton} 77d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton 78d52d00f4edb746ba458a3e659699160952dc925eGreg ClaytonSema::ExprResult Sema::ParseObjCSelectorExpression(Selector Sel, 79d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton SourceLocation AtLoc, 80d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton SourceLocation SelLoc, 81d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton SourceLocation LParenLoc, 82d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton SourceLocation RParenLoc) { 83d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton QualType t = Context.getObjCSelType(); 84d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton return new ObjCSelectorExpr(t, Sel, AtLoc, RParenLoc); 85d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton} 861e5b02176d6952d0679479926fa557534313472bGreg Clayton 87307c7fdc58d19f734991a176db972cc61d9ada16Greg ClaytonSema::ExprResult Sema::ParseObjCProtocolExpression(IdentifierInfo *ProtocolId, 88d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton SourceLocation AtLoc, 89d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton SourceLocation ProtoLoc, 90363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton SourceLocation LParenLoc, 911e5b02176d6952d0679479926fa557534313472bGreg Clayton SourceLocation RParenLoc) { 92d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton ObjCProtocolDecl* PDecl = ObjCProtocols[ProtocolId]; 93d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton if (!PDecl) { 94d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton Diag(ProtoLoc, diag::err_undeclared_protocol, ProtocolId->getName()); 95d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton return true; 96363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton } 97363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton 98d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton QualType t = Context.getObjCProtoType(); 99d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton if (t.isNull()) 100d2f3b42f70f309f548c2b618c5991a905a00ec3aGreg Clayton return true; 101d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton t = Context.getPointerType(t); 102d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton return new ObjCProtocolExpr(t, PDecl, AtLoc, RParenLoc); 1033acaa926c8f0d32da48db61a5fcb95276e6a4006Greg Clayton} 1043acaa926c8f0d32da48db61a5fcb95276e6a4006Greg Clayton 105952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Claytonbool Sema::CheckMessageArgumentTypes(Expr **Args, unsigned NumArgs, 1063acaa926c8f0d32da48db61a5fcb95276e6a4006Greg Clayton ObjCMethodDecl *Method) { 1073acaa926c8f0d32da48db61a5fcb95276e6a4006Greg Clayton bool anyIncompatibleArgs = false; 1083acaa926c8f0d32da48db61a5fcb95276e6a4006Greg Clayton 1093acaa926c8f0d32da48db61a5fcb95276e6a4006Greg Clayton for (unsigned i = 0; i < NumArgs; i++) { 1103acaa926c8f0d32da48db61a5fcb95276e6a4006Greg Clayton Expr *argExpr = Args[i]; 1113acaa926c8f0d32da48db61a5fcb95276e6a4006Greg Clayton assert(argExpr && "CheckMessageArgumentTypes(): missing expression"); 1123acaa926c8f0d32da48db61a5fcb95276e6a4006Greg Clayton 1133acaa926c8f0d32da48db61a5fcb95276e6a4006Greg Clayton QualType lhsType = Method->getParamDecl(i)->getType(); 114d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton QualType rhsType = argExpr->getType(); 1153acaa926c8f0d32da48db61a5fcb95276e6a4006Greg Clayton 1163acaa926c8f0d32da48db61a5fcb95276e6a4006Greg Clayton // If necessary, apply function/array conversion. C99 6.7.5.3p[7,8]. 1173acaa926c8f0d32da48db61a5fcb95276e6a4006Greg Clayton if (const ArrayType *ary = lhsType->getAsArrayType()) 1183acaa926c8f0d32da48db61a5fcb95276e6a4006Greg Clayton lhsType = Context.getPointerType(ary->getElementType()); 1193acaa926c8f0d32da48db61a5fcb95276e6a4006Greg Clayton else if (lhsType->isFunctionType()) 120d2f3b42f70f309f548c2b618c5991a905a00ec3aGreg Clayton lhsType = Context.getPointerType(lhsType); 121d2f3b42f70f309f548c2b618c5991a905a00ec3aGreg Clayton 122d2f3b42f70f309f548c2b618c5991a905a00ec3aGreg Clayton AssignConvertType Result = CheckSingleAssignmentConstraints(lhsType, 123d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton argExpr); 124d2f3b42f70f309f548c2b618c5991a905a00ec3aGreg Clayton if (Args[i] != argExpr) // The expression was converted. 125d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton Args[i] = argExpr; // Make sure we store the converted expression. 126d2f3b42f70f309f548c2b618c5991a905a00ec3aGreg Clayton 1277efa0885bbb5c2cc57d30242f63c154f6a25d372Greg Clayton anyIncompatibleArgs |= 128d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton DiagnoseAssignmentResult(Result, argExpr->getLocStart(), lhsType, rhsType, 1297efa0885bbb5c2cc57d30242f63c154f6a25d372Greg Clayton argExpr, "sending"); 1303acaa926c8f0d32da48db61a5fcb95276e6a4006Greg Clayton } 1317efa0885bbb5c2cc57d30242f63c154f6a25d372Greg Clayton return anyIncompatibleArgs; 132ea4626053e22d06f145ccbf3b154cc04eea8e770Greg Clayton} 1337efa0885bbb5c2cc57d30242f63c154f6a25d372Greg Clayton 134d2f3b42f70f309f548c2b618c5991a905a00ec3aGreg Clayton// ActOnClassMessage - used for both unary and keyword messages. 135d2f3b42f70f309f548c2b618c5991a905a00ec3aGreg Clayton// ArgExprs is optional - if it is present, the number of expressions 1367efa0885bbb5c2cc57d30242f63c154f6a25d372Greg Clayton// is obtained from Sel.getNumArgs(). 1377efa0885bbb5c2cc57d30242f63c154f6a25d372Greg ClaytonSema::ExprResult Sema::ActOnClassMessage( 1387efa0885bbb5c2cc57d30242f63c154f6a25d372Greg Clayton Scope *S, 1397efa0885bbb5c2cc57d30242f63c154f6a25d372Greg Clayton IdentifierInfo *receiverName, Selector Sel, 1407efa0885bbb5c2cc57d30242f63c154f6a25d372Greg Clayton SourceLocation lbrac, SourceLocation rbrac, ExprTy **Args, unsigned NumArgs) 1417efa0885bbb5c2cc57d30242f63c154f6a25d372Greg Clayton{ 1427efa0885bbb5c2cc57d30242f63c154f6a25d372Greg Clayton assert(receiverName && "missing receiver class name"); 1437efa0885bbb5c2cc57d30242f63c154f6a25d372Greg Clayton 1447efa0885bbb5c2cc57d30242f63c154f6a25d372Greg Clayton Expr **ArgExprs = reinterpret_cast<Expr **>(Args); 1457efa0885bbb5c2cc57d30242f63c154f6a25d372Greg Clayton ObjCInterfaceDecl* ClassDecl = 0; 1467efa0885bbb5c2cc57d30242f63c154f6a25d372Greg Clayton if (!strcmp(receiverName->getName(), "super") && CurMethodDecl) { 1477efa0885bbb5c2cc57d30242f63c154f6a25d372Greg Clayton ClassDecl = CurMethodDecl->getClassInterface()->getSuperClass(); 1487efa0885bbb5c2cc57d30242f63c154f6a25d372Greg Clayton if (!ClassDecl) 1497efa0885bbb5c2cc57d30242f63c154f6a25d372Greg Clayton return Diag(lbrac, diag::error_no_super_class, 150d2f3b42f70f309f548c2b618c5991a905a00ec3aGreg Clayton CurMethodDecl->getClassInterface()->getName()); 1517efa0885bbb5c2cc57d30242f63c154f6a25d372Greg Clayton if (CurMethodDecl->isInstance()) { 1527efa0885bbb5c2cc57d30242f63c154f6a25d372Greg Clayton // Synthesize a cast to the super class. This hack allows us to loosely 1537efa0885bbb5c2cc57d30242f63c154f6a25d372Greg Clayton // represent super without creating a special expression node. 1547efa0885bbb5c2cc57d30242f63c154f6a25d372Greg Clayton IdentifierInfo &II = Context.Idents.get("self"); 1557efa0885bbb5c2cc57d30242f63c154f6a25d372Greg Clayton ExprResult ReceiverExpr = ActOnIdentifierExpr(S, lbrac, II, false); 1567efa0885bbb5c2cc57d30242f63c154f6a25d372Greg Clayton QualType superTy = Context.getObjCInterfaceType(ClassDecl); 1577efa0885bbb5c2cc57d30242f63c154f6a25d372Greg Clayton superTy = Context.getPointerType(superTy); 1587efa0885bbb5c2cc57d30242f63c154f6a25d372Greg Clayton ReceiverExpr = ActOnCastExpr(SourceLocation(), superTy.getAsOpaquePtr(), 1597efa0885bbb5c2cc57d30242f63c154f6a25d372Greg Clayton SourceLocation(), ReceiverExpr.Val); 1607efa0885bbb5c2cc57d30242f63c154f6a25d372Greg Clayton // We are really in an instance method, redirect. 1617efa0885bbb5c2cc57d30242f63c154f6a25d372Greg Clayton return ActOnInstanceMessage(ReceiverExpr.Val, Sel, lbrac, rbrac, 1627efa0885bbb5c2cc57d30242f63c154f6a25d372Greg Clayton Args, NumArgs); 1637efa0885bbb5c2cc57d30242f63c154f6a25d372Greg Clayton } 1647efa0885bbb5c2cc57d30242f63c154f6a25d372Greg Clayton // We are sending a message to 'super' within a class method. Do nothing, 1657efa0885bbb5c2cc57d30242f63c154f6a25d372Greg Clayton // the receiver will pass through as 'super' (how convenient:-). 1667efa0885bbb5c2cc57d30242f63c154f6a25d372Greg Clayton } else 1677efa0885bbb5c2cc57d30242f63c154f6a25d372Greg Clayton ClassDecl = getObjCInterfaceDecl(receiverName); 1687efa0885bbb5c2cc57d30242f63c154f6a25d372Greg Clayton 1693acaa926c8f0d32da48db61a5fcb95276e6a4006Greg Clayton // FIXME: can ClassDecl ever be null? 170d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton ObjCMethodDecl *Method = ClassDecl->lookupClassMethod(Sel); 171d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton QualType returnType; 172d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton 173d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton // Before we give up, check if the selector is an instance method. 174d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton if (!Method) 175d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton Method = ClassDecl->lookupInstanceMethod(Sel); 176363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton if (!Method) { 1771e5b02176d6952d0679479926fa557534313472bGreg Clayton Diag(lbrac, diag::warn_method_not_found, std::string("+"), Sel.getName(), 178d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton SourceRange(lbrac, rbrac)); 179363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton returnType = Context.getObjCIdType(); 180363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton } else { 181363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton returnType = Method->getResultType(); 1821e5b02176d6952d0679479926fa557534313472bGreg Clayton if (Sel.getNumArgs()) { 1831e5b02176d6952d0679479926fa557534313472bGreg Clayton if (CheckMessageArgumentTypes(ArgExprs, Sel.getNumArgs(), Method)) 184363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton return true; 185952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton } 186363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton } 187363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton return new ObjCMessageExpr(receiverName, Sel, returnType, Method, 1880fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton lbrac, rbrac, ArgExprs, NumArgs); 1890fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton} 1900fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton 191363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton// ActOnInstanceMessage - used for both unary and keyword messages. 1921e5b02176d6952d0679479926fa557534313472bGreg Clayton// ArgExprs is optional - if it is present, the number of expressions 193363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton// is obtained from Sel.getNumArgs(). 1941e5b02176d6952d0679479926fa557534313472bGreg ClaytonSema::ExprResult Sema::ActOnInstanceMessage( 1951e5b02176d6952d0679479926fa557534313472bGreg Clayton ExprTy *receiver, Selector Sel, 1961e5b02176d6952d0679479926fa557534313472bGreg Clayton SourceLocation lbrac, SourceLocation rbrac, ExprTy **Args, unsigned NumArgs) 1971e5b02176d6952d0679479926fa557534313472bGreg Clayton{ 1981e5b02176d6952d0679479926fa557534313472bGreg Clayton assert(receiver && "missing receiver expression"); 1991e5b02176d6952d0679479926fa557534313472bGreg Clayton 2001e5b02176d6952d0679479926fa557534313472bGreg Clayton Expr **ArgExprs = reinterpret_cast<Expr **>(Args); 2011e5b02176d6952d0679479926fa557534313472bGreg Clayton Expr *RExpr = static_cast<Expr *>(receiver); 2021e5b02176d6952d0679479926fa557534313472bGreg Clayton QualType receiverType = RExpr->getType().getCanonicalType(); 2035f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea QualType returnType; 2041e5b02176d6952d0679479926fa557534313472bGreg Clayton ObjCMethodDecl *Method = 0; 2051e5b02176d6952d0679479926fa557534313472bGreg Clayton 206363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton // FIXME: This code is not stripping off type qualifiers! Should it? 207363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton if (receiverType == Context.getObjCIdType().getCanonicalType() || 208363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton receiverType == Context.getObjCClassType().getCanonicalType()) { 209516f0849819d094d4eab39a1f27b770259103ff8Greg Clayton Method = InstanceMethodPool[Sel].Method; 210363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton if (!Method) 2111b584ebc1de8b50fe375cffb5fb33ad13be10046Jim Ingham Method = FactoryMethodPool[Sel].Method; 212363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton if (!Method) { 213363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton Diag(lbrac, diag::warn_method_not_found, std::string("-"), Sel.getName(), 214363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton SourceRange(lbrac, rbrac)); 215363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton returnType = Context.getObjCIdType(); 216363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton } else { 217363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton returnType = Method->getResultType(); 2183acaa926c8f0d32da48db61a5fcb95276e6a4006Greg Clayton if (Sel.getNumArgs()) 219363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton if (CheckMessageArgumentTypes(ArgExprs, Sel.getNumArgs(), Method)) 220363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton return true; 221363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton } 222d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton } else { 223363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton bool receiverIsQualId = isa<ObjCQualifiedIdType>(receiverType); 224363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton // FIXME (snaroff): checking in this code from Patrick. Needs to be 225363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton // revisited. how do we get the ClassDecl from the receiver expression? 226363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton if (!receiverIsQualId) 227363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton while (const PointerType *PTy = receiverType->getAsPointerType()) 228363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton receiverType = PTy->getPointeeType(); 229d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton 230363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton ObjCInterfaceDecl* ClassDecl = 0; 231363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton if (ObjCQualifiedInterfaceType *QIT = 232363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton dyn_cast<ObjCQualifiedInterfaceType>(receiverType)) { 233363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton ClassDecl = QIT->getDecl(); 234952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton Method = ClassDecl->lookupInstanceMethod(Sel); 235363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton if (!Method) { 236363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton // search protocols 237363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton for (unsigned i = 0; i < QIT->getNumProtocols(); i++) { 238d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton ObjCProtocolDecl *PDecl = QIT->getProtocols(i); 239363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton if (PDecl && (Method = PDecl->lookupInstanceMethod(Sel))) 240363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton break; 241363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton } 242363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton } 2431e3a522380565640ec900979b8532500bd3004c5Johnny Chen if (!Method) 244363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton Diag(lbrac, diag::warn_method_not_found_in_protocol, 245363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton std::string("-"), Sel.getName(), 246363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton SourceRange(lbrac, rbrac)); 2475f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea } 248363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton else if (ObjCQualifiedIdType *QIT = 249363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton dyn_cast<ObjCQualifiedIdType>(receiverType)) { 250363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton // search protocols 251363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton for (unsigned i = 0; i < QIT->getNumProtocols(); i++) { 252851e30ec6a1b1d2c154bb7d69ed0d05b5fd14705Greg Clayton ObjCProtocolDecl *PDecl = QIT->getProtocols(i); 253363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton if (PDecl && (Method = PDecl->lookupInstanceMethod(Sel))) 254363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton break; 255363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton } 256363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton if (!Method) 257d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton Diag(lbrac, diag::warn_method_not_found_in_protocol, 258363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton std::string("-"), Sel.getName(), 259363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton SourceRange(lbrac, rbrac)); 260363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton } 261363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton else { 262363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton ObjCInterfaceType *OCIReceiver =dyn_cast<ObjCInterfaceType>(receiverType); 263363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton if (OCIReceiver == 0) { 264363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton Diag(lbrac, diag::error_bad_receiver_type, 265363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton RExpr->getType().getAsString()); 266363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton return true; 267363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton } 268363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton ClassDecl = OCIReceiver->getDecl(); 269363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton // FIXME: consider using InstanceMethodPool, since it will be faster 270363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton // than the following method (which can do *many* linear searches). The 271363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton // idea is to add class info to InstanceMethodPool... 272363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton Method = ClassDecl->lookupInstanceMethod(Sel); 273363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton } 274363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton if (!Method) { 275363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton // If we have an implementation in scope, check "private" methods. 276363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton if (ClassDecl) 277363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton if (ObjCImplementationDecl *ImpDecl = 278363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton ObjCImplementations[ClassDecl->getIdentifier()]) 279363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton Method = ImpDecl->getInstanceMethod(Sel); 280363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton // If we still haven't found a method, look in the global pool. This 281363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton // behavior isn't very desirable, however we need it for GCC 282363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton // compatibility. 283363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton if (!Method) 284d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton Method = InstanceMethodPool[Sel].Method; 285363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton } 286363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton if (!Method) { 287363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton Diag(lbrac, diag::warn_method_not_found, std::string("-"), Sel.getName(), 288363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton SourceRange(lbrac, rbrac)); 289952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton returnType = Context.getObjCIdType(); 290363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton } else { 291363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton returnType = Method->getResultType(); 292363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton if (Sel.getNumArgs()) 293363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton if (CheckMessageArgumentTypes(ArgExprs, Sel.getNumArgs(), Method)) 294363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton return true; 295d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton } 2968d2ea2888a4acb7f140f9af64ddd2b16b2dee870Greg Clayton } 297d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton return new ObjCMessageExpr(RExpr, Sel, returnType, Method, lbrac, rbrac, 298363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton ArgExprs, NumArgs); 299363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton} 300d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton