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" 19226633Sdim#include "clang/AST/SelectorLocationsKind.h" 20193326Sed#include "clang/Basic/IdentifierTable.h" 21234353Sdim#include "llvm/Support/Compiler.h" 22193326Sed 23193326Sednamespace clang { 24193326Sed class IdentifierInfo; 25193326Sed class ASTContext; 26198092Srdivacky 27193326Sed/// ObjCStringLiteral, used for Objective-C string literals 28193326Sed/// i.e. @"foo". 29193326Sedclass ObjCStringLiteral : public Expr { 30193326Sed Stmt *String; 31193326Sed SourceLocation AtLoc; 32193326Sedpublic: 33193326Sed ObjCStringLiteral(StringLiteral *SL, QualType T, SourceLocation L) 34218893Sdim : Expr(ObjCStringLiteralClass, T, VK_RValue, OK_Ordinary, false, false, 35224145Sdim false, false), 36218893Sdim String(SL), AtLoc(L) {} 37193326Sed explicit ObjCStringLiteral(EmptyShell Empty) 38193326Sed : Expr(ObjCStringLiteralClass, Empty) {} 39193326Sed 40193326Sed StringLiteral *getString() { return cast<StringLiteral>(String); } 41193326Sed const StringLiteral *getString() const { return cast<StringLiteral>(String); } 42193326Sed void setString(StringLiteral *S) { String = S; } 43193326Sed 44193326Sed SourceLocation getAtLoc() const { return AtLoc; } 45193326Sed void setAtLoc(SourceLocation L) { AtLoc = L; } 46193326Sed 47249423Sdim SourceLocation getLocStart() const LLVM_READONLY { return AtLoc; } 48249423Sdim SourceLocation getLocEnd() const LLVM_READONLY { return String->getLocEnd(); } 49198092Srdivacky 50198092Srdivacky static bool classof(const Stmt *T) { 51198092Srdivacky return T->getStmtClass() == ObjCStringLiteralClass; 52193326Sed } 53198092Srdivacky 54193326Sed // Iterators 55218893Sdim child_range children() { return child_range(&String, &String+1); } 56193326Sed}; 57198092Srdivacky 58234353Sdim/// ObjCBoolLiteralExpr - Objective-C Boolean Literal. 59234353Sdim/// 60234353Sdimclass ObjCBoolLiteralExpr : public Expr { 61234353Sdim bool Value; 62234353Sdim SourceLocation Loc; 63234353Sdimpublic: 64234353Sdim ObjCBoolLiteralExpr(bool val, QualType Ty, SourceLocation l) : 65234353Sdim Expr(ObjCBoolLiteralExprClass, Ty, VK_RValue, OK_Ordinary, false, false, 66234353Sdim false, false), Value(val), Loc(l) {} 67234353Sdim 68234353Sdim explicit ObjCBoolLiteralExpr(EmptyShell Empty) 69234353Sdim : Expr(ObjCBoolLiteralExprClass, Empty) { } 70234353Sdim 71234353Sdim bool getValue() const { return Value; } 72234353Sdim void setValue(bool V) { Value = V; } 73234353Sdim 74249423Sdim SourceLocation getLocStart() const LLVM_READONLY { return Loc; } 75249423Sdim SourceLocation getLocEnd() const LLVM_READONLY { return Loc; } 76249423Sdim 77234353Sdim SourceLocation getLocation() const { return Loc; } 78234353Sdim void setLocation(SourceLocation L) { Loc = L; } 79234353Sdim 80234353Sdim static bool classof(const Stmt *T) { 81234353Sdim return T->getStmtClass() == ObjCBoolLiteralExprClass; 82234353Sdim } 83234353Sdim 84234353Sdim // Iterators 85234353Sdim child_range children() { return child_range(); } 86234353Sdim}; 87234353Sdim 88239462Sdim/// ObjCBoxedExpr - used for generalized expression boxing. 89239462Sdim/// as in: @(strdup("hello world")) or @(random()) 90239462Sdim/// Also used for boxing non-parenthesized numeric literals; 91239462Sdim/// as in: @42 or \@true (c++/objc++) or \@__yes (c/objc). 92239462Sdimclass ObjCBoxedExpr : public Expr { 93239462Sdim Stmt *SubExpr; 94239462Sdim ObjCMethodDecl *BoxingMethod; 95239462Sdim SourceRange Range; 96234353Sdimpublic: 97239462Sdim ObjCBoxedExpr(Expr *E, QualType T, ObjCMethodDecl *method, 98239462Sdim SourceRange R) 99239462Sdim : Expr(ObjCBoxedExprClass, T, VK_RValue, OK_Ordinary, 100239462Sdim E->isTypeDependent(), E->isValueDependent(), 101239462Sdim E->isInstantiationDependent(), E->containsUnexpandedParameterPack()), 102239462Sdim SubExpr(E), BoxingMethod(method), Range(R) {} 103239462Sdim explicit ObjCBoxedExpr(EmptyShell Empty) 104239462Sdim : Expr(ObjCBoxedExprClass, Empty) {} 105234353Sdim 106239462Sdim Expr *getSubExpr() { return cast<Expr>(SubExpr); } 107239462Sdim const Expr *getSubExpr() const { return cast<Expr>(SubExpr); } 108234353Sdim 109239462Sdim ObjCMethodDecl *getBoxingMethod() const { 110239462Sdim return BoxingMethod; 111234353Sdim } 112234353Sdim 113239462Sdim SourceLocation getAtLoc() const { return Range.getBegin(); } 114239462Sdim 115249423Sdim SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); } 116249423Sdim SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); } 117234353Sdim SourceRange getSourceRange() const LLVM_READONLY { 118239462Sdim return Range; 119234353Sdim } 120239462Sdim 121234353Sdim static bool classof(const Stmt *T) { 122239462Sdim return T->getStmtClass() == ObjCBoxedExprClass; 123234353Sdim } 124234353Sdim 125234353Sdim // Iterators 126239462Sdim child_range children() { return child_range(&SubExpr, &SubExpr+1); } 127239462Sdim 128234353Sdim friend class ASTStmtReader; 129234353Sdim}; 130234353Sdim 131234353Sdim/// ObjCArrayLiteral - used for objective-c array containers; as in: 132234353Sdim/// @[@"Hello", NSApp, [NSNumber numberWithInt:42]]; 133234353Sdimclass ObjCArrayLiteral : public Expr { 134234353Sdim unsigned NumElements; 135234353Sdim SourceRange Range; 136234353Sdim ObjCMethodDecl *ArrayWithObjectsMethod; 137234353Sdim 138249423Sdim ObjCArrayLiteral(ArrayRef<Expr *> Elements, 139234353Sdim QualType T, ObjCMethodDecl * Method, 140234353Sdim SourceRange SR); 141234353Sdim 142234353Sdim explicit ObjCArrayLiteral(EmptyShell Empty, unsigned NumElements) 143234353Sdim : Expr(ObjCArrayLiteralClass, Empty), NumElements(NumElements) {} 144234353Sdim 145234353Sdimpublic: 146263508Sdim static ObjCArrayLiteral *Create(const ASTContext &C, 147249423Sdim ArrayRef<Expr *> Elements, 148234353Sdim QualType T, ObjCMethodDecl * Method, 149234353Sdim SourceRange SR); 150234353Sdim 151263508Sdim static ObjCArrayLiteral *CreateEmpty(const ASTContext &C, 152263508Sdim unsigned NumElements); 153234353Sdim 154249423Sdim SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); } 155249423Sdim SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); } 156234353Sdim SourceRange getSourceRange() const LLVM_READONLY { return Range; } 157234353Sdim 158234353Sdim static bool classof(const Stmt *T) { 159234353Sdim return T->getStmtClass() == ObjCArrayLiteralClass; 160234353Sdim } 161234353Sdim 162234353Sdim /// \brief Retrieve elements of array of literals. 163234353Sdim Expr **getElements() { return reinterpret_cast<Expr **>(this + 1); } 164234353Sdim 165234353Sdim /// \brief Retrieve elements of array of literals. 166234353Sdim const Expr * const *getElements() const { 167234353Sdim return reinterpret_cast<const Expr * const*>(this + 1); 168234353Sdim } 169234353Sdim 170234353Sdim /// getNumElements - Return number of elements of objective-c array literal. 171234353Sdim unsigned getNumElements() const { return NumElements; } 172234353Sdim 173234353Sdim /// getExpr - Return the Expr at the specified index. 174234353Sdim Expr *getElement(unsigned Index) { 175234353Sdim assert((Index < NumElements) && "Arg access out of range!"); 176234353Sdim return cast<Expr>(getElements()[Index]); 177234353Sdim } 178234353Sdim const Expr *getElement(unsigned Index) const { 179234353Sdim assert((Index < NumElements) && "Arg access out of range!"); 180234353Sdim return cast<Expr>(getElements()[Index]); 181234353Sdim } 182234353Sdim 183234353Sdim ObjCMethodDecl *getArrayWithObjectsMethod() const { 184234353Sdim return ArrayWithObjectsMethod; 185234353Sdim } 186234353Sdim 187234353Sdim // Iterators 188234353Sdim child_range children() { 189234353Sdim return child_range((Stmt **)getElements(), 190234353Sdim (Stmt **)getElements() + NumElements); 191234353Sdim } 192234353Sdim 193234353Sdim friend class ASTStmtReader; 194234353Sdim}; 195234353Sdim 196234353Sdim/// \brief An element in an Objective-C dictionary literal. 197234353Sdim/// 198234353Sdimstruct ObjCDictionaryElement { 199234353Sdim /// \brief The key for the dictionary element. 200234353Sdim Expr *Key; 201234353Sdim 202234353Sdim /// \brief The value of the dictionary element. 203234353Sdim Expr *Value; 204234353Sdim 205234353Sdim /// \brief The location of the ellipsis, if this is a pack expansion. 206234353Sdim SourceLocation EllipsisLoc; 207234353Sdim 208234353Sdim /// \brief The number of elements this pack expansion will expand to, if 209234353Sdim /// this is a pack expansion and is known. 210249423Sdim Optional<unsigned> NumExpansions; 211234353Sdim 212234353Sdim /// \brief Determines whether this dictionary element is a pack expansion. 213234353Sdim bool isPackExpansion() const { return EllipsisLoc.isValid(); } 214234353Sdim}; 215249423Sdim} // end namespace clang 216234353Sdim 217249423Sdimnamespace llvm { 218249423Sdimtemplate <> struct isPodLike<clang::ObjCDictionaryElement> : llvm::true_type {}; 219249423Sdim} 220249423Sdim 221249423Sdimnamespace clang { 222234353Sdim/// ObjCDictionaryLiteral - AST node to represent objective-c dictionary 223234353Sdim/// literals; as in: @{@"name" : NSUserName(), @"date" : [NSDate date] }; 224234353Sdimclass ObjCDictionaryLiteral : public Expr { 225234353Sdim /// \brief Key/value pair used to store the key and value of a given element. 226234353Sdim /// 227234353Sdim /// Objects of this type are stored directly after the expression. 228234353Sdim struct KeyValuePair { 229234353Sdim Expr *Key; 230234353Sdim Expr *Value; 231234353Sdim }; 232234353Sdim 233234353Sdim /// \brief Data that describes an element that is a pack expansion, used if any 234234353Sdim /// of the elements in the dictionary literal are pack expansions. 235234353Sdim struct ExpansionData { 236234353Sdim /// \brief The location of the ellipsis, if this element is a pack 237234353Sdim /// expansion. 238234353Sdim SourceLocation EllipsisLoc; 239234353Sdim 240234353Sdim /// \brief If non-zero, the number of elements that this pack 241234353Sdim /// expansion will expand to (+1). 242234353Sdim unsigned NumExpansionsPlusOne; 243234353Sdim }; 244234353Sdim 245234353Sdim /// \brief The number of elements in this dictionary literal. 246234353Sdim unsigned NumElements : 31; 247234353Sdim 248234353Sdim /// \brief Determine whether this dictionary literal has any pack expansions. 249234353Sdim /// 250234353Sdim /// If the dictionary literal has pack expansions, then there will 251234353Sdim /// be an array of pack expansion data following the array of 252234353Sdim /// key/value pairs, which provide the locations of the ellipses (if 253234353Sdim /// any) and number of elements in the expansion (if known). If 254234353Sdim /// there are no pack expansions, we optimize away this storage. 255234353Sdim unsigned HasPackExpansions : 1; 256234353Sdim 257234353Sdim SourceRange Range; 258234353Sdim ObjCMethodDecl *DictWithObjectsMethod; 259234353Sdim 260234353Sdim ObjCDictionaryLiteral(ArrayRef<ObjCDictionaryElement> VK, 261234353Sdim bool HasPackExpansions, 262234353Sdim QualType T, ObjCMethodDecl *method, 263234353Sdim SourceRange SR); 264234353Sdim 265234353Sdim explicit ObjCDictionaryLiteral(EmptyShell Empty, unsigned NumElements, 266234353Sdim bool HasPackExpansions) 267234353Sdim : Expr(ObjCDictionaryLiteralClass, Empty), NumElements(NumElements), 268234353Sdim HasPackExpansions(HasPackExpansions) {} 269234353Sdim 270234353Sdim KeyValuePair *getKeyValues() { 271234353Sdim return reinterpret_cast<KeyValuePair *>(this + 1); 272234353Sdim } 273234353Sdim 274234353Sdim const KeyValuePair *getKeyValues() const { 275234353Sdim return reinterpret_cast<const KeyValuePair *>(this + 1); 276234353Sdim } 277234353Sdim 278234353Sdim ExpansionData *getExpansionData() { 279234353Sdim if (!HasPackExpansions) 280234353Sdim return 0; 281234353Sdim 282234353Sdim return reinterpret_cast<ExpansionData *>(getKeyValues() + NumElements); 283234353Sdim } 284234353Sdim 285234353Sdim const ExpansionData *getExpansionData() const { 286234353Sdim if (!HasPackExpansions) 287234353Sdim return 0; 288234353Sdim 289234353Sdim return reinterpret_cast<const ExpansionData *>(getKeyValues()+NumElements); 290234353Sdim } 291234353Sdim 292234353Sdimpublic: 293263508Sdim static ObjCDictionaryLiteral *Create(const ASTContext &C, 294234353Sdim ArrayRef<ObjCDictionaryElement> VK, 295234353Sdim bool HasPackExpansions, 296234353Sdim QualType T, ObjCMethodDecl *method, 297234353Sdim SourceRange SR); 298234353Sdim 299263508Sdim static ObjCDictionaryLiteral *CreateEmpty(const ASTContext &C, 300234353Sdim unsigned NumElements, 301234353Sdim bool HasPackExpansions); 302234353Sdim 303234353Sdim /// getNumElements - Return number of elements of objective-c dictionary 304234353Sdim /// literal. 305234353Sdim unsigned getNumElements() const { return NumElements; } 306234353Sdim 307234353Sdim ObjCDictionaryElement getKeyValueElement(unsigned Index) const { 308234353Sdim assert((Index < NumElements) && "Arg access out of range!"); 309234353Sdim const KeyValuePair &KV = getKeyValues()[Index]; 310249423Sdim ObjCDictionaryElement Result = { KV.Key, KV.Value, SourceLocation(), None }; 311234353Sdim if (HasPackExpansions) { 312234353Sdim const ExpansionData &Expansion = getExpansionData()[Index]; 313234353Sdim Result.EllipsisLoc = Expansion.EllipsisLoc; 314234353Sdim if (Expansion.NumExpansionsPlusOne > 0) 315234353Sdim Result.NumExpansions = Expansion.NumExpansionsPlusOne - 1; 316234353Sdim } 317234353Sdim return Result; 318234353Sdim } 319234353Sdim 320234353Sdim ObjCMethodDecl *getDictWithObjectsMethod() const 321234353Sdim { return DictWithObjectsMethod; } 322234353Sdim 323249423Sdim SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); } 324249423Sdim SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); } 325234353Sdim SourceRange getSourceRange() const LLVM_READONLY { return Range; } 326234353Sdim 327234353Sdim static bool classof(const Stmt *T) { 328234353Sdim return T->getStmtClass() == ObjCDictionaryLiteralClass; 329234353Sdim } 330234353Sdim 331234353Sdim // Iterators 332234353Sdim child_range children() { 333234353Sdim // Note: we're taking advantage of the layout of the KeyValuePair struct 334234353Sdim // here. If that struct changes, this code will need to change as well. 335234353Sdim return child_range(reinterpret_cast<Stmt **>(this + 1), 336234353Sdim reinterpret_cast<Stmt **>(this + 1) + NumElements * 2); 337234353Sdim } 338234353Sdim 339234353Sdim friend class ASTStmtReader; 340234353Sdim friend class ASTStmtWriter; 341234353Sdim}; 342234353Sdim 343234353Sdim 344239462Sdim/// ObjCEncodeExpr, used for \@encode in Objective-C. \@encode has the same 345239462Sdim/// type and behavior as StringLiteral except that the string initializer is 346239462Sdim/// obtained from ASTContext with the encoding type as an argument. 347193326Sedclass ObjCEncodeExpr : public Expr { 348207619Srdivacky TypeSourceInfo *EncodedType; 349193326Sed SourceLocation AtLoc, RParenLoc; 350193326Sedpublic: 351207619Srdivacky ObjCEncodeExpr(QualType T, TypeSourceInfo *EncodedType, 352193326Sed SourceLocation at, SourceLocation rp) 353218893Sdim : Expr(ObjCEncodeExprClass, T, VK_LValue, OK_Ordinary, 354218893Sdim EncodedType->getType()->isDependentType(), 355218893Sdim EncodedType->getType()->isDependentType(), 356224145Sdim EncodedType->getType()->isInstantiationDependentType(), 357218893Sdim EncodedType->getType()->containsUnexpandedParameterPack()), 358207619Srdivacky EncodedType(EncodedType), AtLoc(at), RParenLoc(rp) {} 359198092Srdivacky 360193326Sed explicit ObjCEncodeExpr(EmptyShell Empty) : Expr(ObjCEncodeExprClass, Empty){} 361193326Sed 362198092Srdivacky 363193326Sed SourceLocation getAtLoc() const { return AtLoc; } 364193326Sed void setAtLoc(SourceLocation L) { AtLoc = L; } 365193326Sed SourceLocation getRParenLoc() const { return RParenLoc; } 366193326Sed void setRParenLoc(SourceLocation L) { RParenLoc = L; } 367198092Srdivacky 368207619Srdivacky QualType getEncodedType() const { return EncodedType->getType(); } 369193326Sed 370207619Srdivacky TypeSourceInfo *getEncodedTypeSourceInfo() const { return EncodedType; } 371207619Srdivacky void setEncodedTypeSourceInfo(TypeSourceInfo *EncType) { 372207619Srdivacky EncodedType = EncType; 373207619Srdivacky } 374198092Srdivacky 375249423Sdim SourceLocation getLocStart() const LLVM_READONLY { return AtLoc; } 376249423Sdim SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; } 377198092Srdivacky 378193326Sed static bool classof(const Stmt *T) { 379193326Sed return T->getStmtClass() == ObjCEncodeExprClass; 380193326Sed } 381198092Srdivacky 382193326Sed // Iterators 383218893Sdim child_range children() { return child_range(); } 384193326Sed}; 385193326Sed 386239462Sdim/// ObjCSelectorExpr used for \@selector in Objective-C. 387193326Sedclass ObjCSelectorExpr : public Expr { 388193326Sed Selector SelName; 389193326Sed SourceLocation AtLoc, RParenLoc; 390193326Sedpublic: 391193326Sed ObjCSelectorExpr(QualType T, Selector selInfo, 392193326Sed SourceLocation at, SourceLocation rp) 393218893Sdim : Expr(ObjCSelectorExprClass, T, VK_RValue, OK_Ordinary, false, false, 394224145Sdim false, false), 395218893Sdim SelName(selInfo), AtLoc(at), RParenLoc(rp){} 396193326Sed explicit ObjCSelectorExpr(EmptyShell Empty) 397193326Sed : Expr(ObjCSelectorExprClass, Empty) {} 398193326Sed 399193326Sed Selector getSelector() const { return SelName; } 400193326Sed void setSelector(Selector S) { SelName = S; } 401198092Srdivacky 402193326Sed SourceLocation getAtLoc() const { return AtLoc; } 403193326Sed SourceLocation getRParenLoc() const { return RParenLoc; } 404193326Sed void setAtLoc(SourceLocation L) { AtLoc = L; } 405193326Sed void setRParenLoc(SourceLocation L) { RParenLoc = L; } 406193326Sed 407249423Sdim SourceLocation getLocStart() const LLVM_READONLY { return AtLoc; } 408249423Sdim SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; } 409198092Srdivacky 410193326Sed /// getNumArgs - Return the number of actual arguments to this call. 411193326Sed unsigned getNumArgs() const { return SelName.getNumArgs(); } 412198092Srdivacky 413193326Sed static bool classof(const Stmt *T) { 414193326Sed return T->getStmtClass() == ObjCSelectorExprClass; 415193326Sed } 416198092Srdivacky 417193326Sed // Iterators 418218893Sdim child_range children() { return child_range(); } 419193326Sed}; 420198092Srdivacky 421249423Sdim/// ObjCProtocolExpr used for protocol expression in Objective-C. 422249423Sdim/// 423249423Sdim/// This is used as: \@protocol(foo), as in: 424249423Sdim/// \code 425249423Sdim/// [obj conformsToProtocol:@protocol(foo)] 426249423Sdim/// \endcode 427249423Sdim/// 428193326Sed/// The return type is "Protocol*". 429198092Srdivackyclass ObjCProtocolExpr : public Expr { 430198092Srdivacky ObjCProtocolDecl *TheProtocol; 431239462Sdim SourceLocation AtLoc, ProtoLoc, RParenLoc; 432193326Sedpublic: 433193326Sed ObjCProtocolExpr(QualType T, ObjCProtocolDecl *protocol, 434239462Sdim SourceLocation at, SourceLocation protoLoc, SourceLocation rp) 435218893Sdim : Expr(ObjCProtocolExprClass, T, VK_RValue, OK_Ordinary, false, false, 436224145Sdim false, false), 437239462Sdim TheProtocol(protocol), AtLoc(at), ProtoLoc(protoLoc), RParenLoc(rp) {} 438193326Sed explicit ObjCProtocolExpr(EmptyShell Empty) 439193326Sed : Expr(ObjCProtocolExprClass, Empty) {} 440193326Sed 441194613Sed ObjCProtocolDecl *getProtocol() const { return TheProtocol; } 442194613Sed void setProtocol(ObjCProtocolDecl *P) { TheProtocol = P; } 443198092Srdivacky 444239462Sdim SourceLocation getProtocolIdLoc() const { return ProtoLoc; } 445193326Sed SourceLocation getAtLoc() const { return AtLoc; } 446193326Sed SourceLocation getRParenLoc() const { return RParenLoc; } 447193326Sed void setAtLoc(SourceLocation L) { AtLoc = L; } 448193326Sed void setRParenLoc(SourceLocation L) { RParenLoc = L; } 449193326Sed 450249423Sdim SourceLocation getLocStart() const LLVM_READONLY { return AtLoc; } 451249423Sdim SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; } 452198092Srdivacky 453193326Sed static bool classof(const Stmt *T) { 454193326Sed return T->getStmtClass() == ObjCProtocolExprClass; 455193326Sed } 456198092Srdivacky 457193326Sed // Iterators 458218893Sdim child_range children() { return child_range(); } 459239462Sdim 460239462Sdim friend class ASTStmtReader; 461239462Sdim friend class ASTStmtWriter; 462193326Sed}; 463193326Sed 464193326Sed/// ObjCIvarRefExpr - A reference to an ObjC instance variable. 465193326Sedclass ObjCIvarRefExpr : public Expr { 466234353Sdim ObjCIvarDecl *D; 467234353Sdim Stmt *Base; 468193326Sed SourceLocation Loc; 469249423Sdim /// OpLoc - This is the location of '.' or '->' 470249423Sdim SourceLocation OpLoc; 471249423Sdim 472193326Sed bool IsArrow:1; // True if this is "X->F", false if this is "X.F". 473193326Sed bool IsFreeIvar:1; // True if ivar reference has no base (self assumed). 474198092Srdivacky 475193326Sedpublic: 476218893Sdim ObjCIvarRefExpr(ObjCIvarDecl *d, QualType t, 477249423Sdim SourceLocation l, SourceLocation oploc, 478249423Sdim Expr *base, 479198092Srdivacky bool arrow = false, bool freeIvar = false) : 480251662Sdim Expr(ObjCIvarRefExprClass, t, VK_LValue, 481251662Sdim d->isBitField() ? OK_BitField : OK_Ordinary, 482218893Sdim /*TypeDependent=*/false, base->isValueDependent(), 483224145Sdim base->isInstantiationDependent(), 484218893Sdim base->containsUnexpandedParameterPack()), 485249423Sdim D(d), Base(base), Loc(l), OpLoc(oploc), 486249423Sdim IsArrow(arrow), IsFreeIvar(freeIvar) {} 487198092Srdivacky 488193326Sed explicit ObjCIvarRefExpr(EmptyShell Empty) 489193326Sed : Expr(ObjCIvarRefExprClass, Empty) {} 490193326Sed 491193326Sed ObjCIvarDecl *getDecl() { return D; } 492193326Sed const ObjCIvarDecl *getDecl() const { return D; } 493193326Sed void setDecl(ObjCIvarDecl *d) { D = d; } 494198092Srdivacky 495193326Sed const Expr *getBase() const { return cast<Expr>(Base); } 496193326Sed Expr *getBase() { return cast<Expr>(Base); } 497193326Sed void setBase(Expr * base) { Base = base; } 498198092Srdivacky 499193326Sed bool isArrow() const { return IsArrow; } 500193326Sed bool isFreeIvar() const { return IsFreeIvar; } 501193326Sed void setIsArrow(bool A) { IsArrow = A; } 502193326Sed void setIsFreeIvar(bool A) { IsFreeIvar = A; } 503198092Srdivacky 504193326Sed SourceLocation getLocation() const { return Loc; } 505193326Sed void setLocation(SourceLocation L) { Loc = L; } 506193326Sed 507249423Sdim SourceLocation getLocStart() const LLVM_READONLY { 508249423Sdim return isFreeIvar() ? Loc : getBase()->getLocStart(); 509193326Sed } 510249423Sdim SourceLocation getLocEnd() const LLVM_READONLY { return Loc; } 511249423Sdim 512249423Sdim SourceLocation getOpLoc() const { return OpLoc; } 513249423Sdim void setOpLoc(SourceLocation L) { OpLoc = L; } 514198092Srdivacky 515198092Srdivacky static bool classof(const Stmt *T) { 516198092Srdivacky return T->getStmtClass() == ObjCIvarRefExprClass; 517193326Sed } 518198092Srdivacky 519193326Sed // Iterators 520218893Sdim child_range children() { return child_range(&Base, &Base+1); } 521193326Sed}; 522193326Sed 523193326Sed/// ObjCPropertyRefExpr - A dot-syntax expression to access an ObjC 524193326Sed/// property. 525193326Sedclass ObjCPropertyRefExpr : public Expr { 526193326Sedprivate: 527218893Sdim /// If the bool is true, this is an implicit property reference; the 528218893Sdim /// pointer is an (optional) ObjCMethodDecl and Setter may be set. 529218893Sdim /// if the bool is false, this is an explicit property reference; 530218893Sdim /// the pointer is an ObjCPropertyDecl and Setter is always null. 531218893Sdim llvm::PointerIntPair<NamedDecl*, 1, bool> PropertyOrGetter; 532218893Sdim 533234353Sdim /// \brief Indicates whether the property reference will result in a message 534234353Sdim /// to the getter, the setter, or both. 535234353Sdim /// This applies to both implicit and explicit property references. 536234353Sdim enum MethodRefFlags { 537234353Sdim MethodRef_None = 0, 538234353Sdim MethodRef_Getter = 0x1, 539234353Sdim MethodRef_Setter = 0x2 540234353Sdim }; 541234353Sdim 542234353Sdim /// \brief Contains the Setter method pointer and MethodRefFlags bit flags. 543234353Sdim llvm::PointerIntPair<ObjCMethodDecl *, 2, unsigned> SetterAndMethodRefFlags; 544234353Sdim 545234353Sdim // FIXME: Maybe we should store the property identifier here, 546234353Sdim // because it's not rederivable from the other data when there's an 547234353Sdim // implicit property with no getter (because the 'foo' -> 'setFoo:' 548234353Sdim // transformation is lossy on the first character). 549234353Sdim 550193326Sed SourceLocation IdLoc; 551218893Sdim 552218893Sdim /// \brief When the receiver in property access is 'super', this is 553218893Sdim /// the location of the 'super' keyword. When it's an interface, 554218893Sdim /// this is that interface. 555218893Sdim SourceLocation ReceiverLoc; 556218893Sdim llvm::PointerUnion3<Stmt*, const Type*, ObjCInterfaceDecl*> Receiver; 557218893Sdim 558193326Sedpublic: 559198092Srdivacky ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t, 560218893Sdim ExprValueKind VK, ExprObjectKind OK, 561193326Sed SourceLocation l, Expr *base) 562218893Sdim : Expr(ObjCPropertyRefExprClass, t, VK, OK, 563218893Sdim /*TypeDependent=*/false, base->isValueDependent(), 564224145Sdim base->isInstantiationDependent(), 565218893Sdim base->containsUnexpandedParameterPack()), 566234353Sdim PropertyOrGetter(PD, false), SetterAndMethodRefFlags(), 567218893Sdim IdLoc(l), ReceiverLoc(), Receiver(base) { 568234353Sdim assert(t->isSpecificPlaceholderType(BuiltinType::PseudoObject)); 569193326Sed } 570218893Sdim 571218893Sdim ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t, 572218893Sdim ExprValueKind VK, ExprObjectKind OK, 573218893Sdim SourceLocation l, SourceLocation sl, QualType st) 574218893Sdim : Expr(ObjCPropertyRefExprClass, t, VK, OK, 575224145Sdim /*TypeDependent=*/false, false, st->isInstantiationDependentType(), 576218893Sdim st->containsUnexpandedParameterPack()), 577234353Sdim PropertyOrGetter(PD, false), SetterAndMethodRefFlags(), 578218893Sdim IdLoc(l), ReceiverLoc(sl), Receiver(st.getTypePtr()) { 579234353Sdim assert(t->isSpecificPlaceholderType(BuiltinType::PseudoObject)); 580218893Sdim } 581198092Srdivacky 582218893Sdim ObjCPropertyRefExpr(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter, 583218893Sdim QualType T, ExprValueKind VK, ExprObjectKind OK, 584218893Sdim SourceLocation IdLoc, Expr *Base) 585218893Sdim : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, 586224145Sdim Base->isValueDependent(), Base->isInstantiationDependent(), 587218893Sdim Base->containsUnexpandedParameterPack()), 588234353Sdim PropertyOrGetter(Getter, true), SetterAndMethodRefFlags(Setter, 0), 589218893Sdim IdLoc(IdLoc), ReceiverLoc(), Receiver(Base) { 590234353Sdim assert(T->isSpecificPlaceholderType(BuiltinType::PseudoObject)); 591218893Sdim } 592218893Sdim 593218893Sdim ObjCPropertyRefExpr(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter, 594218893Sdim QualType T, ExprValueKind VK, ExprObjectKind OK, 595218893Sdim SourceLocation IdLoc, 596218893Sdim SourceLocation SuperLoc, QualType SuperTy) 597224145Sdim : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, false, false, false), 598234353Sdim PropertyOrGetter(Getter, true), SetterAndMethodRefFlags(Setter, 0), 599218893Sdim IdLoc(IdLoc), ReceiverLoc(SuperLoc), Receiver(SuperTy.getTypePtr()) { 600234353Sdim assert(T->isSpecificPlaceholderType(BuiltinType::PseudoObject)); 601218893Sdim } 602218893Sdim 603218893Sdim ObjCPropertyRefExpr(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter, 604218893Sdim QualType T, ExprValueKind VK, ExprObjectKind OK, 605218893Sdim SourceLocation IdLoc, 606218893Sdim SourceLocation ReceiverLoc, ObjCInterfaceDecl *Receiver) 607224145Sdim : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, false, false, false), 608234353Sdim PropertyOrGetter(Getter, true), SetterAndMethodRefFlags(Setter, 0), 609218893Sdim IdLoc(IdLoc), ReceiverLoc(ReceiverLoc), Receiver(Receiver) { 610234353Sdim assert(T->isSpecificPlaceholderType(BuiltinType::PseudoObject)); 611218893Sdim } 612218893Sdim 613193326Sed explicit ObjCPropertyRefExpr(EmptyShell Empty) 614193326Sed : Expr(ObjCPropertyRefExprClass, Empty) {} 615193326Sed 616218893Sdim bool isImplicitProperty() const { return PropertyOrGetter.getInt(); } 617218893Sdim bool isExplicitProperty() const { return !PropertyOrGetter.getInt(); } 618198092Srdivacky 619218893Sdim ObjCPropertyDecl *getExplicitProperty() const { 620218893Sdim assert(!isImplicitProperty()); 621218893Sdim return cast<ObjCPropertyDecl>(PropertyOrGetter.getPointer()); 622218893Sdim } 623198092Srdivacky 624218893Sdim ObjCMethodDecl *getImplicitPropertyGetter() const { 625218893Sdim assert(isImplicitProperty()); 626218893Sdim return cast_or_null<ObjCMethodDecl>(PropertyOrGetter.getPointer()); 627218893Sdim } 628218893Sdim 629218893Sdim ObjCMethodDecl *getImplicitPropertySetter() const { 630218893Sdim assert(isImplicitProperty()); 631234353Sdim return SetterAndMethodRefFlags.getPointer(); 632218893Sdim } 633218893Sdim 634218893Sdim Selector getGetterSelector() const { 635218893Sdim if (isImplicitProperty()) 636218893Sdim return getImplicitPropertyGetter()->getSelector(); 637218893Sdim return getExplicitProperty()->getGetterName(); 638218893Sdim } 639218893Sdim 640218893Sdim Selector getSetterSelector() const { 641218893Sdim if (isImplicitProperty()) 642218893Sdim return getImplicitPropertySetter()->getSelector(); 643218893Sdim return getExplicitProperty()->getSetterName(); 644218893Sdim } 645218893Sdim 646234353Sdim /// \brief True if the property reference will result in a message to the 647234353Sdim /// getter. 648234353Sdim /// This applies to both implicit and explicit property references. 649234353Sdim bool isMessagingGetter() const { 650234353Sdim return SetterAndMethodRefFlags.getInt() & MethodRef_Getter; 651234353Sdim } 652234353Sdim 653234353Sdim /// \brief True if the property reference will result in a message to the 654234353Sdim /// setter. 655234353Sdim /// This applies to both implicit and explicit property references. 656234353Sdim bool isMessagingSetter() const { 657234353Sdim return SetterAndMethodRefFlags.getInt() & MethodRef_Setter; 658234353Sdim } 659234353Sdim 660234353Sdim void setIsMessagingGetter(bool val = true) { 661234353Sdim setMethodRefFlag(MethodRef_Getter, val); 662234353Sdim } 663234353Sdim 664234353Sdim void setIsMessagingSetter(bool val = true) { 665234353Sdim setMethodRefFlag(MethodRef_Setter, val); 666234353Sdim } 667234353Sdim 668218893Sdim const Expr *getBase() const { 669218893Sdim return cast<Expr>(Receiver.get<Stmt*>()); 670218893Sdim } 671218893Sdim Expr *getBase() { 672218893Sdim return cast<Expr>(Receiver.get<Stmt*>()); 673218893Sdim } 674218893Sdim 675193326Sed SourceLocation getLocation() const { return IdLoc; } 676218893Sdim 677218893Sdim SourceLocation getReceiverLocation() const { return ReceiverLoc; } 678218893Sdim QualType getSuperReceiverType() const { 679218893Sdim return QualType(Receiver.get<const Type*>(), 0); 680218893Sdim } 681221345Sdim QualType getGetterResultType() const { 682221345Sdim QualType ResultType; 683221345Sdim if (isExplicitProperty()) { 684221345Sdim const ObjCPropertyDecl *PDecl = getExplicitProperty(); 685221345Sdim if (const ObjCMethodDecl *Getter = PDecl->getGetterMethodDecl()) 686221345Sdim ResultType = Getter->getResultType(); 687221345Sdim else 688234353Sdim ResultType = PDecl->getType(); 689221345Sdim } else { 690221345Sdim const ObjCMethodDecl *Getter = getImplicitPropertyGetter(); 691234353Sdim if (Getter) 692234353Sdim ResultType = Getter->getResultType(); // with reference! 693221345Sdim } 694221345Sdim return ResultType; 695221345Sdim } 696234353Sdim 697221345Sdim QualType getSetterArgType() const { 698221345Sdim QualType ArgType; 699221345Sdim if (isImplicitProperty()) { 700221345Sdim const ObjCMethodDecl *Setter = getImplicitPropertySetter(); 701226633Sdim ObjCMethodDecl::param_const_iterator P = Setter->param_begin(); 702221345Sdim ArgType = (*P)->getType(); 703221345Sdim } else { 704221345Sdim if (ObjCPropertyDecl *PDecl = getExplicitProperty()) 705221345Sdim if (const ObjCMethodDecl *Setter = PDecl->getSetterMethodDecl()) { 706226633Sdim ObjCMethodDecl::param_const_iterator P = Setter->param_begin(); 707221345Sdim ArgType = (*P)->getType(); 708221345Sdim } 709221345Sdim if (ArgType.isNull()) 710221345Sdim ArgType = getType(); 711221345Sdim } 712221345Sdim return ArgType; 713221345Sdim } 714221345Sdim 715218893Sdim ObjCInterfaceDecl *getClassReceiver() const { 716218893Sdim return Receiver.get<ObjCInterfaceDecl*>(); 717218893Sdim } 718218893Sdim bool isObjectReceiver() const { return Receiver.is<Stmt*>(); } 719218893Sdim bool isSuperReceiver() const { return Receiver.is<const Type*>(); } 720218893Sdim bool isClassReceiver() const { return Receiver.is<ObjCInterfaceDecl*>(); } 721193326Sed 722249423Sdim SourceLocation getLocStart() const LLVM_READONLY { 723249423Sdim return isObjectReceiver() ? getBase()->getLocStart() :getReceiverLocation(); 724193326Sed } 725249423Sdim SourceLocation getLocEnd() const LLVM_READONLY { return IdLoc; } 726198092Srdivacky 727198092Srdivacky static bool classof(const Stmt *T) { 728198092Srdivacky return T->getStmtClass() == ObjCPropertyRefExprClass; 729193326Sed } 730198092Srdivacky 731193326Sed // Iterators 732218893Sdim child_range children() { 733218893Sdim if (Receiver.is<Stmt*>()) { 734218893Sdim Stmt **begin = reinterpret_cast<Stmt**>(&Receiver); // hack! 735218893Sdim return child_range(begin, begin+1); 736193326Sed } 737218893Sdim return child_range(); 738193326Sed } 739198092Srdivacky 740218893Sdimprivate: 741218893Sdim friend class ASTStmtReader; 742234353Sdim friend class ASTStmtWriter; 743234353Sdim void setExplicitProperty(ObjCPropertyDecl *D, unsigned methRefFlags) { 744218893Sdim PropertyOrGetter.setPointer(D); 745218893Sdim PropertyOrGetter.setInt(false); 746234353Sdim SetterAndMethodRefFlags.setPointer(0); 747234353Sdim SetterAndMethodRefFlags.setInt(methRefFlags); 748193326Sed } 749234353Sdim void setImplicitProperty(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter, 750234353Sdim unsigned methRefFlags) { 751218893Sdim PropertyOrGetter.setPointer(Getter); 752218893Sdim PropertyOrGetter.setInt(true); 753234353Sdim SetterAndMethodRefFlags.setPointer(Setter); 754234353Sdim SetterAndMethodRefFlags.setInt(methRefFlags); 755218893Sdim } 756218893Sdim void setBase(Expr *Base) { Receiver = Base; } 757218893Sdim void setSuperReceiver(QualType T) { Receiver = T.getTypePtr(); } 758218893Sdim void setClassReceiver(ObjCInterfaceDecl *D) { Receiver = D; } 759198092Srdivacky 760218893Sdim void setLocation(SourceLocation L) { IdLoc = L; } 761218893Sdim void setReceiverLocation(SourceLocation Loc) { ReceiverLoc = Loc; } 762234353Sdim 763234353Sdim void setMethodRefFlag(MethodRefFlags flag, bool val) { 764234353Sdim unsigned f = SetterAndMethodRefFlags.getInt(); 765234353Sdim if (val) 766234353Sdim f |= flag; 767234353Sdim else 768234353Sdim f &= ~flag; 769234353Sdim SetterAndMethodRefFlags.setInt(f); 770234353Sdim } 771193326Sed}; 772234353Sdim 773234353Sdim/// ObjCSubscriptRefExpr - used for array and dictionary subscripting. 774234353Sdim/// array[4] = array[3]; dictionary[key] = dictionary[alt_key]; 775234353Sdim/// 776234353Sdimclass ObjCSubscriptRefExpr : public Expr { 777234353Sdim // Location of ']' in an indexing expression. 778234353Sdim SourceLocation RBracket; 779234353Sdim // array/dictionary base expression. 780234353Sdim // for arrays, this is a numeric expression. For dictionaries, this is 781234353Sdim // an objective-c object pointer expression. 782234353Sdim enum { BASE, KEY, END_EXPR }; 783234353Sdim Stmt* SubExprs[END_EXPR]; 784234353Sdim 785234353Sdim ObjCMethodDecl *GetAtIndexMethodDecl; 786234353Sdim 787234353Sdim // For immutable objects this is null. When ObjCSubscriptRefExpr is to read 788234353Sdim // an indexed object this is null too. 789234353Sdim ObjCMethodDecl *SetAtIndexMethodDecl; 790234353Sdim 791234353Sdimpublic: 792234353Sdim 793234353Sdim ObjCSubscriptRefExpr(Expr *base, Expr *key, QualType T, 794234353Sdim ExprValueKind VK, ExprObjectKind OK, 795234353Sdim ObjCMethodDecl *getMethod, 796234353Sdim ObjCMethodDecl *setMethod, SourceLocation RB) 797234353Sdim : Expr(ObjCSubscriptRefExprClass, T, VK, OK, 798234353Sdim base->isTypeDependent() || key->isTypeDependent(), 799234353Sdim base->isValueDependent() || key->isValueDependent(), 800234353Sdim base->isInstantiationDependent() || key->isInstantiationDependent(), 801234353Sdim (base->containsUnexpandedParameterPack() || 802234353Sdim key->containsUnexpandedParameterPack())), 803234353Sdim RBracket(RB), 804234353Sdim GetAtIndexMethodDecl(getMethod), 805234353Sdim SetAtIndexMethodDecl(setMethod) 806234353Sdim {SubExprs[BASE] = base; SubExprs[KEY] = key;} 807198092Srdivacky 808234353Sdim explicit ObjCSubscriptRefExpr(EmptyShell Empty) 809234353Sdim : Expr(ObjCSubscriptRefExprClass, Empty) {} 810234353Sdim 811263508Sdim static ObjCSubscriptRefExpr *Create(const ASTContext &C, 812234353Sdim Expr *base, 813234353Sdim Expr *key, QualType T, 814234353Sdim ObjCMethodDecl *getMethod, 815234353Sdim ObjCMethodDecl *setMethod, 816234353Sdim SourceLocation RB); 817234353Sdim 818234353Sdim SourceLocation getRBracket() const { return RBracket; } 819234353Sdim void setRBracket(SourceLocation RB) { RBracket = RB; } 820249423Sdim 821249423Sdim SourceLocation getLocStart() const LLVM_READONLY { 822249423Sdim return SubExprs[BASE]->getLocStart(); 823234353Sdim } 824249423Sdim SourceLocation getLocEnd() const LLVM_READONLY { return RBracket; } 825249423Sdim 826234353Sdim static bool classof(const Stmt *T) { 827234353Sdim return T->getStmtClass() == ObjCSubscriptRefExprClass; 828234353Sdim } 829234353Sdim 830234353Sdim Expr *getBaseExpr() const { return cast<Expr>(SubExprs[BASE]); } 831234353Sdim void setBaseExpr(Stmt *S) { SubExprs[BASE] = S; } 832234353Sdim 833234353Sdim Expr *getKeyExpr() const { return cast<Expr>(SubExprs[KEY]); } 834234353Sdim void setKeyExpr(Stmt *S) { SubExprs[KEY] = S; } 835234353Sdim 836234353Sdim ObjCMethodDecl *getAtIndexMethodDecl() const { 837234353Sdim return GetAtIndexMethodDecl; 838234353Sdim } 839234353Sdim 840234353Sdim ObjCMethodDecl *setAtIndexMethodDecl() const { 841234353Sdim return SetAtIndexMethodDecl; 842234353Sdim } 843234353Sdim 844234353Sdim bool isArraySubscriptRefExpr() const { 845234353Sdim return getKeyExpr()->getType()->isIntegralOrEnumerationType(); 846234353Sdim } 847234353Sdim 848234353Sdim child_range children() { 849234353Sdim return child_range(SubExprs, SubExprs+END_EXPR); 850234353Sdim } 851234353Sdimprivate: 852234353Sdim friend class ASTStmtReader; 853234353Sdim}; 854234353Sdim 855234353Sdim 856207619Srdivacky/// \brief An expression that sends a message to the given Objective-C 857207619Srdivacky/// object or class. 858207619Srdivacky/// 859207619Srdivacky/// The following contains two message send expressions: 860207619Srdivacky/// 861207619Srdivacky/// \code 862207619Srdivacky/// [[NSString alloc] initWithString:@"Hello"] 863207619Srdivacky/// \endcode 864207619Srdivacky/// 865207619Srdivacky/// The innermost message send invokes the "alloc" class method on the 866207619Srdivacky/// NSString class, while the outermost message send invokes the 867207619Srdivacky/// "initWithString" instance method on the object returned from 868207619Srdivacky/// NSString's "alloc". In all, an Objective-C message send can take 869207619Srdivacky/// on four different (although related) forms: 870207619Srdivacky/// 871207619Srdivacky/// 1. Send to an object instance. 872207619Srdivacky/// 2. Send to a class. 873207619Srdivacky/// 3. Send to the superclass instance of the current class. 874207619Srdivacky/// 4. Send to the superclass of the current class. 875207619Srdivacky/// 876207619Srdivacky/// All four kinds of message sends are modeled by the ObjCMessageExpr 877207619Srdivacky/// class, and can be distinguished via \c getReceiverKind(). Example: 878207619Srdivacky/// 879193326Sedclass ObjCMessageExpr : public Expr { 880226633Sdim /// \brief Stores either the selector that this message is sending 881226633Sdim /// to (when \c HasMethod is zero) or an \c ObjCMethodDecl pointer 882226633Sdim /// referring to the method that we type-checked against. 883226633Sdim uintptr_t SelectorOrMethod; 884226633Sdim 885226633Sdim enum { NumArgsBitWidth = 16 }; 886226633Sdim 887207619Srdivacky /// \brief The number of arguments in the message send, not 888207619Srdivacky /// including the receiver. 889226633Sdim unsigned NumArgs : NumArgsBitWidth; 890226633Sdim 891226633Sdim void setNumArgs(unsigned Num) { 892226633Sdim assert((Num >> NumArgsBitWidth) == 0 && "Num of args is out of range!"); 893226633Sdim NumArgs = Num; 894226633Sdim } 895198092Srdivacky 896207619Srdivacky /// \brief The kind of message send this is, which is one of the 897207619Srdivacky /// ReceiverKind values. 898207619Srdivacky /// 899207619Srdivacky /// We pad this out to a byte to avoid excessive masking and shifting. 900207619Srdivacky unsigned Kind : 8; 901198092Srdivacky 902207619Srdivacky /// \brief Whether we have an actual method prototype in \c 903207619Srdivacky /// SelectorOrMethod. 904207619Srdivacky /// 905207619Srdivacky /// When non-zero, we have a method declaration; otherwise, we just 906207619Srdivacky /// have a selector. 907224145Sdim unsigned HasMethod : 1; 908204962Srdivacky 909224145Sdim /// \brief Whether this message send is a "delegate init call", 910224145Sdim /// i.e. a call of an init method on self from within an init method. 911224145Sdim unsigned IsDelegateInitCall : 1; 912234353Sdim 913234353Sdim /// \brief Whether this message send was implicitly generated by 914234353Sdim /// the implementation rather than explicitly written by the user. 915234353Sdim unsigned IsImplicit : 1; 916234353Sdim 917226633Sdim /// \brief Whether the locations of the selector identifiers are in a 918226633Sdim /// "standard" position, a enum SelectorLocationsKind. 919226633Sdim unsigned SelLocsKind : 2; 920224145Sdim 921207619Srdivacky /// \brief When the message expression is a send to 'super', this is 922207619Srdivacky /// the location of the 'super' keyword. 923207619Srdivacky SourceLocation SuperLoc; 924198092Srdivacky 925207619Srdivacky /// \brief The source locations of the open and close square 926207619Srdivacky /// brackets ('[' and ']', respectively). 927207619Srdivacky SourceLocation LBracLoc, RBracLoc; 928193326Sed 929207619Srdivacky ObjCMessageExpr(EmptyShell Empty, unsigned NumArgs) 930226633Sdim : Expr(ObjCMessageExprClass, Empty), SelectorOrMethod(0), Kind(0), 931234353Sdim HasMethod(0), IsDelegateInitCall(0), IsImplicit(0), SelLocsKind(0) { 932226633Sdim setNumArgs(NumArgs); 933226633Sdim } 934193326Sed 935218893Sdim ObjCMessageExpr(QualType T, ExprValueKind VK, 936207619Srdivacky SourceLocation LBracLoc, 937207619Srdivacky SourceLocation SuperLoc, 938207619Srdivacky bool IsInstanceSuper, 939207619Srdivacky QualType SuperType, 940207619Srdivacky Selector Sel, 941226633Sdim ArrayRef<SourceLocation> SelLocs, 942226633Sdim SelectorLocationsKind SelLocsK, 943207619Srdivacky ObjCMethodDecl *Method, 944226633Sdim ArrayRef<Expr *> Args, 945234353Sdim SourceLocation RBracLoc, 946234353Sdim bool isImplicit); 947218893Sdim ObjCMessageExpr(QualType T, ExprValueKind VK, 948207619Srdivacky SourceLocation LBracLoc, 949207619Srdivacky TypeSourceInfo *Receiver, 950207619Srdivacky Selector Sel, 951226633Sdim ArrayRef<SourceLocation> SelLocs, 952226633Sdim SelectorLocationsKind SelLocsK, 953207619Srdivacky ObjCMethodDecl *Method, 954226633Sdim ArrayRef<Expr *> Args, 955234353Sdim SourceLocation RBracLoc, 956234353Sdim bool isImplicit); 957218893Sdim ObjCMessageExpr(QualType T, ExprValueKind VK, 958207619Srdivacky SourceLocation LBracLoc, 959207619Srdivacky Expr *Receiver, 960207619Srdivacky Selector Sel, 961226633Sdim ArrayRef<SourceLocation> SelLocs, 962226633Sdim SelectorLocationsKind SelLocsK, 963207619Srdivacky ObjCMethodDecl *Method, 964226633Sdim ArrayRef<Expr *> Args, 965234353Sdim SourceLocation RBracLoc, 966234353Sdim bool isImplicit); 967198092Srdivacky 968226633Sdim void initArgsAndSelLocs(ArrayRef<Expr *> Args, 969226633Sdim ArrayRef<SourceLocation> SelLocs, 970226633Sdim SelectorLocationsKind SelLocsK); 971226633Sdim 972207619Srdivacky /// \brief Retrieve the pointer value of the message receiver. 973207619Srdivacky void *getReceiverPointer() const { 974207619Srdivacky return *const_cast<void **>( 975207619Srdivacky reinterpret_cast<const void * const*>(this + 1)); 976207619Srdivacky } 977207619Srdivacky 978207619Srdivacky /// \brief Set the pointer value of the message receiver. 979207619Srdivacky void setReceiverPointer(void *Value) { 980207619Srdivacky *reinterpret_cast<void **>(this + 1) = Value; 981207619Srdivacky } 982207619Srdivacky 983226633Sdim SelectorLocationsKind getSelLocsKind() const { 984226633Sdim return (SelectorLocationsKind)SelLocsKind; 985226633Sdim } 986226633Sdim bool hasStandardSelLocs() const { 987226633Sdim return getSelLocsKind() != SelLoc_NonStandard; 988226633Sdim } 989226633Sdim 990226633Sdim /// \brief Get a pointer to the stored selector identifiers locations array. 991226633Sdim /// No locations will be stored if HasStandardSelLocs is true. 992226633Sdim SourceLocation *getStoredSelLocs() { 993226633Sdim return reinterpret_cast<SourceLocation*>(getArgs() + getNumArgs()); 994226633Sdim } 995226633Sdim const SourceLocation *getStoredSelLocs() const { 996226633Sdim return reinterpret_cast<const SourceLocation*>(getArgs() + getNumArgs()); 997226633Sdim } 998226633Sdim 999226633Sdim /// \brief Get the number of stored selector identifiers locations. 1000226633Sdim /// No locations will be stored if HasStandardSelLocs is true. 1001226633Sdim unsigned getNumStoredSelLocs() const { 1002226633Sdim if (hasStandardSelLocs()) 1003226633Sdim return 0; 1004226633Sdim return getNumSelectorLocs(); 1005226633Sdim } 1006226633Sdim 1007263508Sdim static ObjCMessageExpr *alloc(const ASTContext &C, 1008226633Sdim ArrayRef<Expr *> Args, 1009226633Sdim SourceLocation RBraceLoc, 1010226633Sdim ArrayRef<SourceLocation> SelLocs, 1011226633Sdim Selector Sel, 1012226633Sdim SelectorLocationsKind &SelLocsK); 1013263508Sdim static ObjCMessageExpr *alloc(const ASTContext &C, 1014226633Sdim unsigned NumArgs, 1015226633Sdim unsigned NumStoredSelLocs); 1016226633Sdim 1017193326Sedpublic: 1018207619Srdivacky /// \brief The kind of receiver this message is sending to. 1019207619Srdivacky enum ReceiverKind { 1020207619Srdivacky /// \brief The receiver is a class. 1021207619Srdivacky Class = 0, 1022207619Srdivacky /// \brief The receiver is an object instance. 1023207619Srdivacky Instance, 1024207619Srdivacky /// \brief The receiver is a superclass. 1025207619Srdivacky SuperClass, 1026207619Srdivacky /// \brief The receiver is the instance of the superclass object. 1027207619Srdivacky SuperInstance 1028207619Srdivacky }; 1029193326Sed 1030207619Srdivacky /// \brief Create a message send to super. 1031207619Srdivacky /// 1032207619Srdivacky /// \param Context The ASTContext in which this expression will be created. 1033207619Srdivacky /// 1034207619Srdivacky /// \param T The result type of this message. 1035207619Srdivacky /// 1036218893Sdim /// \param VK The value kind of this message. A message returning 1037218893Sdim /// a l-value or r-value reference will be an l-value or x-value, 1038218893Sdim /// respectively. 1039218893Sdim /// 1040239462Sdim /// \param LBracLoc The location of the open square bracket '['. 1041207619Srdivacky /// 1042207619Srdivacky /// \param SuperLoc The location of the "super" keyword. 1043207619Srdivacky /// 1044207619Srdivacky /// \param IsInstanceSuper Whether this is an instance "super" 1045207619Srdivacky /// message (otherwise, it's a class "super" message). 1046207619Srdivacky /// 1047207619Srdivacky /// \param Sel The selector used to determine which method gets called. 1048207619Srdivacky /// 1049207619Srdivacky /// \param Method The Objective-C method against which this message 1050207619Srdivacky /// send was type-checked. May be NULL. 1051207619Srdivacky /// 1052207619Srdivacky /// \param Args The message send arguments. 1053207619Srdivacky /// 1054207619Srdivacky /// \param RBracLoc The location of the closing square bracket ']'. 1055263508Sdim static ObjCMessageExpr *Create(const ASTContext &Context, QualType T, 1056218893Sdim ExprValueKind VK, 1057207619Srdivacky SourceLocation LBracLoc, 1058207619Srdivacky SourceLocation SuperLoc, 1059207619Srdivacky bool IsInstanceSuper, 1060207619Srdivacky QualType SuperType, 1061207619Srdivacky Selector Sel, 1062226633Sdim ArrayRef<SourceLocation> SelLocs, 1063207619Srdivacky ObjCMethodDecl *Method, 1064226633Sdim ArrayRef<Expr *> Args, 1065234353Sdim SourceLocation RBracLoc, 1066234353Sdim bool isImplicit); 1067198092Srdivacky 1068207619Srdivacky /// \brief Create a class message send. 1069207619Srdivacky /// 1070207619Srdivacky /// \param Context The ASTContext in which this expression will be created. 1071207619Srdivacky /// 1072207619Srdivacky /// \param T The result type of this message. 1073207619Srdivacky /// 1074218893Sdim /// \param VK The value kind of this message. A message returning 1075218893Sdim /// a l-value or r-value reference will be an l-value or x-value, 1076218893Sdim /// respectively. 1077218893Sdim /// 1078239462Sdim /// \param LBracLoc The location of the open square bracket '['. 1079207619Srdivacky /// 1080207619Srdivacky /// \param Receiver The type of the receiver, including 1081207619Srdivacky /// source-location information. 1082207619Srdivacky /// 1083207619Srdivacky /// \param Sel The selector used to determine which method gets called. 1084207619Srdivacky /// 1085207619Srdivacky /// \param Method The Objective-C method against which this message 1086207619Srdivacky /// send was type-checked. May be NULL. 1087207619Srdivacky /// 1088207619Srdivacky /// \param Args The message send arguments. 1089207619Srdivacky /// 1090207619Srdivacky /// \param RBracLoc The location of the closing square bracket ']'. 1091263508Sdim static ObjCMessageExpr *Create(const ASTContext &Context, QualType T, 1092218893Sdim ExprValueKind VK, 1093207619Srdivacky SourceLocation LBracLoc, 1094207619Srdivacky TypeSourceInfo *Receiver, 1095207619Srdivacky Selector Sel, 1096226633Sdim ArrayRef<SourceLocation> SelLocs, 1097207619Srdivacky ObjCMethodDecl *Method, 1098226633Sdim ArrayRef<Expr *> Args, 1099234353Sdim SourceLocation RBracLoc, 1100234353Sdim bool isImplicit); 1101198092Srdivacky 1102207619Srdivacky /// \brief Create an instance message send. 1103207619Srdivacky /// 1104207619Srdivacky /// \param Context The ASTContext in which this expression will be created. 1105207619Srdivacky /// 1106207619Srdivacky /// \param T The result type of this message. 1107207619Srdivacky /// 1108218893Sdim /// \param VK The value kind of this message. A message returning 1109218893Sdim /// a l-value or r-value reference will be an l-value or x-value, 1110218893Sdim /// respectively. 1111218893Sdim /// 1112239462Sdim /// \param LBracLoc The location of the open square bracket '['. 1113207619Srdivacky /// 1114207619Srdivacky /// \param Receiver The expression used to produce the object that 1115207619Srdivacky /// will receive this message. 1116207619Srdivacky /// 1117207619Srdivacky /// \param Sel The selector used to determine which method gets called. 1118207619Srdivacky /// 1119207619Srdivacky /// \param Method The Objective-C method against which this message 1120207619Srdivacky /// send was type-checked. May be NULL. 1121207619Srdivacky /// 1122207619Srdivacky /// \param Args The message send arguments. 1123207619Srdivacky /// 1124207619Srdivacky /// \param RBracLoc The location of the closing square bracket ']'. 1125263508Sdim static ObjCMessageExpr *Create(const ASTContext &Context, QualType T, 1126218893Sdim ExprValueKind VK, 1127207619Srdivacky SourceLocation LBracLoc, 1128207619Srdivacky Expr *Receiver, 1129207619Srdivacky Selector Sel, 1130226633Sdim ArrayRef<SourceLocation> SeLocs, 1131207619Srdivacky ObjCMethodDecl *Method, 1132226633Sdim ArrayRef<Expr *> Args, 1133234353Sdim SourceLocation RBracLoc, 1134234353Sdim bool isImplicit); 1135198092Srdivacky 1136207619Srdivacky /// \brief Create an empty Objective-C message expression, to be 1137207619Srdivacky /// filled in by subsequent calls. 1138207619Srdivacky /// 1139207619Srdivacky /// \param Context The context in which the message send will be created. 1140207619Srdivacky /// 1141207619Srdivacky /// \param NumArgs The number of message arguments, not including 1142207619Srdivacky /// the receiver. 1143263508Sdim static ObjCMessageExpr *CreateEmpty(const ASTContext &Context, 1144226633Sdim unsigned NumArgs, 1145226633Sdim unsigned NumStoredSelLocs); 1146198092Srdivacky 1147234353Sdim /// \brief Indicates whether the message send was implicitly 1148234353Sdim /// generated by the implementation. If false, it was written explicitly 1149234353Sdim /// in the source code. 1150234353Sdim bool isImplicit() const { return IsImplicit; } 1151234353Sdim 1152207619Srdivacky /// \brief Determine the kind of receiver that this message is being 1153207619Srdivacky /// sent to. 1154207619Srdivacky ReceiverKind getReceiverKind() const { return (ReceiverKind)Kind; } 1155207619Srdivacky 1156218893Sdim /// \brief Source range of the receiver. 1157218893Sdim SourceRange getReceiverRange() const; 1158218893Sdim 1159207619Srdivacky /// \brief Determine whether this is an instance message to either a 1160207619Srdivacky /// computed object or to super. 1161207619Srdivacky bool isInstanceMessage() const { 1162207619Srdivacky return getReceiverKind() == Instance || getReceiverKind() == SuperInstance; 1163198092Srdivacky } 1164207619Srdivacky 1165207619Srdivacky /// \brief Determine whether this is an class message to either a 1166207619Srdivacky /// specified class or to super. 1167207619Srdivacky bool isClassMessage() const { 1168207619Srdivacky return getReceiverKind() == Class || getReceiverKind() == SuperClass; 1169193326Sed } 1170198092Srdivacky 1171243830Sdim /// \brief Returns the object expression (receiver) for an instance message, 1172243830Sdim /// or null for a message that is not an instance message. 1173207619Srdivacky Expr *getInstanceReceiver() { 1174207619Srdivacky if (getReceiverKind() == Instance) 1175207619Srdivacky return static_cast<Expr *>(getReceiverPointer()); 1176198092Srdivacky 1177207619Srdivacky return 0; 1178207619Srdivacky } 1179207619Srdivacky const Expr *getInstanceReceiver() const { 1180207619Srdivacky return const_cast<ObjCMessageExpr*>(this)->getInstanceReceiver(); 1181207619Srdivacky } 1182198092Srdivacky 1183207619Srdivacky /// \brief Turn this message send into an instance message that 1184207619Srdivacky /// computes the receiver object with the given expression. 1185207619Srdivacky void setInstanceReceiver(Expr *rec) { 1186207619Srdivacky Kind = Instance; 1187207619Srdivacky setReceiverPointer(rec); 1188207619Srdivacky } 1189207619Srdivacky 1190207619Srdivacky /// \brief Returns the type of a class message send, or NULL if the 1191207619Srdivacky /// message is not a class message. 1192207619Srdivacky QualType getClassReceiver() const { 1193207619Srdivacky if (TypeSourceInfo *TSInfo = getClassReceiverTypeInfo()) 1194207619Srdivacky return TSInfo->getType(); 1195204962Srdivacky 1196207619Srdivacky return QualType(); 1197207619Srdivacky } 1198204962Srdivacky 1199207619Srdivacky /// \brief Returns a type-source information of a class message 1200207619Srdivacky /// send, or NULL if the message is not a class message. 1201207619Srdivacky TypeSourceInfo *getClassReceiverTypeInfo() const { 1202207619Srdivacky if (getReceiverKind() == Class) 1203207619Srdivacky return reinterpret_cast<TypeSourceInfo *>(getReceiverPointer()); 1204207619Srdivacky return 0; 1205207619Srdivacky } 1206204962Srdivacky 1207207619Srdivacky void setClassReceiver(TypeSourceInfo *TSInfo) { 1208207619Srdivacky Kind = Class; 1209207619Srdivacky setReceiverPointer(TSInfo); 1210207619Srdivacky } 1211204962Srdivacky 1212207619Srdivacky /// \brief Retrieve the location of the 'super' keyword for a class 1213207619Srdivacky /// or instance message to 'super', otherwise an invalid source location. 1214207619Srdivacky SourceLocation getSuperLoc() const { 1215207619Srdivacky if (getReceiverKind() == SuperInstance || getReceiverKind() == SuperClass) 1216207619Srdivacky return SuperLoc; 1217198092Srdivacky 1218207619Srdivacky return SourceLocation(); 1219193326Sed } 1220198092Srdivacky 1221243830Sdim /// \brief Retrieve the receiver type to which this message is being directed. 1222243830Sdim /// 1223243830Sdim /// This routine cross-cuts all of the different kinds of message 1224243830Sdim /// sends to determine what the underlying (statically known) type 1225243830Sdim /// of the receiver will be; use \c getReceiverKind() to determine 1226243830Sdim /// whether the message is a class or an instance method, whether it 1227243830Sdim /// is a send to super or not, etc. 1228243830Sdim /// 1229243830Sdim /// \returns The type of the receiver. 1230243830Sdim QualType getReceiverType() const; 1231243830Sdim 1232207619Srdivacky /// \brief Retrieve the Objective-C interface to which this message 1233207619Srdivacky /// is being directed, if known. 1234207619Srdivacky /// 1235207619Srdivacky /// This routine cross-cuts all of the different kinds of message 1236207619Srdivacky /// sends to determine what the underlying (statically known) type 1237207619Srdivacky /// of the receiver will be; use \c getReceiverKind() to determine 1238207619Srdivacky /// whether the message is a class or an instance method, whether it 1239207619Srdivacky /// is a send to super or not, etc. 1240207619Srdivacky /// 1241207619Srdivacky /// \returns The Objective-C interface if known, otherwise NULL. 1242207619Srdivacky ObjCInterfaceDecl *getReceiverInterface() const; 1243207619Srdivacky 1244207619Srdivacky /// \brief Retrieve the type referred to by 'super'. 1245207619Srdivacky /// 1246207619Srdivacky /// The returned type will either be an ObjCInterfaceType (for an 1247207619Srdivacky /// class message to super) or an ObjCObjectPointerType that refers 1248207619Srdivacky /// to a class (for an instance message to super); 1249207619Srdivacky QualType getSuperType() const { 1250207619Srdivacky if (getReceiverKind() == SuperInstance || getReceiverKind() == SuperClass) 1251207619Srdivacky return QualType::getFromOpaquePtr(getReceiverPointer()); 1252207619Srdivacky 1253207619Srdivacky return QualType(); 1254207619Srdivacky } 1255207619Srdivacky 1256207619Srdivacky void setSuper(SourceLocation Loc, QualType T, bool IsInstanceSuper) { 1257207619Srdivacky Kind = IsInstanceSuper? SuperInstance : SuperClass; 1258207619Srdivacky SuperLoc = Loc; 1259207619Srdivacky setReceiverPointer(T.getAsOpaquePtr()); 1260207619Srdivacky } 1261207619Srdivacky 1262207619Srdivacky Selector getSelector() const; 1263207619Srdivacky 1264207619Srdivacky void setSelector(Selector S) { 1265207619Srdivacky HasMethod = false; 1266207619Srdivacky SelectorOrMethod = reinterpret_cast<uintptr_t>(S.getAsOpaquePtr()); 1267207619Srdivacky } 1268207619Srdivacky 1269207619Srdivacky const ObjCMethodDecl *getMethodDecl() const { 1270207619Srdivacky if (HasMethod) 1271207619Srdivacky return reinterpret_cast<const ObjCMethodDecl *>(SelectorOrMethod); 1272207619Srdivacky 1273207619Srdivacky return 0; 1274207619Srdivacky } 1275207619Srdivacky 1276207619Srdivacky ObjCMethodDecl *getMethodDecl() { 1277207619Srdivacky if (HasMethod) 1278207619Srdivacky return reinterpret_cast<ObjCMethodDecl *>(SelectorOrMethod); 1279207619Srdivacky 1280207619Srdivacky return 0; 1281207619Srdivacky } 1282207619Srdivacky 1283207619Srdivacky void setMethodDecl(ObjCMethodDecl *MD) { 1284207619Srdivacky HasMethod = true; 1285207619Srdivacky SelectorOrMethod = reinterpret_cast<uintptr_t>(MD); 1286207619Srdivacky } 1287207619Srdivacky 1288221345Sdim ObjCMethodFamily getMethodFamily() const { 1289221345Sdim if (HasMethod) return getMethodDecl()->getMethodFamily(); 1290221345Sdim return getSelector().getMethodFamily(); 1291221345Sdim } 1292221345Sdim 1293207619Srdivacky /// \brief Return the number of actual arguments in this message, 1294207619Srdivacky /// not counting the receiver. 1295193326Sed unsigned getNumArgs() const { return NumArgs; } 1296207619Srdivacky 1297207619Srdivacky /// \brief Retrieve the arguments to this message, not including the 1298207619Srdivacky /// receiver. 1299218893Sdim Expr **getArgs() { 1300218893Sdim return reinterpret_cast<Expr **>(this + 1) + 1; 1301193326Sed } 1302218893Sdim const Expr * const *getArgs() const { 1303218893Sdim return reinterpret_cast<const Expr * const *>(this + 1) + 1; 1304207619Srdivacky } 1305198092Srdivacky 1306193326Sed /// getArg - Return the specified argument. 1307193326Sed Expr *getArg(unsigned Arg) { 1308193326Sed assert(Arg < NumArgs && "Arg access out of range!"); 1309207619Srdivacky return cast<Expr>(getArgs()[Arg]); 1310193326Sed } 1311193326Sed const Expr *getArg(unsigned Arg) const { 1312193326Sed assert(Arg < NumArgs && "Arg access out of range!"); 1313207619Srdivacky return cast<Expr>(getArgs()[Arg]); 1314193326Sed } 1315193326Sed /// setArg - Set the specified argument. 1316193326Sed void setArg(unsigned Arg, Expr *ArgExpr) { 1317193326Sed assert(Arg < NumArgs && "Arg access out of range!"); 1318207619Srdivacky getArgs()[Arg] = ArgExpr; 1319193326Sed } 1320198092Srdivacky 1321224145Sdim /// isDelegateInitCall - Answers whether this message send has been 1322224145Sdim /// tagged as a "delegate init call", i.e. a call to a method in the 1323224145Sdim /// -init family on self from within an -init method implementation. 1324224145Sdim bool isDelegateInitCall() const { return IsDelegateInitCall; } 1325224145Sdim void setDelegateInitCall(bool isDelegate) { IsDelegateInitCall = isDelegate; } 1326224145Sdim 1327207619Srdivacky SourceLocation getLeftLoc() const { return LBracLoc; } 1328207619Srdivacky SourceLocation getRightLoc() const { return RBracLoc; } 1329193326Sed 1330234353Sdim SourceLocation getSelectorStartLoc() const { 1331234353Sdim if (isImplicit()) 1332234353Sdim return getLocStart(); 1333234353Sdim return getSelectorLoc(0); 1334234353Sdim } 1335226633Sdim SourceLocation getSelectorLoc(unsigned Index) const { 1336226633Sdim assert(Index < getNumSelectorLocs() && "Index out of range!"); 1337226633Sdim if (hasStandardSelLocs()) 1338226633Sdim return getStandardSelectorLoc(Index, getSelector(), 1339226633Sdim getSelLocsKind() == SelLoc_StandardWithSpace, 1340226633Sdim llvm::makeArrayRef(const_cast<Expr**>(getArgs()), 1341226633Sdim getNumArgs()), 1342226633Sdim RBracLoc); 1343226633Sdim return getStoredSelLocs()[Index]; 1344226633Sdim } 1345226633Sdim 1346226633Sdim void getSelectorLocs(SmallVectorImpl<SourceLocation> &SelLocs) const; 1347226633Sdim 1348226633Sdim unsigned getNumSelectorLocs() const { 1349234353Sdim if (isImplicit()) 1350234353Sdim return 0; 1351226633Sdim Selector Sel = getSelector(); 1352226633Sdim if (Sel.isUnarySelector()) 1353226633Sdim return 1; 1354226633Sdim return Sel.getNumArgs(); 1355226633Sdim } 1356226633Sdim 1357193326Sed void setSourceRange(SourceRange R) { 1358207619Srdivacky LBracLoc = R.getBegin(); 1359207619Srdivacky RBracLoc = R.getEnd(); 1360193326Sed } 1361249423Sdim SourceLocation getLocStart() const LLVM_READONLY { return LBracLoc; } 1362249423Sdim SourceLocation getLocEnd() const LLVM_READONLY { return RBracLoc; } 1363193326Sed 1364193326Sed static bool classof(const Stmt *T) { 1365193326Sed return T->getStmtClass() == ObjCMessageExprClass; 1366193326Sed } 1367198092Srdivacky 1368193326Sed // Iterators 1369218893Sdim child_range children(); 1370198092Srdivacky 1371193326Sed typedef ExprIterator arg_iterator; 1372193326Sed typedef ConstExprIterator const_arg_iterator; 1373198092Srdivacky 1374218893Sdim arg_iterator arg_begin() { return reinterpret_cast<Stmt **>(getArgs()); } 1375218893Sdim arg_iterator arg_end() { 1376218893Sdim return reinterpret_cast<Stmt **>(getArgs() + NumArgs); 1377193326Sed } 1378218893Sdim const_arg_iterator arg_begin() const { 1379218893Sdim return reinterpret_cast<Stmt const * const*>(getArgs()); 1380218893Sdim } 1381218893Sdim const_arg_iterator arg_end() const { 1382218893Sdim return reinterpret_cast<Stmt const * const*>(getArgs() + NumArgs); 1383218893Sdim } 1384193326Sed 1385218893Sdim friend class ASTStmtReader; 1386218893Sdim friend class ASTStmtWriter; 1387193326Sed}; 1388193326Sed 1389198092Srdivacky/// ObjCIsaExpr - Represent X->isa and X.isa when X is an ObjC 'id' type. 1390221345Sdim/// (similar in spirit to MemberExpr). 1391198092Srdivackyclass ObjCIsaExpr : public Expr { 1392198092Srdivacky /// Base - the expression for the base object pointer. 1393198092Srdivacky Stmt *Base; 1394198092Srdivacky 1395198092Srdivacky /// IsaMemberLoc - This is the location of the 'isa'. 1396198092Srdivacky SourceLocation IsaMemberLoc; 1397249423Sdim 1398249423Sdim /// OpLoc - This is the location of '.' or '->' 1399249423Sdim SourceLocation OpLoc; 1400198092Srdivacky 1401198092Srdivacky /// IsArrow - True if this is "X->F", false if this is "X.F". 1402198092Srdivacky bool IsArrow; 1403198092Srdivackypublic: 1404249423Sdim ObjCIsaExpr(Expr *base, bool isarrow, SourceLocation l, SourceLocation oploc, 1405249423Sdim QualType ty) 1406218893Sdim : Expr(ObjCIsaExprClass, ty, VK_LValue, OK_Ordinary, 1407218893Sdim /*TypeDependent=*/false, base->isValueDependent(), 1408224145Sdim base->isInstantiationDependent(), 1409218893Sdim /*ContainsUnexpandedParameterPack=*/false), 1410249423Sdim Base(base), IsaMemberLoc(l), OpLoc(oploc), IsArrow(isarrow) {} 1411198092Srdivacky 1412198092Srdivacky /// \brief Build an empty expression. 1413198092Srdivacky explicit ObjCIsaExpr(EmptyShell Empty) : Expr(ObjCIsaExprClass, Empty) { } 1414198092Srdivacky 1415198092Srdivacky void setBase(Expr *E) { Base = E; } 1416198092Srdivacky Expr *getBase() const { return cast<Expr>(Base); } 1417198092Srdivacky 1418198092Srdivacky bool isArrow() const { return IsArrow; } 1419198092Srdivacky void setArrow(bool A) { IsArrow = A; } 1420198092Srdivacky 1421198092Srdivacky /// getMemberLoc - Return the location of the "member", in X->F, it is the 1422198092Srdivacky /// location of 'F'. 1423198092Srdivacky SourceLocation getIsaMemberLoc() const { return IsaMemberLoc; } 1424198092Srdivacky void setIsaMemberLoc(SourceLocation L) { IsaMemberLoc = L; } 1425249423Sdim 1426249423Sdim SourceLocation getOpLoc() const { return OpLoc; } 1427249423Sdim void setOpLoc(SourceLocation L) { OpLoc = L; } 1428198092Srdivacky 1429249423Sdim SourceLocation getLocStart() const LLVM_READONLY { 1430249423Sdim return getBase()->getLocStart(); 1431198092Srdivacky } 1432249423Sdim 1433249423Sdim SourceLocation getBaseLocEnd() const LLVM_READONLY { 1434249423Sdim return getBase()->getLocEnd(); 1435249423Sdim } 1436249423Sdim 1437249423Sdim SourceLocation getLocEnd() const LLVM_READONLY { return IsaMemberLoc; } 1438198092Srdivacky 1439234353Sdim SourceLocation getExprLoc() const LLVM_READONLY { return IsaMemberLoc; } 1440198092Srdivacky 1441198092Srdivacky static bool classof(const Stmt *T) { 1442198092Srdivacky return T->getStmtClass() == ObjCIsaExprClass; 1443198092Srdivacky } 1444198092Srdivacky 1445198092Srdivacky // Iterators 1446218893Sdim child_range children() { return child_range(&Base, &Base+1); } 1447198092Srdivacky}; 1448198092Srdivacky 1449224145Sdim 1450224145Sdim/// ObjCIndirectCopyRestoreExpr - Represents the passing of a function 1451224145Sdim/// argument by indirect copy-restore in ARC. This is used to support 1452224145Sdim/// passing indirect arguments with the wrong lifetime, e.g. when 1453224145Sdim/// passing the address of a __strong local variable to an 'out' 1454224145Sdim/// parameter. This expression kind is only valid in an "argument" 1455224145Sdim/// position to some sort of call expression. 1456224145Sdim/// 1457224145Sdim/// The parameter must have type 'pointer to T', and the argument must 1458224145Sdim/// have type 'pointer to U', where T and U agree except possibly in 1459224145Sdim/// qualification. If the argument value is null, then a null pointer 1460224145Sdim/// is passed; otherwise it points to an object A, and: 1461224145Sdim/// 1. A temporary object B of type T is initialized, either by 1462224145Sdim/// zero-initialization (used when initializing an 'out' parameter) 1463224145Sdim/// or copy-initialization (used when initializing an 'inout' 1464224145Sdim/// parameter). 1465224145Sdim/// 2. The address of the temporary is passed to the function. 1466224145Sdim/// 3. If the call completes normally, A is move-assigned from B. 1467224145Sdim/// 4. Finally, A is destroyed immediately. 1468224145Sdim/// 1469224145Sdim/// Currently 'T' must be a retainable object lifetime and must be 1470224145Sdim/// __autoreleasing; this qualifier is ignored when initializing 1471224145Sdim/// the value. 1472224145Sdimclass ObjCIndirectCopyRestoreExpr : public Expr { 1473224145Sdim Stmt *Operand; 1474224145Sdim 1475224145Sdim // unsigned ObjCIndirectCopyRestoreBits.ShouldCopy : 1; 1476224145Sdim 1477224145Sdim friend class ASTReader; 1478224145Sdim friend class ASTStmtReader; 1479224145Sdim 1480224145Sdim void setShouldCopy(bool shouldCopy) { 1481224145Sdim ObjCIndirectCopyRestoreExprBits.ShouldCopy = shouldCopy; 1482224145Sdim } 1483224145Sdim 1484224145Sdim explicit ObjCIndirectCopyRestoreExpr(EmptyShell Empty) 1485224145Sdim : Expr(ObjCIndirectCopyRestoreExprClass, Empty) { } 1486224145Sdim 1487224145Sdimpublic: 1488224145Sdim ObjCIndirectCopyRestoreExpr(Expr *operand, QualType type, bool shouldCopy) 1489224145Sdim : Expr(ObjCIndirectCopyRestoreExprClass, type, VK_LValue, OK_Ordinary, 1490224145Sdim operand->isTypeDependent(), operand->isValueDependent(), 1491224145Sdim operand->isInstantiationDependent(), 1492224145Sdim operand->containsUnexpandedParameterPack()), 1493224145Sdim Operand(operand) { 1494224145Sdim setShouldCopy(shouldCopy); 1495224145Sdim } 1496224145Sdim 1497224145Sdim Expr *getSubExpr() { return cast<Expr>(Operand); } 1498224145Sdim const Expr *getSubExpr() const { return cast<Expr>(Operand); } 1499224145Sdim 1500224145Sdim /// shouldCopy - True if we should do the 'copy' part of the 1501224145Sdim /// copy-restore. If false, the temporary will be zero-initialized. 1502224145Sdim bool shouldCopy() const { return ObjCIndirectCopyRestoreExprBits.ShouldCopy; } 1503224145Sdim 1504224145Sdim child_range children() { return child_range(&Operand, &Operand+1); } 1505224145Sdim 1506224145Sdim // Source locations are determined by the subexpression. 1507249423Sdim SourceLocation getLocStart() const LLVM_READONLY { 1508249423Sdim return Operand->getLocStart(); 1509234353Sdim } 1510249423Sdim SourceLocation getLocEnd() const LLVM_READONLY { return Operand->getLocEnd();} 1511249423Sdim 1512234353Sdim SourceLocation getExprLoc() const LLVM_READONLY { 1513234353Sdim return getSubExpr()->getExprLoc(); 1514234353Sdim } 1515224145Sdim 1516224145Sdim static bool classof(const Stmt *s) { 1517224145Sdim return s->getStmtClass() == ObjCIndirectCopyRestoreExprClass; 1518224145Sdim } 1519224145Sdim}; 1520224145Sdim 1521224145Sdim/// \brief An Objective-C "bridged" cast expression, which casts between 1522224145Sdim/// Objective-C pointers and C pointers, transferring ownership in the process. 1523224145Sdim/// 1524224145Sdim/// \code 1525224145Sdim/// NSString *str = (__bridge_transfer NSString *)CFCreateString(); 1526224145Sdim/// \endcode 1527224145Sdimclass ObjCBridgedCastExpr : public ExplicitCastExpr { 1528224145Sdim SourceLocation LParenLoc; 1529224145Sdim SourceLocation BridgeKeywordLoc; 1530224145Sdim unsigned Kind : 2; 1531224145Sdim 1532224145Sdim friend class ASTStmtReader; 1533224145Sdim friend class ASTStmtWriter; 1534224145Sdim 1535224145Sdimpublic: 1536224145Sdim ObjCBridgedCastExpr(SourceLocation LParenLoc, ObjCBridgeCastKind Kind, 1537226633Sdim CastKind CK, SourceLocation BridgeKeywordLoc, 1538226633Sdim TypeSourceInfo *TSInfo, Expr *Operand) 1539224145Sdim : ExplicitCastExpr(ObjCBridgedCastExprClass, TSInfo->getType(), VK_RValue, 1540226633Sdim CK, Operand, 0, TSInfo), 1541224145Sdim LParenLoc(LParenLoc), BridgeKeywordLoc(BridgeKeywordLoc), Kind(Kind) { } 1542224145Sdim 1543224145Sdim /// \brief Construct an empty Objective-C bridged cast. 1544224145Sdim explicit ObjCBridgedCastExpr(EmptyShell Shell) 1545224145Sdim : ExplicitCastExpr(ObjCBridgedCastExprClass, Shell, 0) { } 1546224145Sdim 1547224145Sdim SourceLocation getLParenLoc() const { return LParenLoc; } 1548224145Sdim 1549224145Sdim /// \brief Determine which kind of bridge is being performed via this cast. 1550224145Sdim ObjCBridgeCastKind getBridgeKind() const { 1551224145Sdim return static_cast<ObjCBridgeCastKind>(Kind); 1552224145Sdim } 1553224145Sdim 1554224145Sdim /// \brief Retrieve the kind of bridge being performed as a string. 1555226633Sdim StringRef getBridgeKindName() const; 1556224145Sdim 1557224145Sdim /// \brief The location of the bridge keyword. 1558224145Sdim SourceLocation getBridgeKeywordLoc() const { return BridgeKeywordLoc; } 1559224145Sdim 1560249423Sdim SourceLocation getLocStart() const LLVM_READONLY { return LParenLoc; } 1561249423Sdim SourceLocation getLocEnd() const LLVM_READONLY { 1562249423Sdim return getSubExpr()->getLocEnd(); 1563224145Sdim } 1564224145Sdim 1565224145Sdim static bool classof(const Stmt *T) { 1566224145Sdim return T->getStmtClass() == ObjCBridgedCastExprClass; 1567224145Sdim } 1568224145Sdim}; 1569224145Sdim 1570193326Sed} // end namespace clang 1571193326Sed 1572193326Sed#endif 1573