ExprObjC.h revision 5fae1d67ac199755dd26a102e1bddc881edab19c
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 TypeSourceInfo *EncodedType; 63 SourceLocation AtLoc, RParenLoc; 64public: 65 ObjCEncodeExpr(QualType T, TypeSourceInfo *EncodedType, 66 SourceLocation at, SourceLocation rp) 67 : Expr(ObjCEncodeExprClass, T, EncodedType->getType()->isDependentType(), 68 EncodedType->getType()->isDependentType()), 69 EncodedType(EncodedType), AtLoc(at), RParenLoc(rp) {} 70 71 explicit ObjCEncodeExpr(EmptyShell Empty) : Expr(ObjCEncodeExprClass, Empty){} 72 73 74 SourceLocation getAtLoc() const { return AtLoc; } 75 void setAtLoc(SourceLocation L) { AtLoc = L; } 76 SourceLocation getRParenLoc() const { return RParenLoc; } 77 void setRParenLoc(SourceLocation L) { RParenLoc = L; } 78 79 QualType getEncodedType() const { return EncodedType->getType(); } 80 81 TypeSourceInfo *getEncodedTypeSourceInfo() const { return EncodedType; } 82 void setEncodedTypeSourceInfo(TypeSourceInfo *EncType) { 83 EncodedType = EncType; 84 } 85 86 virtual SourceRange getSourceRange() const { 87 return SourceRange(AtLoc, RParenLoc); 88 } 89 90 static bool classof(const Stmt *T) { 91 return T->getStmtClass() == ObjCEncodeExprClass; 92 } 93 static bool classof(const ObjCEncodeExpr *) { return true; } 94 95 // Iterators 96 virtual child_iterator child_begin(); 97 virtual child_iterator child_end(); 98}; 99 100/// ObjCSelectorExpr used for @selector in Objective-C. 101class ObjCSelectorExpr : public Expr { 102 Selector SelName; 103 SourceLocation AtLoc, RParenLoc; 104public: 105 ObjCSelectorExpr(QualType T, Selector selInfo, 106 SourceLocation at, SourceLocation rp) 107 : Expr(ObjCSelectorExprClass, T, false, false), SelName(selInfo), AtLoc(at), 108 RParenLoc(rp){} 109 explicit ObjCSelectorExpr(EmptyShell Empty) 110 : Expr(ObjCSelectorExprClass, Empty) {} 111 112 Selector getSelector() const { return SelName; } 113 void setSelector(Selector S) { SelName = S; } 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 /// \brief The number of arguments in the message send, not 348 /// including the receiver. 349 unsigned NumArgs : 16; 350 351 /// \brief The kind of message send this is, which is one of the 352 /// ReceiverKind values. 353 /// 354 /// We pad this out to a byte to avoid excessive masking and shifting. 355 unsigned Kind : 8; 356 357 /// \brief Whether we have an actual method prototype in \c 358 /// SelectorOrMethod. 359 /// 360 /// When non-zero, we have a method declaration; otherwise, we just 361 /// have a selector. 362 unsigned HasMethod : 8; 363 364 /// \brief When the message expression is a send to 'super', this is 365 /// the location of the 'super' keyword. 366 SourceLocation SuperLoc; 367 368 /// \brief Stores either the selector that this message is sending 369 /// to (when \c HasMethod is zero) or an \c ObjCMethodDecl pointer 370 /// referring to the method that we type-checked against. 371 uintptr_t SelectorOrMethod; 372 373 /// \brief The source locations of the open and close square 374 /// brackets ('[' and ']', respectively). 375 SourceLocation LBracLoc, RBracLoc; 376 377 ObjCMessageExpr(EmptyShell Empty, unsigned NumArgs) 378 : Expr(ObjCMessageExprClass, Empty), NumArgs(NumArgs), Kind(0), 379 HasMethod(0), SelectorOrMethod(0) { } 380 381 ObjCMessageExpr(QualType T, 382 SourceLocation LBracLoc, 383 SourceLocation SuperLoc, 384 bool IsInstanceSuper, 385 QualType SuperType, 386 Selector Sel, 387 ObjCMethodDecl *Method, 388 Expr **Args, unsigned NumArgs, 389 SourceLocation RBracLoc); 390 ObjCMessageExpr(QualType T, 391 SourceLocation LBracLoc, 392 TypeSourceInfo *Receiver, 393 Selector Sel, 394 ObjCMethodDecl *Method, 395 Expr **Args, unsigned NumArgs, 396 SourceLocation RBracLoc); 397 ObjCMessageExpr(QualType T, 398 SourceLocation LBracLoc, 399 Expr *Receiver, 400 Selector Sel, 401 ObjCMethodDecl *Method, 402 Expr **Args, unsigned NumArgs, 403 SourceLocation RBracLoc); 404 405 /// \brief Retrieve the pointer value of the ,essage receiver. 406 void *getReceiverPointer() const { 407 return *const_cast<void **>( 408 reinterpret_cast<const void * const*>(this + 1)); 409 } 410 411 /// \brief Set the pointer value of the message receiver. 412 void setReceiverPointer(void *Value) { 413 *reinterpret_cast<void **>(this + 1) = Value; 414 } 415 416public: 417 /// \brief The kind of receiver this message is sending to. 418 enum ReceiverKind { 419 /// \brief The receiver is a class. 420 Class = 0, 421 /// \brief The receiver is an object instance. 422 Instance, 423 /// \brief The receiver is a superclass. 424 SuperClass, 425 /// \brief The receiver is the instance of the superclass object. 426 SuperInstance 427 }; 428 429 /// \brief Create a message send to super. 430 /// 431 /// \param Context The ASTContext in which this expression will be created. 432 /// 433 /// \param T The result type of this message. 434 /// 435 /// \param LBrac The location of the open square bracket '['. 436 /// 437 /// \param SuperLoc The location of the "super" keyword. 438 /// 439 /// \param IsInstanceSuper Whether this is an instance "super" 440 /// message (otherwise, it's a class "super" message). 441 /// 442 /// \param Sel The selector used to determine which method gets called. 443 /// 444 /// \param Method The Objective-C method against which this message 445 /// send was type-checked. May be NULL. 446 /// 447 /// \param Args The message send arguments. 448 /// 449 /// \param NumArgs The number of arguments. 450 /// 451 /// \param RBracLoc The location of the closing square bracket ']'. 452 static ObjCMessageExpr *Create(ASTContext &Context, QualType T, 453 SourceLocation LBracLoc, 454 SourceLocation SuperLoc, 455 bool IsInstanceSuper, 456 QualType SuperType, 457 Selector Sel, 458 ObjCMethodDecl *Method, 459 Expr **Args, unsigned NumArgs, 460 SourceLocation RBracLoc); 461 462 /// \brief Create a class message send. 463 /// 464 /// \param Context The ASTContext in which this expression will be created. 465 /// 466 /// \param T The result type of this message. 467 /// 468 /// \param LBrac The location of the open square bracket '['. 469 /// 470 /// \param Receiver The type of the receiver, including 471 /// source-location information. 472 /// 473 /// \param Sel The selector used to determine which method gets called. 474 /// 475 /// \param Method The Objective-C method against which this message 476 /// send was type-checked. May be NULL. 477 /// 478 /// \param Args The message send arguments. 479 /// 480 /// \param NumArgs The number of arguments. 481 /// 482 /// \param RBracLoc The location of the closing square bracket ']'. 483 static ObjCMessageExpr *Create(ASTContext &Context, QualType T, 484 SourceLocation LBracLoc, 485 TypeSourceInfo *Receiver, 486 Selector Sel, 487 ObjCMethodDecl *Method, 488 Expr **Args, unsigned NumArgs, 489 SourceLocation RBracLoc); 490 491 /// \brief Create an instance message send. 492 /// 493 /// \param Context The ASTContext in which this expression will be created. 494 /// 495 /// \param T The result type of this message. 496 /// 497 /// \param LBrac The location of the open square bracket '['. 498 /// 499 /// \param Receiver The expression used to produce the object that 500 /// will receive this message. 501 /// 502 /// \param Sel The selector used to determine which method gets called. 503 /// 504 /// \param Method The Objective-C method against which this message 505 /// send was type-checked. May be NULL. 506 /// 507 /// \param Args The message send arguments. 508 /// 509 /// \param NumArgs The number of arguments. 510 /// 511 /// \param RBracLoc The location of the closing square bracket ']'. 512 static ObjCMessageExpr *Create(ASTContext &Context, QualType T, 513 SourceLocation LBracLoc, 514 Expr *Receiver, 515 Selector Sel, 516 ObjCMethodDecl *Method, 517 Expr **Args, unsigned NumArgs, 518 SourceLocation RBracLoc); 519 520 /// \brief Create an empty Objective-C message expression, to be 521 /// filled in by subsequent calls. 522 /// 523 /// \param Context The context in which the message send will be created. 524 /// 525 /// \param NumArgs The number of message arguments, not including 526 /// the receiver. 527 static ObjCMessageExpr *CreateEmpty(ASTContext &Context, unsigned NumArgs); 528 529 /// \brief Determine the kind of receiver that this message is being 530 /// sent to. 531 ReceiverKind getReceiverKind() const { return (ReceiverKind)Kind; } 532 533 /// \brief Determine whether this is an instance message to either a 534 /// computed object or to super. 535 bool isInstanceMessage() const { 536 return getReceiverKind() == Instance || getReceiverKind() == SuperInstance; 537 } 538 539 /// \brief Determine whether this is an class message to either a 540 /// specified class or to super. 541 bool isClassMessage() const { 542 return getReceiverKind() == Class || getReceiverKind() == SuperClass; 543 } 544 545 /// \brief Returns the receiver of an instance message. 546 /// 547 /// \brief Returns the object expression for an instance message, or 548 /// NULL for a message that is not an instance message. 549 Expr *getInstanceReceiver() { 550 if (getReceiverKind() == Instance) 551 return static_cast<Expr *>(getReceiverPointer()); 552 553 return 0; 554 } 555 const Expr *getInstanceReceiver() const { 556 return const_cast<ObjCMessageExpr*>(this)->getInstanceReceiver(); 557 } 558 559 /// \brief Turn this message send into an instance message that 560 /// computes the receiver object with the given expression. 561 void setInstanceReceiver(Expr *rec) { 562 Kind = Instance; 563 setReceiverPointer(rec); 564 } 565 566 /// \brief Returns the type of a class message send, or NULL if the 567 /// message is not a class message. 568 QualType getClassReceiver() const { 569 if (TypeSourceInfo *TSInfo = getClassReceiverTypeInfo()) 570 return TSInfo->getType(); 571 572 return QualType(); 573 } 574 575 /// \brief Returns a type-source information of a class message 576 /// send, or NULL if the message is not a class message. 577 TypeSourceInfo *getClassReceiverTypeInfo() const { 578 if (getReceiverKind() == Class) 579 return reinterpret_cast<TypeSourceInfo *>(getReceiverPointer()); 580 return 0; 581 } 582 583 void setClassReceiver(TypeSourceInfo *TSInfo) { 584 Kind = Class; 585 setReceiverPointer(TSInfo); 586 } 587 588 /// \brief Retrieve the location of the 'super' keyword for a class 589 /// or instance message to 'super', otherwise an invalid source location. 590 SourceLocation getSuperLoc() const { 591 if (getReceiverKind() == SuperInstance || getReceiverKind() == SuperClass) 592 return SuperLoc; 593 594 return SourceLocation(); 595 } 596 597 /// \brief Retrieve the Objective-C interface to which this message 598 /// is being directed, if known. 599 /// 600 /// This routine cross-cuts all of the different kinds of message 601 /// sends to determine what the underlying (statically known) type 602 /// of the receiver will be; use \c getReceiverKind() to determine 603 /// whether the message is a class or an instance method, whether it 604 /// is a send to super or not, etc. 605 /// 606 /// \returns The Objective-C interface if known, otherwise NULL. 607 ObjCInterfaceDecl *getReceiverInterface() const; 608 609 /// \brief Retrieve the type referred to by 'super'. 610 /// 611 /// The returned type will either be an ObjCInterfaceType (for an 612 /// class message to super) or an ObjCObjectPointerType that refers 613 /// to a class (for an instance message to super); 614 QualType getSuperType() const { 615 if (getReceiverKind() == SuperInstance || getReceiverKind() == SuperClass) 616 return QualType::getFromOpaquePtr(getReceiverPointer()); 617 618 return QualType(); 619 } 620 621 void setSuper(SourceLocation Loc, QualType T, bool IsInstanceSuper) { 622 Kind = IsInstanceSuper? SuperInstance : SuperClass; 623 SuperLoc = Loc; 624 setReceiverPointer(T.getAsOpaquePtr()); 625 } 626 627 Selector getSelector() const; 628 629 void setSelector(Selector S) { 630 HasMethod = false; 631 SelectorOrMethod = reinterpret_cast<uintptr_t>(S.getAsOpaquePtr()); 632 } 633 634 const ObjCMethodDecl *getMethodDecl() const { 635 if (HasMethod) 636 return reinterpret_cast<const ObjCMethodDecl *>(SelectorOrMethod); 637 638 return 0; 639 } 640 641 ObjCMethodDecl *getMethodDecl() { 642 if (HasMethod) 643 return reinterpret_cast<ObjCMethodDecl *>(SelectorOrMethod); 644 645 return 0; 646 } 647 648 void setMethodDecl(ObjCMethodDecl *MD) { 649 HasMethod = true; 650 SelectorOrMethod = reinterpret_cast<uintptr_t>(MD); 651 } 652 653 /// \brief Return the number of actual arguments in this message, 654 /// not counting the receiver. 655 unsigned getNumArgs() const { return NumArgs; } 656 657 /// \brief Retrieve the arguments to this message, not including the 658 /// receiver. 659 Stmt **getArgs() { 660 return reinterpret_cast<Stmt **>(this + 1) + 1; 661 } 662 const Stmt * const *getArgs() const { 663 return reinterpret_cast<const Stmt * const *>(this + 1) + 1; 664 } 665 666 /// getArg - Return the specified argument. 667 Expr *getArg(unsigned Arg) { 668 assert(Arg < NumArgs && "Arg access out of range!"); 669 return cast<Expr>(getArgs()[Arg]); 670 } 671 const Expr *getArg(unsigned Arg) const { 672 assert(Arg < NumArgs && "Arg access out of range!"); 673 return cast<Expr>(getArgs()[Arg]); 674 } 675 /// setArg - Set the specified argument. 676 void setArg(unsigned Arg, Expr *ArgExpr) { 677 assert(Arg < NumArgs && "Arg access out of range!"); 678 getArgs()[Arg] = ArgExpr; 679 } 680 681 SourceLocation getLeftLoc() const { return LBracLoc; } 682 SourceLocation getRightLoc() const { return RBracLoc; } 683 684 void setLeftLoc(SourceLocation L) { LBracLoc = L; } 685 void setRightLoc(SourceLocation L) { RBracLoc = L; } 686 687 void setSourceRange(SourceRange R) { 688 LBracLoc = R.getBegin(); 689 RBracLoc = R.getEnd(); 690 } 691 virtual SourceRange getSourceRange() const { 692 return SourceRange(LBracLoc, RBracLoc); 693 } 694 695 static bool classof(const Stmt *T) { 696 return T->getStmtClass() == ObjCMessageExprClass; 697 } 698 static bool classof(const ObjCMessageExpr *) { return true; } 699 700 // Iterators 701 virtual child_iterator child_begin(); 702 virtual child_iterator child_end(); 703 704 typedef ExprIterator arg_iterator; 705 typedef ConstExprIterator const_arg_iterator; 706 707 arg_iterator arg_begin() { return getArgs(); } 708 arg_iterator arg_end() { return getArgs() + NumArgs; } 709 const_arg_iterator arg_begin() const { 710 return const_cast<Stmt**>(getArgs()); 711 } 712 const_arg_iterator arg_end() const { 713 return const_cast<Stmt**>(getArgs()) + NumArgs; 714 } 715}; 716 717/// ObjCSuperExpr - Represents the "super" expression in Objective-C, 718/// which refers to the object on which the current method is executing. 719class ObjCSuperExpr : public Expr { 720 SourceLocation Loc; 721public: 722 ObjCSuperExpr(SourceLocation L, QualType Type) 723 : Expr(ObjCSuperExprClass, Type, false, false), Loc(L) { } 724 explicit ObjCSuperExpr(EmptyShell Empty) : Expr(ObjCSuperExprClass, Empty) {} 725 726 SourceLocation getLoc() const { return Loc; } 727 void setLoc(SourceLocation L) { Loc = L; } 728 729 virtual SourceRange getSourceRange() const { return SourceRange(Loc); } 730 731 static bool classof(const Stmt *T) { 732 return T->getStmtClass() == ObjCSuperExprClass; 733 } 734 static bool classof(const ObjCSuperExpr *) { return true; } 735 736 // Iterators 737 virtual child_iterator child_begin(); 738 virtual child_iterator child_end(); 739}; 740 741/// ObjCIsaExpr - Represent X->isa and X.isa when X is an ObjC 'id' type. 742/// (similiar in spirit to MemberExpr). 743class ObjCIsaExpr : public Expr { 744 /// Base - the expression for the base object pointer. 745 Stmt *Base; 746 747 /// IsaMemberLoc - This is the location of the 'isa'. 748 SourceLocation IsaMemberLoc; 749 750 /// IsArrow - True if this is "X->F", false if this is "X.F". 751 bool IsArrow; 752public: 753 ObjCIsaExpr(Expr *base, bool isarrow, SourceLocation l, QualType ty) 754 : Expr(ObjCIsaExprClass, ty, false, false), 755 Base(base), IsaMemberLoc(l), IsArrow(isarrow) {} 756 757 /// \brief Build an empty expression. 758 explicit ObjCIsaExpr(EmptyShell Empty) : Expr(ObjCIsaExprClass, Empty) { } 759 760 void setBase(Expr *E) { Base = E; } 761 Expr *getBase() const { return cast<Expr>(Base); } 762 763 bool isArrow() const { return IsArrow; } 764 void setArrow(bool A) { IsArrow = A; } 765 766 /// getMemberLoc - Return the location of the "member", in X->F, it is the 767 /// location of 'F'. 768 SourceLocation getIsaMemberLoc() const { return IsaMemberLoc; } 769 void setIsaMemberLoc(SourceLocation L) { IsaMemberLoc = L; } 770 771 virtual SourceRange getSourceRange() const { 772 return SourceRange(getBase()->getLocStart(), IsaMemberLoc); 773 } 774 775 virtual SourceLocation getExprLoc() const { return IsaMemberLoc; } 776 777 static bool classof(const Stmt *T) { 778 return T->getStmtClass() == ObjCIsaExprClass; 779 } 780 static bool classof(const ObjCIsaExpr *) { return true; } 781 782 // Iterators 783 virtual child_iterator child_begin(); 784 virtual child_iterator child_end(); 785}; 786 787} // end namespace clang 788 789#endif 790