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