ExprObjC.h revision 8ac2d449820fd0df00fcbde5bf82165c1f49854d
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, 185 bool arrow = false, bool freeIvar = false) : 186 Expr(ObjCIvarRefExprClass, t, /*TypeDependent=*/false, 187 base->isValueDependent()), 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 233 /// \brief When the receiver in property access is 'super', this is 234 /// the location of the 'super' keyword. 235 SourceLocation SuperLoc; 236 237 /// \brief When the receiver in property access is 'super', this is 238 /// the type associated with 'super' keyword. A null type indicates 239 /// that this is not a 'super' receiver. 240 llvm::PointerUnion<Stmt*, Type*> BaseExprOrSuperType; 241 242public: 243 ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t, 244 SourceLocation l, Expr *base) 245 : Expr(ObjCPropertyRefExprClass, t, /*TypeDependent=*/false, 246 base->isValueDependent()), 247 AsProperty(PD), IdLoc(l), BaseExprOrSuperType(base) { 248 } 249 250 ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t, 251 SourceLocation l, SourceLocation sl, QualType st) 252 : Expr(ObjCPropertyRefExprClass, t, /*TypeDependent=*/false, false), 253 AsProperty(PD), IdLoc(l), SuperLoc(sl), 254 BaseExprOrSuperType(st.getTypePtr()) { 255 } 256 257 explicit ObjCPropertyRefExpr(EmptyShell Empty) 258 : Expr(ObjCPropertyRefExprClass, Empty) {} 259 260 ObjCPropertyDecl *getProperty() const { return AsProperty; } 261 262 const Expr *getBase() const { 263 return cast<Expr>(BaseExprOrSuperType.get<Stmt*>()); 264 } 265 Expr *getBase() { 266 return cast<Expr>(BaseExprOrSuperType.get<Stmt*>()); 267 } 268 269 SourceLocation getLocation() const { return IdLoc; } 270 271 SourceLocation getSuperLocation() const { return SuperLoc; } 272 QualType getSuperType() const { 273 Type *t = BaseExprOrSuperType.get<Type*>(); 274 return QualType(t, 0); 275 } 276 bool isSuperReceiver() const { return BaseExprOrSuperType.is<Type*>(); } 277 278 virtual SourceRange getSourceRange() const { 279 return SourceRange( 280 (BaseExprOrSuperType.is<Stmt*>() ? getBase()->getLocStart() 281 : getSuperLocation()), 282 IdLoc); 283 } 284 285 static bool classof(const Stmt *T) { 286 return T->getStmtClass() == ObjCPropertyRefExprClass; 287 } 288 static bool classof(const ObjCPropertyRefExpr *) { return true; } 289 290 // Iterators 291 virtual child_iterator child_begin(); 292 virtual child_iterator child_end(); 293private: 294 friend class ASTStmtReader; 295 void setProperty(ObjCPropertyDecl *D) { AsProperty = D; } 296 void setBase(Expr *base) { BaseExprOrSuperType = base; } 297 void setLocation(SourceLocation L) { IdLoc = L; } 298 void setSuperLocation(SourceLocation Loc) { SuperLoc = Loc; } 299 void setSuperType(QualType T) { BaseExprOrSuperType = T.getTypePtr(); } 300}; 301 302/// ObjCImplicitSetterGetterRefExpr - A dot-syntax expression to access two 303/// methods; one to set a value to an 'ivar' (Setter) and the other to access 304/// an 'ivar' (Setter). 305/// An example for use of this AST is: 306/// @code 307/// @interface Test { } 308/// - (Test *)crash; 309/// - (void)setCrash: (Test*)value; 310/// @end 311/// void foo(Test *p1, Test *p2) 312/// { 313/// p2.crash = p1.crash; // Uses ObjCImplicitSetterGetterRefExpr AST 314/// } 315/// @endcode 316class ObjCImplicitSetterGetterRefExpr : public Expr { 317 /// Setter - Setter method user declared for setting its 'ivar' to a value 318 ObjCMethodDecl *Setter; 319 /// Getter - Getter method user declared for accessing 'ivar' it controls. 320 ObjCMethodDecl *Getter; 321 /// Location of the member in the dot syntax notation. This is location 322 /// of the getter method. 323 SourceLocation MemberLoc; 324 // FIXME: Swizzle these into a single pointer. 325 Stmt *Base; 326 ObjCInterfaceDecl *InterfaceDecl; 327 /// \brief Location of the receiver class in the dot syntax notation 328 /// used to call a class method setter/getter. 329 SourceLocation ClassLoc; 330 331 /// \brief When the receiver in dot-syntax expression is 'super', 332 /// this is the location of the 'super' keyword. 333 SourceLocation SuperLoc; 334 335 /// \brief When the receiver in dot-syntax expression is 'super', this is 336 /// the type associated with 'super' keyword. 337 QualType SuperTy; 338 339 /// \brief When the receiver in dot-syntax expression is 'super', this is 340 /// set to true. 341 bool IsSuper:1; 342 343public: 344 ObjCImplicitSetterGetterRefExpr(ObjCMethodDecl *getter, 345 QualType t, 346 ObjCMethodDecl *setter, 347 SourceLocation l, Expr *base) 348 : Expr(ObjCImplicitSetterGetterRefExprClass, t, /*TypeDependent=*/false, 349 base->isValueDependent()), 350 Setter(setter), Getter(getter), MemberLoc(l), Base(base), 351 InterfaceDecl(0), ClassLoc(SourceLocation()) { 352 IsSuper = false; 353 } 354 355 ObjCImplicitSetterGetterRefExpr(ObjCMethodDecl *getter, 356 QualType t, 357 ObjCMethodDecl *setter, 358 SourceLocation l, 359 SourceLocation sl, 360 QualType st) 361 : Expr(ObjCImplicitSetterGetterRefExprClass, t, /*TypeDependent=*/false, 362 false), 363 Setter(setter), Getter(getter), MemberLoc(l), 364 InterfaceDecl(0), ClassLoc(SourceLocation()), 365 SuperLoc(sl), SuperTy(st), IsSuper(true) { 366 } 367 368 ObjCImplicitSetterGetterRefExpr(ObjCMethodDecl *getter, 369 QualType t, 370 ObjCMethodDecl *setter, 371 SourceLocation l, ObjCInterfaceDecl *C, SourceLocation CL) 372 : Expr(ObjCImplicitSetterGetterRefExprClass, t, false, false), 373 Setter(setter), Getter(getter), MemberLoc(l), Base(0), InterfaceDecl(C), 374 ClassLoc(CL) { 375 IsSuper = false; 376 } 377 explicit ObjCImplicitSetterGetterRefExpr(EmptyShell Empty) 378 : Expr(ObjCImplicitSetterGetterRefExprClass, Empty){} 379 380 ObjCMethodDecl *getGetterMethod() const { return Getter; } 381 ObjCMethodDecl *getSetterMethod() const { return Setter; } 382 ObjCInterfaceDecl *getInterfaceDecl() const { return InterfaceDecl; } 383 void setGetterMethod(ObjCMethodDecl *D) { Getter = D; } 384 void setSetterMethod(ObjCMethodDecl *D) { Setter = D; } 385 void setInterfaceDecl(ObjCInterfaceDecl *D) { InterfaceDecl = D; } 386 387 virtual SourceRange getSourceRange() const { 388 if (isSuperReceiver()) 389 return SourceRange(getSuperLocation(), MemberLoc); 390 if (Base) 391 return SourceRange(getBase()->getLocStart(), MemberLoc); 392 return SourceRange(ClassLoc, MemberLoc); 393 } 394 const Expr *getBase() const { return cast_or_null<Expr>(Base); } 395 Expr *getBase() { return cast_or_null<Expr>(Base); } 396 void setBase(Expr *base) { Base = base; } 397 398 SourceLocation getLocation() const { return MemberLoc; } 399 void setLocation(SourceLocation L) { MemberLoc = L; } 400 SourceLocation getClassLoc() const { return ClassLoc; } 401 void setClassLoc(SourceLocation L) { ClassLoc = L; } 402 403 SourceLocation getSuperLocation() const { return SuperLoc; } 404 QualType getSuperType() const { return SuperTy; } 405 bool isSuperReceiver() const { return IsSuper; } 406 407 static bool classof(const Stmt *T) { 408 return T->getStmtClass() == ObjCImplicitSetterGetterRefExprClass; 409 } 410 static bool classof(const ObjCImplicitSetterGetterRefExpr *) { return true; } 411 412 // Iterators 413 virtual child_iterator child_begin(); 414 virtual child_iterator child_end(); 415 416private: 417 friend class ASTStmtReader; 418 void setSuperLocation(SourceLocation Loc) { SuperLoc = Loc; } 419 void setSuperType(QualType T) { SuperTy = T; } 420 void setSuperReceiver(bool bv) { IsSuper = bv; } 421}; 422 423/// \brief An expression that sends a message to the given Objective-C 424/// object or class. 425/// 426/// The following contains two message send expressions: 427/// 428/// \code 429/// [[NSString alloc] initWithString:@"Hello"] 430/// \endcode 431/// 432/// The innermost message send invokes the "alloc" class method on the 433/// NSString class, while the outermost message send invokes the 434/// "initWithString" instance method on the object returned from 435/// NSString's "alloc". In all, an Objective-C message send can take 436/// on four different (although related) forms: 437/// 438/// 1. Send to an object instance. 439/// 2. Send to a class. 440/// 3. Send to the superclass instance of the current class. 441/// 4. Send to the superclass of the current class. 442/// 443/// All four kinds of message sends are modeled by the ObjCMessageExpr 444/// class, and can be distinguished via \c getReceiverKind(). Example: 445/// 446class ObjCMessageExpr : public Expr { 447 /// \brief The number of arguments in the message send, not 448 /// including the receiver. 449 unsigned NumArgs : 16; 450 451 /// \brief The kind of message send this is, which is one of the 452 /// ReceiverKind values. 453 /// 454 /// We pad this out to a byte to avoid excessive masking and shifting. 455 unsigned Kind : 8; 456 457 /// \brief Whether we have an actual method prototype in \c 458 /// SelectorOrMethod. 459 /// 460 /// When non-zero, we have a method declaration; otherwise, we just 461 /// have a selector. 462 unsigned HasMethod : 8; 463 464 /// \brief When the message expression is a send to 'super', this is 465 /// the location of the 'super' keyword. 466 SourceLocation SuperLoc; 467 468 /// \brief Stores either the selector that this message is sending 469 /// to (when \c HasMethod is zero) or an \c ObjCMethodDecl pointer 470 /// referring to the method that we type-checked against. 471 uintptr_t SelectorOrMethod; 472 473 /// \brief The source locations of the open and close square 474 /// brackets ('[' and ']', respectively). 475 SourceLocation LBracLoc, RBracLoc; 476 477 ObjCMessageExpr(EmptyShell Empty, unsigned NumArgs) 478 : Expr(ObjCMessageExprClass, Empty), NumArgs(NumArgs), Kind(0), 479 HasMethod(0), SelectorOrMethod(0) { } 480 481 ObjCMessageExpr(QualType T, 482 SourceLocation LBracLoc, 483 SourceLocation SuperLoc, 484 bool IsInstanceSuper, 485 QualType SuperType, 486 Selector Sel, 487 ObjCMethodDecl *Method, 488 Expr **Args, unsigned NumArgs, 489 SourceLocation RBracLoc); 490 ObjCMessageExpr(QualType T, 491 SourceLocation LBracLoc, 492 TypeSourceInfo *Receiver, 493 Selector Sel, 494 ObjCMethodDecl *Method, 495 Expr **Args, unsigned NumArgs, 496 SourceLocation RBracLoc); 497 ObjCMessageExpr(QualType T, 498 SourceLocation LBracLoc, 499 Expr *Receiver, 500 Selector Sel, 501 ObjCMethodDecl *Method, 502 Expr **Args, unsigned NumArgs, 503 SourceLocation RBracLoc); 504 505 /// \brief Retrieve the pointer value of the message receiver. 506 void *getReceiverPointer() const { 507 return *const_cast<void **>( 508 reinterpret_cast<const void * const*>(this + 1)); 509 } 510 511 /// \brief Set the pointer value of the message receiver. 512 void setReceiverPointer(void *Value) { 513 *reinterpret_cast<void **>(this + 1) = Value; 514 } 515 516public: 517 /// \brief The kind of receiver this message is sending to. 518 enum ReceiverKind { 519 /// \brief The receiver is a class. 520 Class = 0, 521 /// \brief The receiver is an object instance. 522 Instance, 523 /// \brief The receiver is a superclass. 524 SuperClass, 525 /// \brief The receiver is the instance of the superclass object. 526 SuperInstance 527 }; 528 529 /// \brief Create a message send to super. 530 /// 531 /// \param Context The ASTContext in which this expression will be created. 532 /// 533 /// \param T The result type of this message. 534 /// 535 /// \param LBrac The location of the open square bracket '['. 536 /// 537 /// \param SuperLoc The location of the "super" keyword. 538 /// 539 /// \param IsInstanceSuper Whether this is an instance "super" 540 /// message (otherwise, it's a class "super" message). 541 /// 542 /// \param Sel The selector used to determine which method gets called. 543 /// 544 /// \param Method The Objective-C method against which this message 545 /// send was type-checked. May be NULL. 546 /// 547 /// \param Args The message send arguments. 548 /// 549 /// \param NumArgs The number of arguments. 550 /// 551 /// \param RBracLoc The location of the closing square bracket ']'. 552 static ObjCMessageExpr *Create(ASTContext &Context, QualType T, 553 SourceLocation LBracLoc, 554 SourceLocation SuperLoc, 555 bool IsInstanceSuper, 556 QualType SuperType, 557 Selector Sel, 558 ObjCMethodDecl *Method, 559 Expr **Args, unsigned NumArgs, 560 SourceLocation RBracLoc); 561 562 /// \brief Create a class message send. 563 /// 564 /// \param Context The ASTContext in which this expression will be created. 565 /// 566 /// \param T The result type of this message. 567 /// 568 /// \param LBrac The location of the open square bracket '['. 569 /// 570 /// \param Receiver The type of the receiver, including 571 /// source-location information. 572 /// 573 /// \param Sel The selector used to determine which method gets called. 574 /// 575 /// \param Method The Objective-C method against which this message 576 /// send was type-checked. May be NULL. 577 /// 578 /// \param Args The message send arguments. 579 /// 580 /// \param NumArgs The number of arguments. 581 /// 582 /// \param RBracLoc The location of the closing square bracket ']'. 583 static ObjCMessageExpr *Create(ASTContext &Context, QualType T, 584 SourceLocation LBracLoc, 585 TypeSourceInfo *Receiver, 586 Selector Sel, 587 ObjCMethodDecl *Method, 588 Expr **Args, unsigned NumArgs, 589 SourceLocation RBracLoc); 590 591 /// \brief Create an instance message send. 592 /// 593 /// \param Context The ASTContext in which this expression will be created. 594 /// 595 /// \param T The result type of this message. 596 /// 597 /// \param LBrac The location of the open square bracket '['. 598 /// 599 /// \param Receiver The expression used to produce the object that 600 /// will receive this message. 601 /// 602 /// \param Sel The selector used to determine which method gets called. 603 /// 604 /// \param Method The Objective-C method against which this message 605 /// send was type-checked. May be NULL. 606 /// 607 /// \param Args The message send arguments. 608 /// 609 /// \param NumArgs The number of arguments. 610 /// 611 /// \param RBracLoc The location of the closing square bracket ']'. 612 static ObjCMessageExpr *Create(ASTContext &Context, QualType T, 613 SourceLocation LBracLoc, 614 Expr *Receiver, 615 Selector Sel, 616 ObjCMethodDecl *Method, 617 Expr **Args, unsigned NumArgs, 618 SourceLocation RBracLoc); 619 620 /// \brief Create an empty Objective-C message expression, to be 621 /// filled in by subsequent calls. 622 /// 623 /// \param Context The context in which the message send will be created. 624 /// 625 /// \param NumArgs The number of message arguments, not including 626 /// the receiver. 627 static ObjCMessageExpr *CreateEmpty(ASTContext &Context, unsigned NumArgs); 628 629 /// \brief Determine the kind of receiver that this message is being 630 /// sent to. 631 ReceiverKind getReceiverKind() const { return (ReceiverKind)Kind; } 632 633 /// \brief Determine whether this is an instance message to either a 634 /// computed object or to super. 635 bool isInstanceMessage() const { 636 return getReceiverKind() == Instance || getReceiverKind() == SuperInstance; 637 } 638 639 /// \brief Determine whether this is an class message to either a 640 /// specified class or to super. 641 bool isClassMessage() const { 642 return getReceiverKind() == Class || getReceiverKind() == SuperClass; 643 } 644 645 /// \brief Returns the receiver of an instance message. 646 /// 647 /// \brief Returns the object expression for an instance message, or 648 /// NULL for a message that is not an instance message. 649 Expr *getInstanceReceiver() { 650 if (getReceiverKind() == Instance) 651 return static_cast<Expr *>(getReceiverPointer()); 652 653 return 0; 654 } 655 const Expr *getInstanceReceiver() const { 656 return const_cast<ObjCMessageExpr*>(this)->getInstanceReceiver(); 657 } 658 659 /// \brief Turn this message send into an instance message that 660 /// computes the receiver object with the given expression. 661 void setInstanceReceiver(Expr *rec) { 662 Kind = Instance; 663 setReceiverPointer(rec); 664 } 665 666 /// \brief Returns the type of a class message send, or NULL if the 667 /// message is not a class message. 668 QualType getClassReceiver() const { 669 if (TypeSourceInfo *TSInfo = getClassReceiverTypeInfo()) 670 return TSInfo->getType(); 671 672 return QualType(); 673 } 674 675 /// \brief Returns a type-source information of a class message 676 /// send, or NULL if the message is not a class message. 677 TypeSourceInfo *getClassReceiverTypeInfo() const { 678 if (getReceiverKind() == Class) 679 return reinterpret_cast<TypeSourceInfo *>(getReceiverPointer()); 680 return 0; 681 } 682 683 void setClassReceiver(TypeSourceInfo *TSInfo) { 684 Kind = Class; 685 setReceiverPointer(TSInfo); 686 } 687 688 /// \brief Retrieve the location of the 'super' keyword for a class 689 /// or instance message to 'super', otherwise an invalid source location. 690 SourceLocation getSuperLoc() const { 691 if (getReceiverKind() == SuperInstance || getReceiverKind() == SuperClass) 692 return SuperLoc; 693 694 return SourceLocation(); 695 } 696 697 /// \brief Retrieve the Objective-C interface to which this message 698 /// is being directed, if known. 699 /// 700 /// This routine cross-cuts all of the different kinds of message 701 /// sends to determine what the underlying (statically known) type 702 /// of the receiver will be; use \c getReceiverKind() to determine 703 /// whether the message is a class or an instance method, whether it 704 /// is a send to super or not, etc. 705 /// 706 /// \returns The Objective-C interface if known, otherwise NULL. 707 ObjCInterfaceDecl *getReceiverInterface() const; 708 709 /// \brief Retrieve the type referred to by 'super'. 710 /// 711 /// The returned type will either be an ObjCInterfaceType (for an 712 /// class message to super) or an ObjCObjectPointerType that refers 713 /// to a class (for an instance message to super); 714 QualType getSuperType() const { 715 if (getReceiverKind() == SuperInstance || getReceiverKind() == SuperClass) 716 return QualType::getFromOpaquePtr(getReceiverPointer()); 717 718 return QualType(); 719 } 720 721 void setSuper(SourceLocation Loc, QualType T, bool IsInstanceSuper) { 722 Kind = IsInstanceSuper? SuperInstance : SuperClass; 723 SuperLoc = Loc; 724 setReceiverPointer(T.getAsOpaquePtr()); 725 } 726 727 Selector getSelector() const; 728 729 void setSelector(Selector S) { 730 HasMethod = false; 731 SelectorOrMethod = reinterpret_cast<uintptr_t>(S.getAsOpaquePtr()); 732 } 733 734 const ObjCMethodDecl *getMethodDecl() const { 735 if (HasMethod) 736 return reinterpret_cast<const ObjCMethodDecl *>(SelectorOrMethod); 737 738 return 0; 739 } 740 741 ObjCMethodDecl *getMethodDecl() { 742 if (HasMethod) 743 return reinterpret_cast<ObjCMethodDecl *>(SelectorOrMethod); 744 745 return 0; 746 } 747 748 void setMethodDecl(ObjCMethodDecl *MD) { 749 HasMethod = true; 750 SelectorOrMethod = reinterpret_cast<uintptr_t>(MD); 751 } 752 753 /// \brief Return the number of actual arguments in this message, 754 /// not counting the receiver. 755 unsigned getNumArgs() const { return NumArgs; } 756 757 /// \brief Retrieve the arguments to this message, not including the 758 /// receiver. 759 Stmt **getArgs() { 760 return reinterpret_cast<Stmt **>(this + 1) + 1; 761 } 762 const Stmt * const *getArgs() const { 763 return reinterpret_cast<const Stmt * const *>(this + 1) + 1; 764 } 765 766 /// getArg - Return the specified argument. 767 Expr *getArg(unsigned Arg) { 768 assert(Arg < NumArgs && "Arg access out of range!"); 769 return cast<Expr>(getArgs()[Arg]); 770 } 771 const Expr *getArg(unsigned Arg) const { 772 assert(Arg < NumArgs && "Arg access out of range!"); 773 return cast<Expr>(getArgs()[Arg]); 774 } 775 /// setArg - Set the specified argument. 776 void setArg(unsigned Arg, Expr *ArgExpr) { 777 assert(Arg < NumArgs && "Arg access out of range!"); 778 getArgs()[Arg] = ArgExpr; 779 } 780 781 SourceLocation getLeftLoc() const { return LBracLoc; } 782 SourceLocation getRightLoc() const { return RBracLoc; } 783 784 void setLeftLoc(SourceLocation L) { LBracLoc = L; } 785 void setRightLoc(SourceLocation L) { RBracLoc = L; } 786 787 void setSourceRange(SourceRange R) { 788 LBracLoc = R.getBegin(); 789 RBracLoc = R.getEnd(); 790 } 791 virtual SourceRange getSourceRange() const { 792 return SourceRange(LBracLoc, RBracLoc); 793 } 794 795 static bool classof(const Stmt *T) { 796 return T->getStmtClass() == ObjCMessageExprClass; 797 } 798 static bool classof(const ObjCMessageExpr *) { return true; } 799 800 // Iterators 801 virtual child_iterator child_begin(); 802 virtual child_iterator child_end(); 803 804 typedef ExprIterator arg_iterator; 805 typedef ConstExprIterator const_arg_iterator; 806 807 arg_iterator arg_begin() { return getArgs(); } 808 arg_iterator arg_end() { return getArgs() + NumArgs; } 809 const_arg_iterator arg_begin() const { return getArgs(); } 810 const_arg_iterator arg_end() const { return getArgs() + NumArgs; } 811}; 812 813/// ObjCIsaExpr - Represent X->isa and X.isa when X is an ObjC 'id' type. 814/// (similiar in spirit to MemberExpr). 815class ObjCIsaExpr : public Expr { 816 /// Base - the expression for the base object pointer. 817 Stmt *Base; 818 819 /// IsaMemberLoc - This is the location of the 'isa'. 820 SourceLocation IsaMemberLoc; 821 822 /// IsArrow - True if this is "X->F", false if this is "X.F". 823 bool IsArrow; 824public: 825 ObjCIsaExpr(Expr *base, bool isarrow, SourceLocation l, QualType ty) 826 : Expr(ObjCIsaExprClass, ty, /*TypeDependent=*/false, 827 base->isValueDependent()), 828 Base(base), IsaMemberLoc(l), IsArrow(isarrow) {} 829 830 /// \brief Build an empty expression. 831 explicit ObjCIsaExpr(EmptyShell Empty) : Expr(ObjCIsaExprClass, Empty) { } 832 833 void setBase(Expr *E) { Base = E; } 834 Expr *getBase() const { return cast<Expr>(Base); } 835 836 bool isArrow() const { return IsArrow; } 837 void setArrow(bool A) { IsArrow = A; } 838 839 /// getMemberLoc - Return the location of the "member", in X->F, it is the 840 /// location of 'F'. 841 SourceLocation getIsaMemberLoc() const { return IsaMemberLoc; } 842 void setIsaMemberLoc(SourceLocation L) { IsaMemberLoc = L; } 843 844 virtual SourceRange getSourceRange() const { 845 return SourceRange(getBase()->getLocStart(), IsaMemberLoc); 846 } 847 848 virtual SourceLocation getExprLoc() const { return IsaMemberLoc; } 849 850 static bool classof(const Stmt *T) { 851 return T->getStmtClass() == ObjCIsaExprClass; 852 } 853 static bool classof(const ObjCIsaExpr *) { return true; } 854 855 // Iterators 856 virtual child_iterator child_begin(); 857 virtual child_iterator child_end(); 858}; 859 860} // end namespace clang 861 862#endif 863