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