ExprObjC.h revision f242b1b0c4e998911cb96b2ba7e27ab4a5abaed3
1//===--- ExprObjC.h - Classes for representing ObjC expressions -*- C++ -*-===// 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 defines the ExprObjC interface and subclasses. 11// 12//===----------------------------------------------------------------------===// 13 14#ifndef LLVM_CLANG_AST_EXPROBJC_H 15#define LLVM_CLANG_AST_EXPROBJC_H 16 17#include "clang/AST/Expr.h" 18#include "clang/Basic/IdentifierTable.h" 19 20namespace clang { 21 class IdentifierInfo; 22 class ASTContext; 23 class ObjCMethodDecl; 24 class ObjCPropertyDecl; 25 26/// ObjCStringLiteral, used for Objective-C string literals 27/// i.e. @"foo". 28class ObjCStringLiteral : public Expr { 29 Stmt *String; 30 SourceLocation AtLoc; 31public: 32 ObjCStringLiteral(StringLiteral *SL, QualType T, SourceLocation L) 33 : Expr(ObjCStringLiteralClass, T), String(SL), AtLoc(L) {} 34 explicit ObjCStringLiteral(EmptyShell Empty) 35 : Expr(ObjCStringLiteralClass, Empty) {} 36 37 ObjCStringLiteral* Clone(ASTContext &C) const; 38 39 StringLiteral *getString() { return cast<StringLiteral>(String); } 40 const StringLiteral *getString() const { return cast<StringLiteral>(String); } 41 void setString(StringLiteral *S) { String = S; } 42 43 SourceLocation getAtLoc() const { return AtLoc; } 44 void setAtLoc(SourceLocation L) { AtLoc = L; } 45 46 virtual SourceRange getSourceRange() const { 47 return SourceRange(AtLoc, String->getLocEnd()); 48 } 49 50 static bool classof(const Stmt *T) { 51 return T->getStmtClass() == ObjCStringLiteralClass; 52 } 53 static bool classof(const ObjCStringLiteral *) { return true; } 54 55 // Iterators 56 virtual child_iterator child_begin(); 57 virtual child_iterator child_end(); 58}; 59 60/// ObjCEncodeExpr, used for @encode in Objective-C. @encode has the same type 61/// and behavior as StringLiteral except that the string initializer is obtained 62/// from ASTContext with the encoding type as an argument. 63class ObjCEncodeExpr : public Expr { 64 QualType EncType; 65 SourceLocation AtLoc, RParenLoc; 66public: 67 ObjCEncodeExpr(QualType T, QualType ET, 68 SourceLocation at, SourceLocation rp) 69 : Expr(ObjCEncodeExprClass, T, ET->isDependentType(), 70 ET->isDependentType()), EncType(ET), AtLoc(at), RParenLoc(rp) {} 71 72 explicit ObjCEncodeExpr(EmptyShell Empty) : Expr(ObjCEncodeExprClass, Empty){} 73 74 75 SourceLocation getAtLoc() const { return AtLoc; } 76 void setAtLoc(SourceLocation L) { AtLoc = L; } 77 SourceLocation getRParenLoc() const { return RParenLoc; } 78 void setRParenLoc(SourceLocation L) { RParenLoc = L; } 79 80 QualType getEncodedType() const { return EncType; } 81 void setEncodedType(QualType T) { EncType = T; } 82 83 84 virtual SourceRange getSourceRange() const { 85 return SourceRange(AtLoc, RParenLoc); 86 } 87 88 static bool classof(const Stmt *T) { 89 return T->getStmtClass() == ObjCEncodeExprClass; 90 } 91 static bool classof(const ObjCEncodeExpr *) { return true; } 92 93 // Iterators 94 virtual child_iterator child_begin(); 95 virtual child_iterator child_end(); 96}; 97 98/// ObjCSelectorExpr used for @selector in Objective-C. 99class ObjCSelectorExpr : public Expr { 100 Selector SelName; 101 SourceLocation AtLoc, RParenLoc; 102public: 103 ObjCSelectorExpr(QualType T, Selector selInfo, 104 SourceLocation at, SourceLocation rp) 105 : Expr(ObjCSelectorExprClass, T), SelName(selInfo), AtLoc(at), RParenLoc(rp){} 106 explicit ObjCSelectorExpr(EmptyShell Empty) 107 : Expr(ObjCSelectorExprClass, Empty) {} 108 109 ObjCSelectorExpr *Clone(ASTContext &C) const; 110 111 Selector getSelector() const { return SelName; } 112 void setSelector(Selector S) { SelName = S; } 113 114 SourceLocation getAtLoc() const { return AtLoc; } 115 SourceLocation getRParenLoc() const { return RParenLoc; } 116 void setAtLoc(SourceLocation L) { AtLoc = L; } 117 void setRParenLoc(SourceLocation L) { RParenLoc = L; } 118 119 virtual SourceRange getSourceRange() const { 120 return SourceRange(AtLoc, RParenLoc); 121 } 122 123 /// getNumArgs - Return the number of actual arguments to this call. 124 unsigned getNumArgs() const { return SelName.getNumArgs(); } 125 126 static bool classof(const Stmt *T) { 127 return T->getStmtClass() == ObjCSelectorExprClass; 128 } 129 static bool classof(const ObjCSelectorExpr *) { return true; } 130 131 // Iterators 132 virtual child_iterator child_begin(); 133 virtual child_iterator child_end(); 134}; 135 136/// ObjCProtocolExpr used for protocol expression in Objective-C. This is used 137/// as: @protocol(foo), as in: 138/// obj conformsToProtocol:@protocol(foo)] 139/// The return type is "Protocol*". 140class ObjCProtocolExpr : public Expr { 141 ObjCProtocolDecl *TheProtocol; 142 SourceLocation AtLoc, RParenLoc; 143public: 144 ObjCProtocolExpr(QualType T, ObjCProtocolDecl *protocol, 145 SourceLocation at, SourceLocation rp) 146 : Expr(ObjCProtocolExprClass, T), TheProtocol(protocol), 147 AtLoc(at), RParenLoc(rp) {} 148 explicit ObjCProtocolExpr(EmptyShell Empty) 149 : Expr(ObjCProtocolExprClass, Empty) {} 150 151 ObjCProtocolExpr *Clone(ASTContext &C) const; 152 153 ObjCProtocolDecl *getProtocol() const { return TheProtocol; } 154 void setProtocol(ObjCProtocolDecl *P) { TheProtocol = P; } 155 156 SourceLocation getAtLoc() const { return AtLoc; } 157 SourceLocation getRParenLoc() const { return RParenLoc; } 158 void setAtLoc(SourceLocation L) { AtLoc = L; } 159 void setRParenLoc(SourceLocation L) { RParenLoc = L; } 160 161 virtual SourceRange getSourceRange() const { 162 return SourceRange(AtLoc, RParenLoc); 163 } 164 165 static bool classof(const Stmt *T) { 166 return T->getStmtClass() == ObjCProtocolExprClass; 167 } 168 static bool classof(const ObjCProtocolExpr *) { return true; } 169 170 // Iterators 171 virtual child_iterator child_begin(); 172 virtual child_iterator child_end(); 173}; 174 175/// ObjCIvarRefExpr - A reference to an ObjC instance variable. 176class ObjCIvarRefExpr : public Expr { 177 class ObjCIvarDecl *D; 178 SourceLocation Loc; 179 Stmt *Base; 180 bool IsArrow:1; // True if this is "X->F", false if this is "X.F". 181 bool IsFreeIvar:1; // True if ivar reference has no base (self assumed). 182 183public: 184 ObjCIvarRefExpr(ObjCIvarDecl *d, 185 QualType t, SourceLocation l, Expr *base=0, 186 bool arrow = false, bool freeIvar = false) : 187 Expr(ObjCIvarRefExprClass, t), D(d), 188 Loc(l), Base(base), IsArrow(arrow), 189 IsFreeIvar(freeIvar) {} 190 191 explicit ObjCIvarRefExpr(EmptyShell Empty) 192 : Expr(ObjCIvarRefExprClass, Empty) {} 193 194 ObjCIvarDecl *getDecl() { return D; } 195 const ObjCIvarDecl *getDecl() const { return D; } 196 void setDecl(ObjCIvarDecl *d) { D = d; } 197 198 const Expr *getBase() const { return cast<Expr>(Base); } 199 Expr *getBase() { return cast<Expr>(Base); } 200 void setBase(Expr * base) { Base = base; } 201 202 bool isArrow() const { return IsArrow; } 203 bool isFreeIvar() const { return IsFreeIvar; } 204 void setIsArrow(bool A) { IsArrow = A; } 205 void setIsFreeIvar(bool A) { IsFreeIvar = A; } 206 207 SourceLocation getLocation() const { return Loc; } 208 void setLocation(SourceLocation L) { Loc = L; } 209 210 virtual SourceRange getSourceRange() const { 211 return isFreeIvar() ? SourceRange(Loc) 212 : SourceRange(getBase()->getLocStart(), Loc); 213 } 214 215 static bool classof(const Stmt *T) { 216 return T->getStmtClass() == ObjCIvarRefExprClass; 217 } 218 static bool classof(const ObjCIvarRefExpr *) { return true; } 219 220 // Iterators 221 virtual child_iterator child_begin(); 222 virtual child_iterator child_end(); 223}; 224 225/// ObjCPropertyRefExpr - A dot-syntax expression to access an ObjC 226/// property. 227/// 228class ObjCPropertyRefExpr : public Expr { 229private: 230 ObjCPropertyDecl *AsProperty; 231 SourceLocation IdLoc; 232 Stmt *Base; 233public: 234 ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t, 235 SourceLocation l, Expr *base) 236 : Expr(ObjCPropertyRefExprClass, t), AsProperty(PD), IdLoc(l), Base(base) { 237 } 238 239 explicit ObjCPropertyRefExpr(EmptyShell Empty) 240 : Expr(ObjCPropertyRefExprClass, Empty) {} 241 242 ObjCPropertyDecl *getProperty() const { return AsProperty; } 243 void setProperty(ObjCPropertyDecl *D) { AsProperty = D; } 244 245 const Expr *getBase() const { return cast<Expr>(Base); } 246 Expr *getBase() { return cast<Expr>(Base); } 247 void setBase(Expr *base) { Base = base; } 248 249 SourceLocation getLocation() const { return IdLoc; } 250 void setLocation(SourceLocation L) { IdLoc = L; } 251 252 virtual SourceRange getSourceRange() const { 253 return SourceRange(getBase()->getLocStart(), IdLoc); 254 } 255 256 static bool classof(const Stmt *T) { 257 return T->getStmtClass() == ObjCPropertyRefExprClass; 258 } 259 static bool classof(const ObjCPropertyRefExpr *) { return true; } 260 261 // Iterators 262 virtual child_iterator child_begin(); 263 virtual child_iterator child_end(); 264}; 265 266/// ObjCKVCRefExpr - A dot-syntax expression to access "implicit" properties 267/// (i.e. methods following the property naming convention). KVC stands for 268/// Key Value Encoding, a generic concept for accessing or setting a 'Key' 269/// value for an object. 270/// 271class ObjCKVCRefExpr : public Expr { 272 ObjCMethodDecl *Setter; 273 ObjCMethodDecl *Getter; 274 SourceLocation Loc; 275 // FIXME: Swizzle these into a single pointer. 276 Stmt *Base; 277 ObjCInterfaceDecl *ClassProp; 278 SourceLocation ClassLoc; 279 280public: 281 ObjCKVCRefExpr(ObjCMethodDecl *getter, 282 QualType t, 283 ObjCMethodDecl *setter, 284 SourceLocation l, Expr *base) 285 : Expr(ObjCKVCRefExprClass, t), Setter(setter), 286 Getter(getter), Loc(l), Base(base), ClassProp(0), 287 ClassLoc(SourceLocation()) { 288 } 289 ObjCKVCRefExpr(ObjCMethodDecl *getter, 290 QualType t, 291 ObjCMethodDecl *setter, 292 SourceLocation l, ObjCInterfaceDecl *C, SourceLocation CL) 293 : Expr(ObjCKVCRefExprClass, t), Setter(setter), 294 Getter(getter), Loc(l), Base(0), ClassProp(C), ClassLoc(CL) { 295 } 296 explicit ObjCKVCRefExpr(EmptyShell Empty) : Expr(ObjCKVCRefExprClass, Empty){} 297 298 ObjCMethodDecl *getGetterMethod() const { return Getter; } 299 ObjCMethodDecl *getSetterMethod() const { return Setter; } 300 ObjCInterfaceDecl *getClassProp() const { return ClassProp; } 301 void setGetterMethod(ObjCMethodDecl *D) { Getter = D; } 302 void setSetterMethod(ObjCMethodDecl *D) { Setter = D; } 303 void setClassProp(ObjCInterfaceDecl *D) { ClassProp = D; } 304 305 virtual SourceRange getSourceRange() const { 306 if (Base) 307 return SourceRange(getBase()->getLocStart(), Loc); 308 return SourceRange(ClassLoc, Loc); 309 } 310 const Expr *getBase() const { return cast_or_null<Expr>(Base); } 311 Expr *getBase() { return cast_or_null<Expr>(Base); } 312 void setBase(Expr *base) { Base = base; } 313 314 SourceLocation getLocation() const { return Loc; } 315 void setLocation(SourceLocation L) { Loc = L; } 316 SourceLocation getClassLoc() const { return ClassLoc; } 317 void setClassLoc(SourceLocation L) { ClassLoc = L; } 318 319 static bool classof(const Stmt *T) { 320 return T->getStmtClass() == ObjCKVCRefExprClass; 321 } 322 static bool classof(const ObjCKVCRefExpr *) { return true; } 323 324 // Iterators 325 virtual child_iterator child_begin(); 326 virtual child_iterator child_end(); 327}; 328 329class ObjCMessageExpr : public Expr { 330 // SubExprs - The receiver and arguments of the message expression. 331 Stmt **SubExprs; 332 333 // NumArgs - The number of arguments (not including the receiver) to the 334 // message expression. 335 unsigned NumArgs; 336 337 // A unigue name for this message. 338 Selector SelName; 339 340 // A method prototype for this message (optional). 341 // FIXME: Since method decls contain the selector, and most messages have a 342 // prototype, consider devising a scheme for unifying SelName/MethodProto. 343 ObjCMethodDecl *MethodProto; 344 345 SourceLocation LBracloc, RBracloc; 346 347 // Constants for indexing into SubExprs. 348 enum { RECEIVER=0, ARGS_START=1 }; 349 350 // Bit-swizzling flags. 351 enum { IsInstMeth=0, IsClsMethDeclUnknown, IsClsMethDeclKnown, Flags=0x3 }; 352 unsigned getFlag() const { return (uintptr_t) SubExprs[RECEIVER] & Flags; } 353 354public: 355 /// This constructor is used to represent class messages where the 356 /// ObjCInterfaceDecl* of the receiver is not known. 357 ObjCMessageExpr(IdentifierInfo *clsName, Selector selInfo, 358 QualType retType, ObjCMethodDecl *methDecl, 359 SourceLocation LBrac, SourceLocation RBrac, 360 Expr **ArgExprs, unsigned NumArgs); 361 362 /// This constructor is used to represent class messages where the 363 /// ObjCInterfaceDecl* of the receiver is known. 364 // FIXME: clsName should be typed to ObjCInterfaceType 365 ObjCMessageExpr(ObjCInterfaceDecl *cls, Selector selInfo, 366 QualType retType, ObjCMethodDecl *methDecl, 367 SourceLocation LBrac, SourceLocation RBrac, 368 Expr **ArgExprs, unsigned NumArgs); 369 370 // constructor for instance messages. 371 ObjCMessageExpr(Expr *receiver, Selector selInfo, 372 QualType retType, ObjCMethodDecl *methDecl, 373 SourceLocation LBrac, SourceLocation RBrac, 374 Expr **ArgExprs, unsigned NumArgs); 375 376 explicit ObjCMessageExpr(EmptyShell Empty) 377 : Expr(ObjCMessageExprClass, Empty), SubExprs(0), NumArgs(0) {} 378 379 ~ObjCMessageExpr() { 380 delete [] SubExprs; 381 } 382 383 /// getReceiver - Returns the receiver of the message expression. 384 /// This can be NULL if the message is for class methods. For 385 /// class methods, use getClassName. 386 /// FIXME: need to handle/detect 'super' usage within a class method. 387 Expr *getReceiver() { 388 uintptr_t x = (uintptr_t) SubExprs[RECEIVER]; 389 return (x & Flags) == IsInstMeth ? (Expr*) x : 0; 390 } 391 const Expr *getReceiver() const { 392 return const_cast<ObjCMessageExpr*>(this)->getReceiver(); 393 } 394 // FIXME: need setters for different receiver types. 395 void setReceiver(Expr *rec) { SubExprs[RECEIVER] = rec; } 396 Selector getSelector() const { return SelName; } 397 void setSelector(Selector S) { SelName = S; } 398 399 const ObjCMethodDecl *getMethodDecl() const { return MethodProto; } 400 ObjCMethodDecl *getMethodDecl() { return MethodProto; } 401 void setMethodDecl(ObjCMethodDecl *MD) { MethodProto = MD; } 402 403 typedef std::pair<ObjCInterfaceDecl*, IdentifierInfo*> ClassInfo; 404 405 /// getClassInfo - For class methods, this returns both the ObjCInterfaceDecl* 406 /// and IdentifierInfo* of the invoked class. Both can be NULL if this 407 /// is an instance message, and the ObjCInterfaceDecl* can be NULL if none 408 /// was available when this ObjCMessageExpr object was constructed. 409 ClassInfo getClassInfo() const; 410 void setClassInfo(const ClassInfo &C); 411 412 /// getClassName - For class methods, this returns the invoked class, 413 /// and returns NULL otherwise. For instance methods, use getReceiver. 414 IdentifierInfo *getClassName() const { 415 return getClassInfo().second; 416 } 417 418 /// getNumArgs - Return the number of actual arguments to this call. 419 unsigned getNumArgs() const { return NumArgs; } 420 void setNumArgs(unsigned nArgs) { 421 NumArgs = nArgs; 422 // FIXME: should always allocate SubExprs via the ASTContext's 423 // allocator. 424 if (!SubExprs) 425 SubExprs = new Stmt* [NumArgs + 1]; 426 } 427 428 /// getArg - Return the specified argument. 429 Expr *getArg(unsigned Arg) { 430 assert(Arg < NumArgs && "Arg access out of range!"); 431 return cast<Expr>(SubExprs[Arg+ARGS_START]); 432 } 433 const Expr *getArg(unsigned Arg) const { 434 assert(Arg < NumArgs && "Arg access out of range!"); 435 return cast<Expr>(SubExprs[Arg+ARGS_START]); 436 } 437 /// setArg - Set the specified argument. 438 void setArg(unsigned Arg, Expr *ArgExpr) { 439 assert(Arg < NumArgs && "Arg access out of range!"); 440 SubExprs[Arg+ARGS_START] = ArgExpr; 441 } 442 443 SourceLocation getLeftLoc() const { return LBracloc; } 444 SourceLocation getRightLoc() const { return RBracloc; } 445 446 void setLeftLoc(SourceLocation L) { LBracloc = L; } 447 void setRightLoc(SourceLocation L) { RBracloc = L; } 448 449 void setSourceRange(SourceRange R) { 450 LBracloc = R.getBegin(); 451 RBracloc = R.getEnd(); 452 } 453 virtual SourceRange getSourceRange() const { 454 return SourceRange(LBracloc, RBracloc); 455 } 456 457 static bool classof(const Stmt *T) { 458 return T->getStmtClass() == ObjCMessageExprClass; 459 } 460 static bool classof(const ObjCMessageExpr *) { return true; } 461 462 // Iterators 463 virtual child_iterator child_begin(); 464 virtual child_iterator child_end(); 465 466 typedef ExprIterator arg_iterator; 467 typedef ConstExprIterator const_arg_iterator; 468 469 arg_iterator arg_begin() { return &SubExprs[ARGS_START]; } 470 arg_iterator arg_end() { return &SubExprs[ARGS_START] + NumArgs; } 471 const_arg_iterator arg_begin() const { return &SubExprs[ARGS_START]; } 472 const_arg_iterator arg_end() const { return &SubExprs[ARGS_START] + NumArgs; } 473}; 474 475/// ObjCSuperExpr - Represents the "super" expression in Objective-C, 476/// which refers to the object on which the current method is executing. 477class ObjCSuperExpr : public Expr { 478 SourceLocation Loc; 479public: 480 ObjCSuperExpr(SourceLocation L, QualType Type) 481 : Expr(ObjCSuperExprClass, Type), Loc(L) { } 482 explicit ObjCSuperExpr(EmptyShell Empty) : Expr(ObjCSuperExprClass, Empty) {} 483 484 SourceLocation getLoc() const { return Loc; } 485 void setLoc(SourceLocation L) { Loc = L; } 486 487 virtual SourceRange getSourceRange() const { return SourceRange(Loc); } 488 489 static bool classof(const Stmt *T) { 490 return T->getStmtClass() == ObjCSuperExprClass; 491 } 492 static bool classof(const ObjCSuperExpr *) { return true; } 493 494 // Iterators 495 virtual child_iterator child_begin(); 496 virtual child_iterator child_end(); 497}; 498 499/// ObjCIsaExpr - Represent X->isa and X.isa (similiar in spirit to MemberExpr). 500class ObjCIsaExpr : public Expr { 501 /// Base - the expression for the base object pointer. 502 Stmt *Base; 503 504 /// IsaMemberLoc - This is the location of the 'isa'. 505 SourceLocation IsaMemberLoc; 506 507 /// IsArrow - True if this is "X->F", false if this is "X.F". 508 bool IsArrow; 509public: 510 ObjCIsaExpr(Expr *base, bool isarrow, SourceLocation l, QualType ty) 511 : Expr(ObjCIsaExprClass, ty), 512 Base(base), IsaMemberLoc(l), IsArrow(isarrow) {} 513 514 /// \brief Build an empty expression. 515 explicit ObjCIsaExpr(EmptyShell Empty) : Expr(ObjCIsaExprClass, Empty) { } 516 517 void setBase(Expr *E) { Base = E; } 518 Expr *getBase() const { return cast<Expr>(Base); } 519 520 bool isArrow() const { return IsArrow; } 521 void setArrow(bool A) { IsArrow = A; } 522 523 /// getMemberLoc - Return the location of the "member", in X->F, it is the 524 /// location of 'F'. 525 SourceLocation getIsaMemberLoc() const { return IsaMemberLoc; } 526 void setIsaMemberLoc(SourceLocation L) { IsaMemberLoc = L; } 527 528 virtual SourceRange getSourceRange() const { 529 return SourceRange(getBase()->getLocStart(), IsaMemberLoc); 530 } 531 532 virtual SourceLocation getExprLoc() const { return IsaMemberLoc; } 533 534 static bool classof(const Stmt *T) { 535 return T->getStmtClass() == ObjCIsaExprClass; 536 } 537 static bool classof(const ObjCIsaExpr *) { return true; } 538 539 // Iterators 540 virtual child_iterator child_begin(); 541 virtual child_iterator child_end(); 542}; 543 544} // end namespace clang 545 546#endif 547