ExprObjC.h revision 218893
1193326Sed//===--- ExprObjC.h - Classes for representing ObjC expressions -*- C++ -*-===// 2193326Sed// 3193326Sed// The LLVM Compiler Infrastructure 4193326Sed// 5193326Sed// This file is distributed under the University of Illinois Open Source 6193326Sed// License. See LICENSE.TXT for details. 7193326Sed// 8193326Sed//===----------------------------------------------------------------------===// 9193326Sed// 10193326Sed// This file defines the ExprObjC interface and subclasses. 11193326Sed// 12193326Sed//===----------------------------------------------------------------------===// 13193326Sed 14193326Sed#ifndef LLVM_CLANG_AST_EXPROBJC_H 15193326Sed#define LLVM_CLANG_AST_EXPROBJC_H 16193326Sed 17218893Sdim#include "clang/AST/DeclObjC.h" 18193326Sed#include "clang/AST/Expr.h" 19193326Sed#include "clang/Basic/IdentifierTable.h" 20193326Sed 21193326Sednamespace clang { 22193326Sed class IdentifierInfo; 23193326Sed class ASTContext; 24198092Srdivacky 25193326Sed/// ObjCStringLiteral, used for Objective-C string literals 26193326Sed/// i.e. @"foo". 27193326Sedclass ObjCStringLiteral : public Expr { 28193326Sed Stmt *String; 29193326Sed SourceLocation AtLoc; 30193326Sedpublic: 31193326Sed ObjCStringLiteral(StringLiteral *SL, QualType T, SourceLocation L) 32218893Sdim : Expr(ObjCStringLiteralClass, T, VK_RValue, OK_Ordinary, false, false, 33218893Sdim false), 34218893Sdim String(SL), AtLoc(L) {} 35193326Sed explicit ObjCStringLiteral(EmptyShell Empty) 36193326Sed : Expr(ObjCStringLiteralClass, Empty) {} 37193326Sed 38193326Sed StringLiteral *getString() { return cast<StringLiteral>(String); } 39193326Sed const StringLiteral *getString() const { return cast<StringLiteral>(String); } 40193326Sed void setString(StringLiteral *S) { String = S; } 41193326Sed 42193326Sed SourceLocation getAtLoc() const { return AtLoc; } 43193326Sed void setAtLoc(SourceLocation L) { AtLoc = L; } 44193326Sed 45218893Sdim SourceRange getSourceRange() const { 46193326Sed return SourceRange(AtLoc, String->getLocEnd()); 47193326Sed } 48198092Srdivacky 49198092Srdivacky static bool classof(const Stmt *T) { 50198092Srdivacky return T->getStmtClass() == ObjCStringLiteralClass; 51193326Sed } 52198092Srdivacky static bool classof(const ObjCStringLiteral *) { return true; } 53198092Srdivacky 54193326Sed // Iterators 55218893Sdim child_range children() { return child_range(&String, &String+1); } 56193326Sed}; 57198092Srdivacky 58193326Sed/// ObjCEncodeExpr, used for @encode in Objective-C. @encode has the same type 59193326Sed/// and behavior as StringLiteral except that the string initializer is obtained 60193326Sed/// from ASTContext with the encoding type as an argument. 61193326Sedclass ObjCEncodeExpr : public Expr { 62207619Srdivacky TypeSourceInfo *EncodedType; 63193326Sed SourceLocation AtLoc, RParenLoc; 64193326Sedpublic: 65207619Srdivacky ObjCEncodeExpr(QualType T, TypeSourceInfo *EncodedType, 66193326Sed SourceLocation at, SourceLocation rp) 67218893Sdim : Expr(ObjCEncodeExprClass, T, VK_LValue, OK_Ordinary, 68218893Sdim EncodedType->getType()->isDependentType(), 69218893Sdim EncodedType->getType()->isDependentType(), 70218893Sdim EncodedType->getType()->containsUnexpandedParameterPack()), 71207619Srdivacky EncodedType(EncodedType), AtLoc(at), RParenLoc(rp) {} 72198092Srdivacky 73193326Sed explicit ObjCEncodeExpr(EmptyShell Empty) : Expr(ObjCEncodeExprClass, Empty){} 74193326Sed 75198092Srdivacky 76193326Sed SourceLocation getAtLoc() const { return AtLoc; } 77193326Sed void setAtLoc(SourceLocation L) { AtLoc = L; } 78193326Sed SourceLocation getRParenLoc() const { return RParenLoc; } 79193326Sed void setRParenLoc(SourceLocation L) { RParenLoc = L; } 80198092Srdivacky 81207619Srdivacky QualType getEncodedType() const { return EncodedType->getType(); } 82193326Sed 83207619Srdivacky TypeSourceInfo *getEncodedTypeSourceInfo() const { return EncodedType; } 84207619Srdivacky void setEncodedTypeSourceInfo(TypeSourceInfo *EncType) { 85207619Srdivacky EncodedType = EncType; 86207619Srdivacky } 87198092Srdivacky 88218893Sdim SourceRange getSourceRange() const { 89193326Sed return SourceRange(AtLoc, RParenLoc); 90193326Sed } 91198092Srdivacky 92193326Sed static bool classof(const Stmt *T) { 93193326Sed return T->getStmtClass() == ObjCEncodeExprClass; 94193326Sed } 95193326Sed static bool classof(const ObjCEncodeExpr *) { return true; } 96198092Srdivacky 97193326Sed // Iterators 98218893Sdim child_range children() { return child_range(); } 99193326Sed}; 100193326Sed 101193326Sed/// ObjCSelectorExpr used for @selector in Objective-C. 102193326Sedclass ObjCSelectorExpr : public Expr { 103193326Sed Selector SelName; 104193326Sed SourceLocation AtLoc, RParenLoc; 105193326Sedpublic: 106193326Sed ObjCSelectorExpr(QualType T, Selector selInfo, 107193326Sed SourceLocation at, SourceLocation rp) 108218893Sdim : Expr(ObjCSelectorExprClass, T, VK_RValue, OK_Ordinary, false, false, 109218893Sdim false), 110218893Sdim SelName(selInfo), AtLoc(at), RParenLoc(rp){} 111193326Sed explicit ObjCSelectorExpr(EmptyShell Empty) 112193326Sed : Expr(ObjCSelectorExprClass, Empty) {} 113193326Sed 114193326Sed Selector getSelector() const { return SelName; } 115193326Sed void setSelector(Selector S) { SelName = S; } 116198092Srdivacky 117193326Sed SourceLocation getAtLoc() const { return AtLoc; } 118193326Sed SourceLocation getRParenLoc() const { return RParenLoc; } 119193326Sed void setAtLoc(SourceLocation L) { AtLoc = L; } 120193326Sed void setRParenLoc(SourceLocation L) { RParenLoc = L; } 121193326Sed 122218893Sdim SourceRange getSourceRange() const { 123193326Sed return SourceRange(AtLoc, RParenLoc); 124193326Sed } 125198092Srdivacky 126193326Sed /// getNumArgs - Return the number of actual arguments to this call. 127193326Sed unsigned getNumArgs() const { return SelName.getNumArgs(); } 128198092Srdivacky 129193326Sed static bool classof(const Stmt *T) { 130193326Sed return T->getStmtClass() == ObjCSelectorExprClass; 131193326Sed } 132193326Sed static bool classof(const ObjCSelectorExpr *) { return true; } 133198092Srdivacky 134193326Sed // Iterators 135218893Sdim child_range children() { return child_range(); } 136193326Sed}; 137198092Srdivacky 138193326Sed/// ObjCProtocolExpr used for protocol expression in Objective-C. This is used 139193326Sed/// as: @protocol(foo), as in: 140193326Sed/// obj conformsToProtocol:@protocol(foo)] 141193326Sed/// The return type is "Protocol*". 142198092Srdivackyclass ObjCProtocolExpr : public Expr { 143198092Srdivacky ObjCProtocolDecl *TheProtocol; 144193326Sed SourceLocation AtLoc, RParenLoc; 145193326Sedpublic: 146193326Sed ObjCProtocolExpr(QualType T, ObjCProtocolDecl *protocol, 147193326Sed SourceLocation at, SourceLocation rp) 148218893Sdim : Expr(ObjCProtocolExprClass, T, VK_RValue, OK_Ordinary, false, false, 149218893Sdim false), 150218893Sdim TheProtocol(protocol), AtLoc(at), RParenLoc(rp) {} 151193326Sed explicit ObjCProtocolExpr(EmptyShell Empty) 152193326Sed : Expr(ObjCProtocolExprClass, Empty) {} 153193326Sed 154194613Sed ObjCProtocolDecl *getProtocol() const { return TheProtocol; } 155194613Sed void setProtocol(ObjCProtocolDecl *P) { TheProtocol = P; } 156198092Srdivacky 157193326Sed SourceLocation getAtLoc() const { return AtLoc; } 158193326Sed SourceLocation getRParenLoc() const { return RParenLoc; } 159193326Sed void setAtLoc(SourceLocation L) { AtLoc = L; } 160193326Sed void setRParenLoc(SourceLocation L) { RParenLoc = L; } 161193326Sed 162218893Sdim SourceRange getSourceRange() const { 163193326Sed return SourceRange(AtLoc, RParenLoc); 164193326Sed } 165198092Srdivacky 166193326Sed static bool classof(const Stmt *T) { 167193326Sed return T->getStmtClass() == ObjCProtocolExprClass; 168193326Sed } 169193326Sed static bool classof(const ObjCProtocolExpr *) { return true; } 170198092Srdivacky 171193326Sed // Iterators 172218893Sdim child_range children() { return child_range(); } 173193326Sed}; 174193326Sed 175193326Sed/// ObjCIvarRefExpr - A reference to an ObjC instance variable. 176193326Sedclass ObjCIvarRefExpr : public Expr { 177193326Sed class ObjCIvarDecl *D; 178193326Sed SourceLocation Loc; 179193326Sed Stmt *Base; 180193326Sed bool IsArrow:1; // True if this is "X->F", false if this is "X.F". 181193326Sed bool IsFreeIvar:1; // True if ivar reference has no base (self assumed). 182198092Srdivacky 183193326Sedpublic: 184218893Sdim ObjCIvarRefExpr(ObjCIvarDecl *d, QualType t, 185218893Sdim SourceLocation l, Expr *base, 186198092Srdivacky bool arrow = false, bool freeIvar = false) : 187218893Sdim Expr(ObjCIvarRefExprClass, t, VK_LValue, OK_Ordinary, 188218893Sdim /*TypeDependent=*/false, base->isValueDependent(), 189218893Sdim base->containsUnexpandedParameterPack()), 190218893Sdim D(d), Loc(l), Base(base), IsArrow(arrow), IsFreeIvar(freeIvar) {} 191198092Srdivacky 192193326Sed explicit ObjCIvarRefExpr(EmptyShell Empty) 193193326Sed : Expr(ObjCIvarRefExprClass, Empty) {} 194193326Sed 195193326Sed ObjCIvarDecl *getDecl() { return D; } 196193326Sed const ObjCIvarDecl *getDecl() const { return D; } 197193326Sed void setDecl(ObjCIvarDecl *d) { D = d; } 198198092Srdivacky 199193326Sed const Expr *getBase() const { return cast<Expr>(Base); } 200193326Sed Expr *getBase() { return cast<Expr>(Base); } 201193326Sed void setBase(Expr * base) { Base = base; } 202198092Srdivacky 203193326Sed bool isArrow() const { return IsArrow; } 204193326Sed bool isFreeIvar() const { return IsFreeIvar; } 205193326Sed void setIsArrow(bool A) { IsArrow = A; } 206193326Sed void setIsFreeIvar(bool A) { IsFreeIvar = A; } 207198092Srdivacky 208193326Sed SourceLocation getLocation() const { return Loc; } 209193326Sed void setLocation(SourceLocation L) { Loc = L; } 210193326Sed 211218893Sdim SourceRange getSourceRange() const { 212193326Sed return isFreeIvar() ? SourceRange(Loc) 213198092Srdivacky : SourceRange(getBase()->getLocStart(), Loc); 214193326Sed } 215198092Srdivacky 216198092Srdivacky static bool classof(const Stmt *T) { 217198092Srdivacky return T->getStmtClass() == ObjCIvarRefExprClass; 218193326Sed } 219193326Sed static bool classof(const ObjCIvarRefExpr *) { return true; } 220198092Srdivacky 221193326Sed // Iterators 222218893Sdim child_range children() { return child_range(&Base, &Base+1); } 223193326Sed}; 224193326Sed 225193326Sed/// ObjCPropertyRefExpr - A dot-syntax expression to access an ObjC 226193326Sed/// property. 227193326Sed/// 228193326Sedclass ObjCPropertyRefExpr : public Expr { 229193326Sedprivate: 230218893Sdim /// If the bool is true, this is an implicit property reference; the 231218893Sdim /// pointer is an (optional) ObjCMethodDecl and Setter may be set. 232218893Sdim /// if the bool is false, this is an explicit property reference; 233218893Sdim /// the pointer is an ObjCPropertyDecl and Setter is always null. 234218893Sdim llvm::PointerIntPair<NamedDecl*, 1, bool> PropertyOrGetter; 235218893Sdim ObjCMethodDecl *Setter; 236218893Sdim 237193326Sed SourceLocation IdLoc; 238218893Sdim 239218893Sdim /// \brief When the receiver in property access is 'super', this is 240218893Sdim /// the location of the 'super' keyword. When it's an interface, 241218893Sdim /// this is that interface. 242218893Sdim SourceLocation ReceiverLoc; 243218893Sdim llvm::PointerUnion3<Stmt*, const Type*, ObjCInterfaceDecl*> Receiver; 244218893Sdim 245193326Sedpublic: 246198092Srdivacky ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t, 247218893Sdim ExprValueKind VK, ExprObjectKind OK, 248193326Sed SourceLocation l, Expr *base) 249218893Sdim : Expr(ObjCPropertyRefExprClass, t, VK, OK, 250218893Sdim /*TypeDependent=*/false, base->isValueDependent(), 251218893Sdim base->containsUnexpandedParameterPack()), 252218893Sdim PropertyOrGetter(PD, false), Setter(0), 253218893Sdim IdLoc(l), ReceiverLoc(), Receiver(base) { 254193326Sed } 255218893Sdim 256218893Sdim ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t, 257218893Sdim ExprValueKind VK, ExprObjectKind OK, 258218893Sdim SourceLocation l, SourceLocation sl, QualType st) 259218893Sdim : Expr(ObjCPropertyRefExprClass, t, VK, OK, 260218893Sdim /*TypeDependent=*/false, false, 261218893Sdim st->containsUnexpandedParameterPack()), 262218893Sdim PropertyOrGetter(PD, false), Setter(0), 263218893Sdim IdLoc(l), ReceiverLoc(sl), Receiver(st.getTypePtr()) { 264218893Sdim } 265198092Srdivacky 266218893Sdim ObjCPropertyRefExpr(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter, 267218893Sdim QualType T, ExprValueKind VK, ExprObjectKind OK, 268218893Sdim SourceLocation IdLoc, Expr *Base) 269218893Sdim : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, 270218893Sdim Base->isValueDependent(), 271218893Sdim Base->containsUnexpandedParameterPack()), 272218893Sdim PropertyOrGetter(Getter, true), Setter(Setter), 273218893Sdim IdLoc(IdLoc), ReceiverLoc(), Receiver(Base) { 274218893Sdim } 275218893Sdim 276218893Sdim ObjCPropertyRefExpr(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter, 277218893Sdim QualType T, ExprValueKind VK, ExprObjectKind OK, 278218893Sdim SourceLocation IdLoc, 279218893Sdim SourceLocation SuperLoc, QualType SuperTy) 280218893Sdim : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, false, false), 281218893Sdim PropertyOrGetter(Getter, true), Setter(Setter), 282218893Sdim IdLoc(IdLoc), ReceiverLoc(SuperLoc), Receiver(SuperTy.getTypePtr()) { 283218893Sdim } 284218893Sdim 285218893Sdim ObjCPropertyRefExpr(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter, 286218893Sdim QualType T, ExprValueKind VK, ExprObjectKind OK, 287218893Sdim SourceLocation IdLoc, 288218893Sdim SourceLocation ReceiverLoc, ObjCInterfaceDecl *Receiver) 289218893Sdim : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, false, false), 290218893Sdim PropertyOrGetter(Getter, true), Setter(Setter), 291218893Sdim IdLoc(IdLoc), ReceiverLoc(ReceiverLoc), Receiver(Receiver) { 292218893Sdim } 293218893Sdim 294193326Sed explicit ObjCPropertyRefExpr(EmptyShell Empty) 295193326Sed : Expr(ObjCPropertyRefExprClass, Empty) {} 296193326Sed 297218893Sdim bool isImplicitProperty() const { return PropertyOrGetter.getInt(); } 298218893Sdim bool isExplicitProperty() const { return !PropertyOrGetter.getInt(); } 299198092Srdivacky 300218893Sdim ObjCPropertyDecl *getExplicitProperty() const { 301218893Sdim assert(!isImplicitProperty()); 302218893Sdim return cast<ObjCPropertyDecl>(PropertyOrGetter.getPointer()); 303218893Sdim } 304198092Srdivacky 305218893Sdim ObjCMethodDecl *getImplicitPropertyGetter() const { 306218893Sdim assert(isImplicitProperty()); 307218893Sdim return cast_or_null<ObjCMethodDecl>(PropertyOrGetter.getPointer()); 308218893Sdim } 309218893Sdim 310218893Sdim ObjCMethodDecl *getImplicitPropertySetter() const { 311218893Sdim assert(isImplicitProperty()); 312218893Sdim return Setter; 313218893Sdim } 314218893Sdim 315218893Sdim Selector getGetterSelector() const { 316218893Sdim if (isImplicitProperty()) 317218893Sdim return getImplicitPropertyGetter()->getSelector(); 318218893Sdim return getExplicitProperty()->getGetterName(); 319218893Sdim } 320218893Sdim 321218893Sdim Selector getSetterSelector() const { 322218893Sdim if (isImplicitProperty()) 323218893Sdim return getImplicitPropertySetter()->getSelector(); 324218893Sdim return getExplicitProperty()->getSetterName(); 325218893Sdim } 326218893Sdim 327218893Sdim const Expr *getBase() const { 328218893Sdim return cast<Expr>(Receiver.get<Stmt*>()); 329218893Sdim } 330218893Sdim Expr *getBase() { 331218893Sdim return cast<Expr>(Receiver.get<Stmt*>()); 332218893Sdim } 333218893Sdim 334193326Sed SourceLocation getLocation() const { return IdLoc; } 335218893Sdim 336218893Sdim SourceLocation getReceiverLocation() const { return ReceiverLoc; } 337218893Sdim QualType getSuperReceiverType() const { 338218893Sdim return QualType(Receiver.get<const Type*>(), 0); 339218893Sdim } 340218893Sdim ObjCInterfaceDecl *getClassReceiver() const { 341218893Sdim return Receiver.get<ObjCInterfaceDecl*>(); 342218893Sdim } 343218893Sdim bool isObjectReceiver() const { return Receiver.is<Stmt*>(); } 344218893Sdim bool isSuperReceiver() const { return Receiver.is<const Type*>(); } 345218893Sdim bool isClassReceiver() const { return Receiver.is<ObjCInterfaceDecl*>(); } 346193326Sed 347218893Sdim SourceRange getSourceRange() const { 348218893Sdim return SourceRange((isObjectReceiver() ? getBase()->getLocStart() 349218893Sdim : getReceiverLocation()), 350218893Sdim IdLoc); 351193326Sed } 352198092Srdivacky 353198092Srdivacky static bool classof(const Stmt *T) { 354198092Srdivacky return T->getStmtClass() == ObjCPropertyRefExprClass; 355193326Sed } 356193326Sed static bool classof(const ObjCPropertyRefExpr *) { return true; } 357198092Srdivacky 358193326Sed // Iterators 359218893Sdim child_range children() { 360218893Sdim if (Receiver.is<Stmt*>()) { 361218893Sdim Stmt **begin = reinterpret_cast<Stmt**>(&Receiver); // hack! 362218893Sdim return child_range(begin, begin+1); 363193326Sed } 364218893Sdim return child_range(); 365193326Sed } 366198092Srdivacky 367218893Sdimprivate: 368218893Sdim friend class ASTStmtReader; 369218893Sdim void setExplicitProperty(ObjCPropertyDecl *D) { 370218893Sdim PropertyOrGetter.setPointer(D); 371218893Sdim PropertyOrGetter.setInt(false); 372218893Sdim Setter = 0; 373193326Sed } 374218893Sdim void setImplicitProperty(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter) { 375218893Sdim PropertyOrGetter.setPointer(Getter); 376218893Sdim PropertyOrGetter.setInt(true); 377218893Sdim this->Setter = Setter; 378218893Sdim } 379218893Sdim void setBase(Expr *Base) { Receiver = Base; } 380218893Sdim void setSuperReceiver(QualType T) { Receiver = T.getTypePtr(); } 381218893Sdim void setClassReceiver(ObjCInterfaceDecl *D) { Receiver = D; } 382198092Srdivacky 383218893Sdim void setLocation(SourceLocation L) { IdLoc = L; } 384218893Sdim void setReceiverLocation(SourceLocation Loc) { ReceiverLoc = Loc; } 385193326Sed}; 386198092Srdivacky 387207619Srdivacky/// \brief An expression that sends a message to the given Objective-C 388207619Srdivacky/// object or class. 389207619Srdivacky/// 390207619Srdivacky/// The following contains two message send expressions: 391207619Srdivacky/// 392207619Srdivacky/// \code 393207619Srdivacky/// [[NSString alloc] initWithString:@"Hello"] 394207619Srdivacky/// \endcode 395207619Srdivacky/// 396207619Srdivacky/// The innermost message send invokes the "alloc" class method on the 397207619Srdivacky/// NSString class, while the outermost message send invokes the 398207619Srdivacky/// "initWithString" instance method on the object returned from 399207619Srdivacky/// NSString's "alloc". In all, an Objective-C message send can take 400207619Srdivacky/// on four different (although related) forms: 401207619Srdivacky/// 402207619Srdivacky/// 1. Send to an object instance. 403207619Srdivacky/// 2. Send to a class. 404207619Srdivacky/// 3. Send to the superclass instance of the current class. 405207619Srdivacky/// 4. Send to the superclass of the current class. 406207619Srdivacky/// 407207619Srdivacky/// All four kinds of message sends are modeled by the ObjCMessageExpr 408207619Srdivacky/// class, and can be distinguished via \c getReceiverKind(). Example: 409207619Srdivacky/// 410193326Sedclass ObjCMessageExpr : public Expr { 411207619Srdivacky /// \brief The number of arguments in the message send, not 412207619Srdivacky /// including the receiver. 413207619Srdivacky unsigned NumArgs : 16; 414198092Srdivacky 415207619Srdivacky /// \brief The kind of message send this is, which is one of the 416207619Srdivacky /// ReceiverKind values. 417207619Srdivacky /// 418207619Srdivacky /// We pad this out to a byte to avoid excessive masking and shifting. 419207619Srdivacky unsigned Kind : 8; 420198092Srdivacky 421207619Srdivacky /// \brief Whether we have an actual method prototype in \c 422207619Srdivacky /// SelectorOrMethod. 423207619Srdivacky /// 424207619Srdivacky /// When non-zero, we have a method declaration; otherwise, we just 425207619Srdivacky /// have a selector. 426207619Srdivacky unsigned HasMethod : 8; 427204962Srdivacky 428207619Srdivacky /// \brief When the message expression is a send to 'super', this is 429207619Srdivacky /// the location of the 'super' keyword. 430207619Srdivacky SourceLocation SuperLoc; 431198092Srdivacky 432207619Srdivacky /// \brief Stores either the selector that this message is sending 433207619Srdivacky /// to (when \c HasMethod is zero) or an \c ObjCMethodDecl pointer 434207619Srdivacky /// referring to the method that we type-checked against. 435207619Srdivacky uintptr_t SelectorOrMethod; 436193326Sed 437218893Sdim /// \brief Location of the selector. 438218893Sdim SourceLocation SelectorLoc; 439218893Sdim 440207619Srdivacky /// \brief The source locations of the open and close square 441207619Srdivacky /// brackets ('[' and ']', respectively). 442207619Srdivacky SourceLocation LBracLoc, RBracLoc; 443193326Sed 444207619Srdivacky ObjCMessageExpr(EmptyShell Empty, unsigned NumArgs) 445207619Srdivacky : Expr(ObjCMessageExprClass, Empty), NumArgs(NumArgs), Kind(0), 446207619Srdivacky HasMethod(0), SelectorOrMethod(0) { } 447193326Sed 448218893Sdim ObjCMessageExpr(QualType T, ExprValueKind VK, 449207619Srdivacky SourceLocation LBracLoc, 450207619Srdivacky SourceLocation SuperLoc, 451207619Srdivacky bool IsInstanceSuper, 452207619Srdivacky QualType SuperType, 453207619Srdivacky Selector Sel, 454218893Sdim SourceLocation SelLoc, 455207619Srdivacky ObjCMethodDecl *Method, 456207619Srdivacky Expr **Args, unsigned NumArgs, 457207619Srdivacky SourceLocation RBracLoc); 458218893Sdim ObjCMessageExpr(QualType T, ExprValueKind VK, 459207619Srdivacky SourceLocation LBracLoc, 460207619Srdivacky TypeSourceInfo *Receiver, 461207619Srdivacky Selector Sel, 462218893Sdim SourceLocation SelLoc, 463207619Srdivacky ObjCMethodDecl *Method, 464207619Srdivacky Expr **Args, unsigned NumArgs, 465207619Srdivacky SourceLocation RBracLoc); 466218893Sdim ObjCMessageExpr(QualType T, ExprValueKind VK, 467207619Srdivacky SourceLocation LBracLoc, 468207619Srdivacky Expr *Receiver, 469207619Srdivacky Selector Sel, 470218893Sdim SourceLocation SelLoc, 471207619Srdivacky ObjCMethodDecl *Method, 472207619Srdivacky Expr **Args, unsigned NumArgs, 473207619Srdivacky SourceLocation RBracLoc); 474198092Srdivacky 475207619Srdivacky /// \brief Retrieve the pointer value of the message receiver. 476207619Srdivacky void *getReceiverPointer() const { 477207619Srdivacky return *const_cast<void **>( 478207619Srdivacky reinterpret_cast<const void * const*>(this + 1)); 479207619Srdivacky } 480207619Srdivacky 481207619Srdivacky /// \brief Set the pointer value of the message receiver. 482207619Srdivacky void setReceiverPointer(void *Value) { 483207619Srdivacky *reinterpret_cast<void **>(this + 1) = Value; 484207619Srdivacky } 485207619Srdivacky 486193326Sedpublic: 487207619Srdivacky /// \brief The kind of receiver this message is sending to. 488207619Srdivacky enum ReceiverKind { 489207619Srdivacky /// \brief The receiver is a class. 490207619Srdivacky Class = 0, 491207619Srdivacky /// \brief The receiver is an object instance. 492207619Srdivacky Instance, 493207619Srdivacky /// \brief The receiver is a superclass. 494207619Srdivacky SuperClass, 495207619Srdivacky /// \brief The receiver is the instance of the superclass object. 496207619Srdivacky SuperInstance 497207619Srdivacky }; 498193326Sed 499207619Srdivacky /// \brief Create a message send to super. 500207619Srdivacky /// 501207619Srdivacky /// \param Context The ASTContext in which this expression will be created. 502207619Srdivacky /// 503207619Srdivacky /// \param T The result type of this message. 504207619Srdivacky /// 505218893Sdim /// \param VK The value kind of this message. A message returning 506218893Sdim /// a l-value or r-value reference will be an l-value or x-value, 507218893Sdim /// respectively. 508218893Sdim /// 509207619Srdivacky /// \param LBrac The location of the open square bracket '['. 510207619Srdivacky /// 511207619Srdivacky /// \param SuperLoc The location of the "super" keyword. 512207619Srdivacky /// 513207619Srdivacky /// \param IsInstanceSuper Whether this is an instance "super" 514207619Srdivacky /// message (otherwise, it's a class "super" message). 515207619Srdivacky /// 516207619Srdivacky /// \param Sel The selector used to determine which method gets called. 517207619Srdivacky /// 518207619Srdivacky /// \param Method The Objective-C method against which this message 519207619Srdivacky /// send was type-checked. May be NULL. 520207619Srdivacky /// 521207619Srdivacky /// \param Args The message send arguments. 522207619Srdivacky /// 523207619Srdivacky /// \param NumArgs The number of arguments. 524207619Srdivacky /// 525207619Srdivacky /// \param RBracLoc The location of the closing square bracket ']'. 526218893Sdim static ObjCMessageExpr *Create(ASTContext &Context, QualType T, 527218893Sdim ExprValueKind VK, 528207619Srdivacky SourceLocation LBracLoc, 529207619Srdivacky SourceLocation SuperLoc, 530207619Srdivacky bool IsInstanceSuper, 531207619Srdivacky QualType SuperType, 532207619Srdivacky Selector Sel, 533218893Sdim SourceLocation SelLoc, 534207619Srdivacky ObjCMethodDecl *Method, 535207619Srdivacky Expr **Args, unsigned NumArgs, 536207619Srdivacky SourceLocation RBracLoc); 537198092Srdivacky 538207619Srdivacky /// \brief Create a class message send. 539207619Srdivacky /// 540207619Srdivacky /// \param Context The ASTContext in which this expression will be created. 541207619Srdivacky /// 542207619Srdivacky /// \param T The result type of this message. 543207619Srdivacky /// 544218893Sdim /// \param VK The value kind of this message. A message returning 545218893Sdim /// a l-value or r-value reference will be an l-value or x-value, 546218893Sdim /// respectively. 547218893Sdim /// 548207619Srdivacky /// \param LBrac The location of the open square bracket '['. 549207619Srdivacky /// 550207619Srdivacky /// \param Receiver The type of the receiver, including 551207619Srdivacky /// source-location information. 552207619Srdivacky /// 553207619Srdivacky /// \param Sel The selector used to determine which method gets called. 554207619Srdivacky /// 555207619Srdivacky /// \param Method The Objective-C method against which this message 556207619Srdivacky /// send was type-checked. May be NULL. 557207619Srdivacky /// 558207619Srdivacky /// \param Args The message send arguments. 559207619Srdivacky /// 560207619Srdivacky /// \param NumArgs The number of arguments. 561207619Srdivacky /// 562207619Srdivacky /// \param RBracLoc The location of the closing square bracket ']'. 563207619Srdivacky static ObjCMessageExpr *Create(ASTContext &Context, QualType T, 564218893Sdim ExprValueKind VK, 565207619Srdivacky SourceLocation LBracLoc, 566207619Srdivacky TypeSourceInfo *Receiver, 567207619Srdivacky Selector Sel, 568218893Sdim SourceLocation SelLoc, 569207619Srdivacky ObjCMethodDecl *Method, 570207619Srdivacky Expr **Args, unsigned NumArgs, 571207619Srdivacky SourceLocation RBracLoc); 572198092Srdivacky 573207619Srdivacky /// \brief Create an instance message send. 574207619Srdivacky /// 575207619Srdivacky /// \param Context The ASTContext in which this expression will be created. 576207619Srdivacky /// 577207619Srdivacky /// \param T The result type of this message. 578207619Srdivacky /// 579218893Sdim /// \param VK The value kind of this message. A message returning 580218893Sdim /// a l-value or r-value reference will be an l-value or x-value, 581218893Sdim /// respectively. 582218893Sdim /// 583207619Srdivacky /// \param LBrac The location of the open square bracket '['. 584207619Srdivacky /// 585207619Srdivacky /// \param Receiver The expression used to produce the object that 586207619Srdivacky /// will receive this message. 587207619Srdivacky /// 588207619Srdivacky /// \param Sel The selector used to determine which method gets called. 589207619Srdivacky /// 590207619Srdivacky /// \param Method The Objective-C method against which this message 591207619Srdivacky /// send was type-checked. May be NULL. 592207619Srdivacky /// 593207619Srdivacky /// \param Args The message send arguments. 594207619Srdivacky /// 595207619Srdivacky /// \param NumArgs The number of arguments. 596207619Srdivacky /// 597207619Srdivacky /// \param RBracLoc The location of the closing square bracket ']'. 598207619Srdivacky static ObjCMessageExpr *Create(ASTContext &Context, QualType T, 599218893Sdim ExprValueKind VK, 600207619Srdivacky SourceLocation LBracLoc, 601207619Srdivacky Expr *Receiver, 602207619Srdivacky Selector Sel, 603218893Sdim SourceLocation SelLoc, 604207619Srdivacky ObjCMethodDecl *Method, 605207619Srdivacky Expr **Args, unsigned NumArgs, 606207619Srdivacky SourceLocation RBracLoc); 607198092Srdivacky 608207619Srdivacky /// \brief Create an empty Objective-C message expression, to be 609207619Srdivacky /// filled in by subsequent calls. 610207619Srdivacky /// 611207619Srdivacky /// \param Context The context in which the message send will be created. 612207619Srdivacky /// 613207619Srdivacky /// \param NumArgs The number of message arguments, not including 614207619Srdivacky /// the receiver. 615207619Srdivacky static ObjCMessageExpr *CreateEmpty(ASTContext &Context, unsigned NumArgs); 616198092Srdivacky 617207619Srdivacky /// \brief Determine the kind of receiver that this message is being 618207619Srdivacky /// sent to. 619207619Srdivacky ReceiverKind getReceiverKind() const { return (ReceiverKind)Kind; } 620207619Srdivacky 621218893Sdim /// \brief Source range of the receiver. 622218893Sdim SourceRange getReceiverRange() const; 623218893Sdim 624207619Srdivacky /// \brief Determine whether this is an instance message to either a 625207619Srdivacky /// computed object or to super. 626207619Srdivacky bool isInstanceMessage() const { 627207619Srdivacky return getReceiverKind() == Instance || getReceiverKind() == SuperInstance; 628198092Srdivacky } 629207619Srdivacky 630207619Srdivacky /// \brief Determine whether this is an class message to either a 631207619Srdivacky /// specified class or to super. 632207619Srdivacky bool isClassMessage() const { 633207619Srdivacky return getReceiverKind() == Class || getReceiverKind() == SuperClass; 634193326Sed } 635198092Srdivacky 636207619Srdivacky /// \brief Returns the receiver of an instance message. 637207619Srdivacky /// 638207619Srdivacky /// \brief Returns the object expression for an instance message, or 639207619Srdivacky /// NULL for a message that is not an instance message. 640207619Srdivacky Expr *getInstanceReceiver() { 641207619Srdivacky if (getReceiverKind() == Instance) 642207619Srdivacky return static_cast<Expr *>(getReceiverPointer()); 643198092Srdivacky 644207619Srdivacky return 0; 645207619Srdivacky } 646207619Srdivacky const Expr *getInstanceReceiver() const { 647207619Srdivacky return const_cast<ObjCMessageExpr*>(this)->getInstanceReceiver(); 648207619Srdivacky } 649198092Srdivacky 650207619Srdivacky /// \brief Turn this message send into an instance message that 651207619Srdivacky /// computes the receiver object with the given expression. 652207619Srdivacky void setInstanceReceiver(Expr *rec) { 653207619Srdivacky Kind = Instance; 654207619Srdivacky setReceiverPointer(rec); 655207619Srdivacky } 656207619Srdivacky 657207619Srdivacky /// \brief Returns the type of a class message send, or NULL if the 658207619Srdivacky /// message is not a class message. 659207619Srdivacky QualType getClassReceiver() const { 660207619Srdivacky if (TypeSourceInfo *TSInfo = getClassReceiverTypeInfo()) 661207619Srdivacky return TSInfo->getType(); 662204962Srdivacky 663207619Srdivacky return QualType(); 664207619Srdivacky } 665204962Srdivacky 666207619Srdivacky /// \brief Returns a type-source information of a class message 667207619Srdivacky /// send, or NULL if the message is not a class message. 668207619Srdivacky TypeSourceInfo *getClassReceiverTypeInfo() const { 669207619Srdivacky if (getReceiverKind() == Class) 670207619Srdivacky return reinterpret_cast<TypeSourceInfo *>(getReceiverPointer()); 671207619Srdivacky return 0; 672207619Srdivacky } 673204962Srdivacky 674207619Srdivacky void setClassReceiver(TypeSourceInfo *TSInfo) { 675207619Srdivacky Kind = Class; 676207619Srdivacky setReceiverPointer(TSInfo); 677207619Srdivacky } 678204962Srdivacky 679207619Srdivacky /// \brief Retrieve the location of the 'super' keyword for a class 680207619Srdivacky /// or instance message to 'super', otherwise an invalid source location. 681207619Srdivacky SourceLocation getSuperLoc() const { 682207619Srdivacky if (getReceiverKind() == SuperInstance || getReceiverKind() == SuperClass) 683207619Srdivacky return SuperLoc; 684198092Srdivacky 685207619Srdivacky return SourceLocation(); 686193326Sed } 687198092Srdivacky 688207619Srdivacky /// \brief Retrieve the Objective-C interface to which this message 689207619Srdivacky /// is being directed, if known. 690207619Srdivacky /// 691207619Srdivacky /// This routine cross-cuts all of the different kinds of message 692207619Srdivacky /// sends to determine what the underlying (statically known) type 693207619Srdivacky /// of the receiver will be; use \c getReceiverKind() to determine 694207619Srdivacky /// whether the message is a class or an instance method, whether it 695207619Srdivacky /// is a send to super or not, etc. 696207619Srdivacky /// 697207619Srdivacky /// \returns The Objective-C interface if known, otherwise NULL. 698207619Srdivacky ObjCInterfaceDecl *getReceiverInterface() const; 699207619Srdivacky 700207619Srdivacky /// \brief Retrieve the type referred to by 'super'. 701207619Srdivacky /// 702207619Srdivacky /// The returned type will either be an ObjCInterfaceType (for an 703207619Srdivacky /// class message to super) or an ObjCObjectPointerType that refers 704207619Srdivacky /// to a class (for an instance message to super); 705207619Srdivacky QualType getSuperType() const { 706207619Srdivacky if (getReceiverKind() == SuperInstance || getReceiverKind() == SuperClass) 707207619Srdivacky return QualType::getFromOpaquePtr(getReceiverPointer()); 708207619Srdivacky 709207619Srdivacky return QualType(); 710207619Srdivacky } 711207619Srdivacky 712207619Srdivacky void setSuper(SourceLocation Loc, QualType T, bool IsInstanceSuper) { 713207619Srdivacky Kind = IsInstanceSuper? SuperInstance : SuperClass; 714207619Srdivacky SuperLoc = Loc; 715207619Srdivacky setReceiverPointer(T.getAsOpaquePtr()); 716207619Srdivacky } 717207619Srdivacky 718207619Srdivacky Selector getSelector() const; 719207619Srdivacky 720207619Srdivacky void setSelector(Selector S) { 721207619Srdivacky HasMethod = false; 722207619Srdivacky SelectorOrMethod = reinterpret_cast<uintptr_t>(S.getAsOpaquePtr()); 723207619Srdivacky } 724207619Srdivacky 725207619Srdivacky const ObjCMethodDecl *getMethodDecl() const { 726207619Srdivacky if (HasMethod) 727207619Srdivacky return reinterpret_cast<const ObjCMethodDecl *>(SelectorOrMethod); 728207619Srdivacky 729207619Srdivacky return 0; 730207619Srdivacky } 731207619Srdivacky 732207619Srdivacky ObjCMethodDecl *getMethodDecl() { 733207619Srdivacky if (HasMethod) 734207619Srdivacky return reinterpret_cast<ObjCMethodDecl *>(SelectorOrMethod); 735207619Srdivacky 736207619Srdivacky return 0; 737207619Srdivacky } 738207619Srdivacky 739207619Srdivacky void setMethodDecl(ObjCMethodDecl *MD) { 740207619Srdivacky HasMethod = true; 741207619Srdivacky SelectorOrMethod = reinterpret_cast<uintptr_t>(MD); 742207619Srdivacky } 743207619Srdivacky 744207619Srdivacky /// \brief Return the number of actual arguments in this message, 745207619Srdivacky /// not counting the receiver. 746193326Sed unsigned getNumArgs() const { return NumArgs; } 747207619Srdivacky 748207619Srdivacky /// \brief Retrieve the arguments to this message, not including the 749207619Srdivacky /// receiver. 750218893Sdim Expr **getArgs() { 751218893Sdim return reinterpret_cast<Expr **>(this + 1) + 1; 752193326Sed } 753218893Sdim const Expr * const *getArgs() const { 754218893Sdim return reinterpret_cast<const Expr * const *>(this + 1) + 1; 755207619Srdivacky } 756198092Srdivacky 757193326Sed /// getArg - Return the specified argument. 758193326Sed Expr *getArg(unsigned Arg) { 759193326Sed assert(Arg < NumArgs && "Arg access out of range!"); 760207619Srdivacky return cast<Expr>(getArgs()[Arg]); 761193326Sed } 762193326Sed const Expr *getArg(unsigned Arg) const { 763193326Sed assert(Arg < NumArgs && "Arg access out of range!"); 764207619Srdivacky return cast<Expr>(getArgs()[Arg]); 765193326Sed } 766193326Sed /// setArg - Set the specified argument. 767193326Sed void setArg(unsigned Arg, Expr *ArgExpr) { 768193326Sed assert(Arg < NumArgs && "Arg access out of range!"); 769207619Srdivacky getArgs()[Arg] = ArgExpr; 770193326Sed } 771198092Srdivacky 772207619Srdivacky SourceLocation getLeftLoc() const { return LBracLoc; } 773207619Srdivacky SourceLocation getRightLoc() const { return RBracLoc; } 774218893Sdim SourceLocation getSelectorLoc() const { return SelectorLoc; } 775193326Sed 776193326Sed void setSourceRange(SourceRange R) { 777207619Srdivacky LBracLoc = R.getBegin(); 778207619Srdivacky RBracLoc = R.getEnd(); 779193326Sed } 780218893Sdim SourceRange getSourceRange() const { 781207619Srdivacky return SourceRange(LBracLoc, RBracLoc); 782193326Sed } 783193326Sed 784193326Sed static bool classof(const Stmt *T) { 785193326Sed return T->getStmtClass() == ObjCMessageExprClass; 786193326Sed } 787193326Sed static bool classof(const ObjCMessageExpr *) { return true; } 788198092Srdivacky 789193326Sed // Iterators 790218893Sdim child_range children(); 791198092Srdivacky 792193326Sed typedef ExprIterator arg_iterator; 793193326Sed typedef ConstExprIterator const_arg_iterator; 794198092Srdivacky 795218893Sdim arg_iterator arg_begin() { return reinterpret_cast<Stmt **>(getArgs()); } 796218893Sdim arg_iterator arg_end() { 797218893Sdim return reinterpret_cast<Stmt **>(getArgs() + NumArgs); 798193326Sed } 799218893Sdim const_arg_iterator arg_begin() const { 800218893Sdim return reinterpret_cast<Stmt const * const*>(getArgs()); 801218893Sdim } 802218893Sdim const_arg_iterator arg_end() const { 803218893Sdim return reinterpret_cast<Stmt const * const*>(getArgs() + NumArgs); 804218893Sdim } 805193326Sed 806218893Sdim friend class ASTStmtReader; 807218893Sdim friend class ASTStmtWriter; 808193326Sed}; 809193326Sed 810198092Srdivacky/// ObjCIsaExpr - Represent X->isa and X.isa when X is an ObjC 'id' type. 811198092Srdivacky/// (similiar in spirit to MemberExpr). 812198092Srdivackyclass ObjCIsaExpr : public Expr { 813198092Srdivacky /// Base - the expression for the base object pointer. 814198092Srdivacky Stmt *Base; 815198092Srdivacky 816198092Srdivacky /// IsaMemberLoc - This is the location of the 'isa'. 817198092Srdivacky SourceLocation IsaMemberLoc; 818198092Srdivacky 819198092Srdivacky /// IsArrow - True if this is "X->F", false if this is "X.F". 820198092Srdivacky bool IsArrow; 821198092Srdivackypublic: 822198092Srdivacky ObjCIsaExpr(Expr *base, bool isarrow, SourceLocation l, QualType ty) 823218893Sdim : Expr(ObjCIsaExprClass, ty, VK_LValue, OK_Ordinary, 824218893Sdim /*TypeDependent=*/false, base->isValueDependent(), 825218893Sdim /*ContainsUnexpandedParameterPack=*/false), 826198092Srdivacky Base(base), IsaMemberLoc(l), IsArrow(isarrow) {} 827198092Srdivacky 828198092Srdivacky /// \brief Build an empty expression. 829198092Srdivacky explicit ObjCIsaExpr(EmptyShell Empty) : Expr(ObjCIsaExprClass, Empty) { } 830198092Srdivacky 831198092Srdivacky void setBase(Expr *E) { Base = E; } 832198092Srdivacky Expr *getBase() const { return cast<Expr>(Base); } 833198092Srdivacky 834198092Srdivacky bool isArrow() const { return IsArrow; } 835198092Srdivacky void setArrow(bool A) { IsArrow = A; } 836198092Srdivacky 837198092Srdivacky /// getMemberLoc - Return the location of the "member", in X->F, it is the 838198092Srdivacky /// location of 'F'. 839198092Srdivacky SourceLocation getIsaMemberLoc() const { return IsaMemberLoc; } 840198092Srdivacky void setIsaMemberLoc(SourceLocation L) { IsaMemberLoc = L; } 841198092Srdivacky 842218893Sdim SourceRange getSourceRange() const { 843198092Srdivacky return SourceRange(getBase()->getLocStart(), IsaMemberLoc); 844198092Srdivacky } 845198092Srdivacky 846218893Sdim SourceLocation getExprLoc() const { return IsaMemberLoc; } 847198092Srdivacky 848198092Srdivacky static bool classof(const Stmt *T) { 849198092Srdivacky return T->getStmtClass() == ObjCIsaExprClass; 850198092Srdivacky } 851198092Srdivacky static bool classof(const ObjCIsaExpr *) { return true; } 852198092Srdivacky 853198092Srdivacky // Iterators 854218893Sdim child_range children() { return child_range(&Base, &Base+1); } 855198092Srdivacky}; 856198092Srdivacky 857193326Sed} // end namespace clang 858193326Sed 859193326Sed#endif 860