ExprObjC.h revision 360784
1327952Sdim//===- ExprObjC.h - Classes for representing ObjC expressions ---*- C++ -*-===// 2193326Sed// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6193326Sed// 7193326Sed//===----------------------------------------------------------------------===// 8193326Sed// 9193326Sed// This file defines the ExprObjC interface and subclasses. 10193326Sed// 11193326Sed//===----------------------------------------------------------------------===// 12193326Sed 13193326Sed#ifndef LLVM_CLANG_AST_EXPROBJC_H 14193326Sed#define LLVM_CLANG_AST_EXPROBJC_H 15193326Sed 16327952Sdim#include "clang/AST/Decl.h" 17218893Sdim#include "clang/AST/DeclObjC.h" 18193326Sed#include "clang/AST/Expr.h" 19327952Sdim#include "clang/AST/OperationKinds.h" 20226633Sdim#include "clang/AST/SelectorLocationsKind.h" 21327952Sdim#include "clang/AST/Stmt.h" 22327952Sdim#include "clang/AST/Type.h" 23193326Sed#include "clang/Basic/IdentifierTable.h" 24327952Sdim#include "clang/Basic/LLVM.h" 25327952Sdim#include "clang/Basic/SourceLocation.h" 26327952Sdim#include "clang/Basic/Specifiers.h" 27327952Sdim#include "llvm/ADT/ArrayRef.h" 28327952Sdim#include "llvm/ADT/None.h" 29327952Sdim#include "llvm/ADT/Optional.h" 30327952Sdim#include "llvm/ADT/PointerIntPair.h" 31327952Sdim#include "llvm/ADT/PointerUnion.h" 32327952Sdim#include "llvm/ADT/StringRef.h" 33327952Sdim#include "llvm/ADT/iterator_range.h" 34327952Sdim#include "llvm/Support/Casting.h" 35234353Sdim#include "llvm/Support/Compiler.h" 36327952Sdim#include "llvm/Support/TrailingObjects.h" 37341825Sdim#include "llvm/Support/VersionTuple.h" 38327952Sdim#include "llvm/Support/type_traits.h" 39327952Sdim#include <cassert> 40327952Sdim#include <cstddef> 41327952Sdim#include <cstdint> 42193326Sed 43193326Sednamespace clang { 44198092Srdivacky 45327952Sdimclass ASTContext; 46327952Sdimclass CXXBaseSpecifier; 47327952Sdim 48193326Sed/// ObjCStringLiteral, used for Objective-C string literals 49193326Sed/// i.e. @"foo". 50193326Sedclass ObjCStringLiteral : public Expr { 51193326Sed Stmt *String; 52193326Sed SourceLocation AtLoc; 53327952Sdim 54193326Sedpublic: 55193326Sed ObjCStringLiteral(StringLiteral *SL, QualType T, SourceLocation L) 56327952Sdim : Expr(ObjCStringLiteralClass, T, VK_RValue, OK_Ordinary, false, false, 57327952Sdim false, false), 58327952Sdim String(SL), AtLoc(L) {} 59193326Sed explicit ObjCStringLiteral(EmptyShell Empty) 60327952Sdim : Expr(ObjCStringLiteralClass, Empty) {} 61193326Sed 62193326Sed StringLiteral *getString() { return cast<StringLiteral>(String); } 63193326Sed const StringLiteral *getString() const { return cast<StringLiteral>(String); } 64193326Sed void setString(StringLiteral *S) { String = S; } 65193326Sed 66193326Sed SourceLocation getAtLoc() const { return AtLoc; } 67193326Sed void setAtLoc(SourceLocation L) { AtLoc = L; } 68193326Sed 69341825Sdim SourceLocation getBeginLoc() const LLVM_READONLY { return AtLoc; } 70344779Sdim SourceLocation getEndLoc() const LLVM_READONLY { return String->getEndLoc(); } 71198092Srdivacky 72327952Sdim // Iterators 73327952Sdim child_range children() { return child_range(&String, &String+1); } 74327952Sdim 75353358Sdim const_child_range children() const { 76353358Sdim return const_child_range(&String, &String + 1); 77353358Sdim } 78353358Sdim 79198092Srdivacky static bool classof(const Stmt *T) { 80198092Srdivacky return T->getStmtClass() == ObjCStringLiteralClass; 81193326Sed } 82193326Sed}; 83198092Srdivacky 84234353Sdim/// ObjCBoolLiteralExpr - Objective-C Boolean Literal. 85234353Sdimclass ObjCBoolLiteralExpr : public Expr { 86234353Sdim bool Value; 87234353Sdim SourceLocation Loc; 88327952Sdim 89234353Sdimpublic: 90327952Sdim ObjCBoolLiteralExpr(bool val, QualType Ty, SourceLocation l) 91327952Sdim : Expr(ObjCBoolLiteralExprClass, Ty, VK_RValue, OK_Ordinary, false, false, 92327952Sdim false, false), 93327952Sdim Value(val), Loc(l) {} 94234353Sdim explicit ObjCBoolLiteralExpr(EmptyShell Empty) 95327952Sdim : Expr(ObjCBoolLiteralExprClass, Empty) {} 96341825Sdim 97234353Sdim bool getValue() const { return Value; } 98234353Sdim void setValue(bool V) { Value = V; } 99249423Sdim 100341825Sdim SourceLocation getBeginLoc() const LLVM_READONLY { return Loc; } 101341825Sdim SourceLocation getEndLoc() const LLVM_READONLY { return Loc; } 102341825Sdim 103234353Sdim SourceLocation getLocation() const { return Loc; } 104234353Sdim void setLocation(SourceLocation L) { Loc = L; } 105341825Sdim 106234353Sdim // Iterators 107296417Sdim child_range children() { 108296417Sdim return child_range(child_iterator(), child_iterator()); 109296417Sdim } 110327952Sdim 111353358Sdim const_child_range children() const { 112353358Sdim return const_child_range(const_child_iterator(), const_child_iterator()); 113353358Sdim } 114353358Sdim 115327952Sdim static bool classof(const Stmt *T) { 116327952Sdim return T->getStmtClass() == ObjCBoolLiteralExprClass; 117327952Sdim } 118234353Sdim}; 119234353Sdim 120239462Sdim/// ObjCBoxedExpr - used for generalized expression boxing. 121288943Sdim/// as in: @(strdup("hello world")), @(random()) or @(view.frame) 122239462Sdim/// Also used for boxing non-parenthesized numeric literals; 123314564Sdim/// as in: @42 or \@true (c++/objc++) or \@__objc_yes (c/objc). 124239462Sdimclass ObjCBoxedExpr : public Expr { 125239462Sdim Stmt *SubExpr; 126239462Sdim ObjCMethodDecl *BoxingMethod; 127239462Sdim SourceRange Range; 128327952Sdim 129234353Sdimpublic: 130327952Sdim friend class ASTStmtReader; 131327952Sdim 132239462Sdim ObjCBoxedExpr(Expr *E, QualType T, ObjCMethodDecl *method, 133239462Sdim SourceRange R) 134341825Sdim : Expr(ObjCBoxedExprClass, T, VK_RValue, OK_Ordinary, 135341825Sdim E->isTypeDependent(), E->isValueDependent(), 136327952Sdim E->isInstantiationDependent(), 137341825Sdim E->containsUnexpandedParameterPack()), 138327952Sdim SubExpr(E), BoxingMethod(method), Range(R) {} 139239462Sdim explicit ObjCBoxedExpr(EmptyShell Empty) 140327952Sdim : Expr(ObjCBoxedExprClass, Empty) {} 141341825Sdim 142239462Sdim Expr *getSubExpr() { return cast<Expr>(SubExpr); } 143239462Sdim const Expr *getSubExpr() const { return cast<Expr>(SubExpr); } 144341825Sdim 145239462Sdim ObjCMethodDecl *getBoxingMethod() const { 146341825Sdim return BoxingMethod; 147234353Sdim } 148341825Sdim 149353358Sdim // Indicates whether this boxed expression can be emitted as a compile-time 150353358Sdim // constant. 151353358Sdim bool isExpressibleAsConstantInitializer() const { 152353358Sdim return !BoxingMethod && SubExpr; 153353358Sdim } 154353358Sdim 155239462Sdim SourceLocation getAtLoc() const { return Range.getBegin(); } 156327952Sdim 157341825Sdim SourceLocation getBeginLoc() const LLVM_READONLY { return Range.getBegin(); } 158341825Sdim SourceLocation getEndLoc() const LLVM_READONLY { return Range.getEnd(); } 159341825Sdim 160234353Sdim SourceRange getSourceRange() const LLVM_READONLY { 161239462Sdim return Range; 162234353Sdim } 163341825Sdim 164234353Sdim // Iterators 165239462Sdim child_range children() { return child_range(&SubExpr, &SubExpr+1); } 166280031Sdim 167353358Sdim const_child_range children() const { 168353358Sdim return const_child_range(&SubExpr, &SubExpr + 1); 169353358Sdim } 170353358Sdim 171327952Sdim using const_arg_iterator = ConstExprIterator; 172280031Sdim 173280031Sdim const_arg_iterator arg_begin() const { 174280031Sdim return reinterpret_cast<Stmt const * const*>(&SubExpr); 175280031Sdim } 176327952Sdim 177280031Sdim const_arg_iterator arg_end() const { 178280031Sdim return reinterpret_cast<Stmt const * const*>(&SubExpr + 1); 179280031Sdim } 180327952Sdim 181327952Sdim static bool classof(const Stmt *T) { 182327952Sdim return T->getStmtClass() == ObjCBoxedExprClass; 183327952Sdim } 184234353Sdim}; 185234353Sdim 186234353Sdim/// ObjCArrayLiteral - used for objective-c array containers; as in: 187234353Sdim/// @[@"Hello", NSApp, [NSNumber numberWithInt:42]]; 188296417Sdimclass ObjCArrayLiteral final 189296417Sdim : public Expr, 190296417Sdim private llvm::TrailingObjects<ObjCArrayLiteral, Expr *> { 191234353Sdim unsigned NumElements; 192234353Sdim SourceRange Range; 193234353Sdim ObjCMethodDecl *ArrayWithObjectsMethod; 194296417Sdim 195249423Sdim ObjCArrayLiteral(ArrayRef<Expr *> Elements, 196234353Sdim QualType T, ObjCMethodDecl * Method, 197234353Sdim SourceRange SR); 198296417Sdim 199234353Sdim explicit ObjCArrayLiteral(EmptyShell Empty, unsigned NumElements) 200327952Sdim : Expr(ObjCArrayLiteralClass, Empty), NumElements(NumElements) {} 201234353Sdim 202234353Sdimpublic: 203327952Sdim friend class ASTStmtReader; 204327952Sdim friend TrailingObjects; 205327952Sdim 206261991Sdim static ObjCArrayLiteral *Create(const ASTContext &C, 207249423Sdim ArrayRef<Expr *> Elements, 208234353Sdim QualType T, ObjCMethodDecl * Method, 209234353Sdim SourceRange SR); 210234353Sdim 211261991Sdim static ObjCArrayLiteral *CreateEmpty(const ASTContext &C, 212261991Sdim unsigned NumElements); 213234353Sdim 214341825Sdim SourceLocation getBeginLoc() const LLVM_READONLY { return Range.getBegin(); } 215341825Sdim SourceLocation getEndLoc() const LLVM_READONLY { return Range.getEnd(); } 216234353Sdim SourceRange getSourceRange() const LLVM_READONLY { return Range; } 217234353Sdim 218341825Sdim /// Retrieve elements of array of literals. 219296417Sdim Expr **getElements() { return getTrailingObjects<Expr *>(); } 220234353Sdim 221341825Sdim /// Retrieve elements of array of literals. 222296417Sdim const Expr * const *getElements() const { 223296417Sdim return getTrailingObjects<Expr *>(); 224234353Sdim } 225234353Sdim 226234353Sdim /// getNumElements - Return number of elements of objective-c array literal. 227234353Sdim unsigned getNumElements() const { return NumElements; } 228341825Sdim 229327952Sdim /// getElement - Return the Element at the specified index. 230234353Sdim Expr *getElement(unsigned Index) { 231234353Sdim assert((Index < NumElements) && "Arg access out of range!"); 232341825Sdim return getElements()[Index]; 233234353Sdim } 234234353Sdim const Expr *getElement(unsigned Index) const { 235234353Sdim assert((Index < NumElements) && "Arg access out of range!"); 236341825Sdim return getElements()[Index]; 237234353Sdim } 238341825Sdim 239234353Sdim ObjCMethodDecl *getArrayWithObjectsMethod() const { 240341825Sdim return ArrayWithObjectsMethod; 241234353Sdim } 242341825Sdim 243234353Sdim // Iterators 244296417Sdim child_range children() { 245296417Sdim return child_range(reinterpret_cast<Stmt **>(getElements()), 246296417Sdim reinterpret_cast<Stmt **>(getElements()) + NumElements); 247234353Sdim } 248296417Sdim 249353358Sdim const_child_range children() const { 250353358Sdim auto Children = const_cast<ObjCArrayLiteral *>(this)->children(); 251353358Sdim return const_child_range(Children.begin(), Children.end()); 252353358Sdim } 253353358Sdim 254327952Sdim static bool classof(const Stmt *T) { 255327952Sdim return T->getStmtClass() == ObjCArrayLiteralClass; 256327952Sdim } 257234353Sdim}; 258234353Sdim 259341825Sdim/// An element in an Objective-C dictionary literal. 260234353Sdim/// 261234353Sdimstruct ObjCDictionaryElement { 262341825Sdim /// The key for the dictionary element. 263234353Sdim Expr *Key; 264341825Sdim 265341825Sdim /// The value of the dictionary element. 266234353Sdim Expr *Value; 267341825Sdim 268341825Sdim /// The location of the ellipsis, if this is a pack expansion. 269234353Sdim SourceLocation EllipsisLoc; 270341825Sdim 271341825Sdim /// The number of elements this pack expansion will expand to, if 272234353Sdim /// this is a pack expansion and is known. 273249423Sdim Optional<unsigned> NumExpansions; 274234353Sdim 275341825Sdim /// Determines whether this dictionary element is a pack expansion. 276234353Sdim bool isPackExpansion() const { return EllipsisLoc.isValid(); } 277234353Sdim}; 278234353Sdim 279327952Sdim} // namespace clang 280327952Sdim 281249423Sdimnamespace clang { 282327952Sdim 283341825Sdim/// Internal struct for storing Key/value pair. 284296417Sdimstruct ObjCDictionaryLiteral_KeyValuePair { 285296417Sdim Expr *Key; 286296417Sdim Expr *Value; 287296417Sdim}; 288234353Sdim 289341825Sdim/// Internal struct to describes an element that is a pack 290296417Sdim/// expansion, used if any of the elements in the dictionary literal 291296417Sdim/// are pack expansions. 292296417Sdimstruct ObjCDictionaryLiteral_ExpansionData { 293341825Sdim /// The location of the ellipsis, if this element is a pack 294296417Sdim /// expansion. 295296417Sdim SourceLocation EllipsisLoc; 296234353Sdim 297341825Sdim /// If non-zero, the number of elements that this pack 298296417Sdim /// expansion will expand to (+1). 299296417Sdim unsigned NumExpansionsPlusOne; 300296417Sdim}; 301296417Sdim 302296417Sdim/// ObjCDictionaryLiteral - AST node to represent objective-c dictionary 303296417Sdim/// literals; as in: @{@"name" : NSUserName(), @"date" : [NSDate date] }; 304296417Sdimclass ObjCDictionaryLiteral final 305296417Sdim : public Expr, 306296417Sdim private llvm::TrailingObjects<ObjCDictionaryLiteral, 307296417Sdim ObjCDictionaryLiteral_KeyValuePair, 308296417Sdim ObjCDictionaryLiteral_ExpansionData> { 309341825Sdim /// The number of elements in this dictionary literal. 310234353Sdim unsigned NumElements : 31; 311296417Sdim 312341825Sdim /// Determine whether this dictionary literal has any pack expansions. 313234353Sdim /// 314234353Sdim /// If the dictionary literal has pack expansions, then there will 315234353Sdim /// be an array of pack expansion data following the array of 316234353Sdim /// key/value pairs, which provide the locations of the ellipses (if 317234353Sdim /// any) and number of elements in the expansion (if known). If 318234353Sdim /// there are no pack expansions, we optimize away this storage. 319234353Sdim unsigned HasPackExpansions : 1; 320296417Sdim 321234353Sdim SourceRange Range; 322234353Sdim ObjCMethodDecl *DictWithObjectsMethod; 323296417Sdim 324327952Sdim using KeyValuePair = ObjCDictionaryLiteral_KeyValuePair; 325327952Sdim using ExpansionData = ObjCDictionaryLiteral_ExpansionData; 326296417Sdim 327341825Sdim ObjCDictionaryLiteral(ArrayRef<ObjCDictionaryElement> VK, 328234353Sdim bool HasPackExpansions, 329234353Sdim QualType T, ObjCMethodDecl *method, 330234353Sdim SourceRange SR); 331234353Sdim 332234353Sdim explicit ObjCDictionaryLiteral(EmptyShell Empty, unsigned NumElements, 333234353Sdim bool HasPackExpansions) 334327952Sdim : Expr(ObjCDictionaryLiteralClass, Empty), NumElements(NumElements), 335327952Sdim HasPackExpansions(HasPackExpansions) {} 336234353Sdim 337327952Sdim size_t numTrailingObjects(OverloadToken<KeyValuePair>) const { 338327952Sdim return NumElements; 339327952Sdim } 340327952Sdim 341234353Sdimpublic: 342327952Sdim friend class ASTStmtReader; 343327952Sdim friend class ASTStmtWriter; 344327952Sdim friend TrailingObjects; 345327952Sdim 346261991Sdim static ObjCDictionaryLiteral *Create(const ASTContext &C, 347341825Sdim ArrayRef<ObjCDictionaryElement> VK, 348234353Sdim bool HasPackExpansions, 349234353Sdim QualType T, ObjCMethodDecl *method, 350234353Sdim SourceRange SR); 351341825Sdim 352261991Sdim static ObjCDictionaryLiteral *CreateEmpty(const ASTContext &C, 353234353Sdim unsigned NumElements, 354234353Sdim bool HasPackExpansions); 355341825Sdim 356341825Sdim /// getNumElements - Return number of elements of objective-c dictionary 357234353Sdim /// literal. 358234353Sdim unsigned getNumElements() const { return NumElements; } 359234353Sdim 360234353Sdim ObjCDictionaryElement getKeyValueElement(unsigned Index) const { 361234353Sdim assert((Index < NumElements) && "Arg access out of range!"); 362296417Sdim const KeyValuePair &KV = getTrailingObjects<KeyValuePair>()[Index]; 363249423Sdim ObjCDictionaryElement Result = { KV.Key, KV.Value, SourceLocation(), None }; 364234353Sdim if (HasPackExpansions) { 365296417Sdim const ExpansionData &Expansion = 366296417Sdim getTrailingObjects<ExpansionData>()[Index]; 367234353Sdim Result.EllipsisLoc = Expansion.EllipsisLoc; 368234353Sdim if (Expansion.NumExpansionsPlusOne > 0) 369234353Sdim Result.NumExpansions = Expansion.NumExpansionsPlusOne - 1; 370234353Sdim } 371234353Sdim return Result; 372234353Sdim } 373341825Sdim 374327952Sdim ObjCMethodDecl *getDictWithObjectsMethod() const { 375327952Sdim return DictWithObjectsMethod; 376327952Sdim } 377234353Sdim 378341825Sdim SourceLocation getBeginLoc() const LLVM_READONLY { return Range.getBegin(); } 379341825Sdim SourceLocation getEndLoc() const LLVM_READONLY { return Range.getEnd(); } 380234353Sdim SourceRange getSourceRange() const LLVM_READONLY { return Range; } 381327952Sdim 382234353Sdim // Iterators 383296417Sdim child_range children() { 384234353Sdim // Note: we're taking advantage of the layout of the KeyValuePair struct 385234353Sdim // here. If that struct changes, this code will need to change as well. 386296417Sdim static_assert(sizeof(KeyValuePair) == sizeof(Stmt *) * 2, 387296417Sdim "KeyValuePair is expected size"); 388296417Sdim return child_range( 389296417Sdim reinterpret_cast<Stmt **>(getTrailingObjects<KeyValuePair>()), 390296417Sdim reinterpret_cast<Stmt **>(getTrailingObjects<KeyValuePair>()) + 391296417Sdim NumElements * 2); 392234353Sdim } 393327952Sdim 394353358Sdim const_child_range children() const { 395353358Sdim auto Children = const_cast<ObjCDictionaryLiteral *>(this)->children(); 396353358Sdim return const_child_range(Children.begin(), Children.end()); 397353358Sdim } 398353358Sdim 399327952Sdim static bool classof(const Stmt *T) { 400327952Sdim return T->getStmtClass() == ObjCDictionaryLiteralClass; 401327952Sdim } 402234353Sdim}; 403234353Sdim 404239462Sdim/// ObjCEncodeExpr, used for \@encode in Objective-C. \@encode has the same 405239462Sdim/// type and behavior as StringLiteral except that the string initializer is 406239462Sdim/// obtained from ASTContext with the encoding type as an argument. 407193326Sedclass ObjCEncodeExpr : public Expr { 408207619Srdivacky TypeSourceInfo *EncodedType; 409193326Sed SourceLocation AtLoc, RParenLoc; 410327952Sdim 411193326Sedpublic: 412207619Srdivacky ObjCEncodeExpr(QualType T, TypeSourceInfo *EncodedType, 413193326Sed SourceLocation at, SourceLocation rp) 414327952Sdim : Expr(ObjCEncodeExprClass, T, VK_LValue, OK_Ordinary, 415327952Sdim EncodedType->getType()->isDependentType(), 416327952Sdim EncodedType->getType()->isDependentType(), 417327952Sdim EncodedType->getType()->isInstantiationDependentType(), 418341825Sdim EncodedType->getType()->containsUnexpandedParameterPack()), 419327952Sdim EncodedType(EncodedType), AtLoc(at), RParenLoc(rp) {} 420198092Srdivacky 421193326Sed explicit ObjCEncodeExpr(EmptyShell Empty) : Expr(ObjCEncodeExprClass, Empty){} 422193326Sed 423193326Sed SourceLocation getAtLoc() const { return AtLoc; } 424193326Sed void setAtLoc(SourceLocation L) { AtLoc = L; } 425193326Sed SourceLocation getRParenLoc() const { return RParenLoc; } 426193326Sed void setRParenLoc(SourceLocation L) { RParenLoc = L; } 427198092Srdivacky 428207619Srdivacky QualType getEncodedType() const { return EncodedType->getType(); } 429193326Sed 430207619Srdivacky TypeSourceInfo *getEncodedTypeSourceInfo() const { return EncodedType; } 431327952Sdim 432341825Sdim void setEncodedTypeSourceInfo(TypeSourceInfo *EncType) { 433341825Sdim EncodedType = EncType; 434207619Srdivacky } 435198092Srdivacky 436341825Sdim SourceLocation getBeginLoc() const LLVM_READONLY { return AtLoc; } 437341825Sdim SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; } 438198092Srdivacky 439193326Sed // Iterators 440296417Sdim child_range children() { 441296417Sdim return child_range(child_iterator(), child_iterator()); 442296417Sdim } 443327952Sdim 444353358Sdim const_child_range children() const { 445353358Sdim return const_child_range(const_child_iterator(), const_child_iterator()); 446353358Sdim } 447353358Sdim 448327952Sdim static bool classof(const Stmt *T) { 449327952Sdim return T->getStmtClass() == ObjCEncodeExprClass; 450327952Sdim } 451193326Sed}; 452193326Sed 453239462Sdim/// ObjCSelectorExpr used for \@selector in Objective-C. 454193326Sedclass ObjCSelectorExpr : public Expr { 455193326Sed Selector SelName; 456193326Sed SourceLocation AtLoc, RParenLoc; 457327952Sdim 458193326Sedpublic: 459193326Sed ObjCSelectorExpr(QualType T, Selector selInfo, 460193326Sed SourceLocation at, SourceLocation rp) 461327952Sdim : Expr(ObjCSelectorExprClass, T, VK_RValue, OK_Ordinary, false, false, 462327952Sdim false, false), 463327952Sdim SelName(selInfo), AtLoc(at), RParenLoc(rp) {} 464193326Sed explicit ObjCSelectorExpr(EmptyShell Empty) 465327952Sdim : Expr(ObjCSelectorExprClass, Empty) {} 466193326Sed 467193326Sed Selector getSelector() const { return SelName; } 468193326Sed void setSelector(Selector S) { SelName = S; } 469198092Srdivacky 470193326Sed SourceLocation getAtLoc() const { return AtLoc; } 471193326Sed SourceLocation getRParenLoc() const { return RParenLoc; } 472193326Sed void setAtLoc(SourceLocation L) { AtLoc = L; } 473193326Sed void setRParenLoc(SourceLocation L) { RParenLoc = L; } 474193326Sed 475341825Sdim SourceLocation getBeginLoc() const LLVM_READONLY { return AtLoc; } 476341825Sdim SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; } 477198092Srdivacky 478193326Sed /// getNumArgs - Return the number of actual arguments to this call. 479193326Sed unsigned getNumArgs() const { return SelName.getNumArgs(); } 480198092Srdivacky 481193326Sed // Iterators 482296417Sdim child_range children() { 483296417Sdim return child_range(child_iterator(), child_iterator()); 484296417Sdim } 485327952Sdim 486353358Sdim const_child_range children() const { 487353358Sdim return const_child_range(const_child_iterator(), const_child_iterator()); 488353358Sdim } 489353358Sdim 490327952Sdim static bool classof(const Stmt *T) { 491327952Sdim return T->getStmtClass() == ObjCSelectorExprClass; 492327952Sdim } 493193326Sed}; 494198092Srdivacky 495249423Sdim/// ObjCProtocolExpr used for protocol expression in Objective-C. 496249423Sdim/// 497249423Sdim/// This is used as: \@protocol(foo), as in: 498249423Sdim/// \code 499249423Sdim/// [obj conformsToProtocol:@protocol(foo)] 500249423Sdim/// \endcode 501249423Sdim/// 502193326Sed/// The return type is "Protocol*". 503198092Srdivackyclass ObjCProtocolExpr : public Expr { 504198092Srdivacky ObjCProtocolDecl *TheProtocol; 505239462Sdim SourceLocation AtLoc, ProtoLoc, RParenLoc; 506327952Sdim 507193326Sedpublic: 508327952Sdim friend class ASTStmtReader; 509327952Sdim friend class ASTStmtWriter; 510327952Sdim 511193326Sed ObjCProtocolExpr(QualType T, ObjCProtocolDecl *protocol, 512239462Sdim SourceLocation at, SourceLocation protoLoc, SourceLocation rp) 513327952Sdim : Expr(ObjCProtocolExprClass, T, VK_RValue, OK_Ordinary, false, false, 514327952Sdim false, false), 515327952Sdim TheProtocol(protocol), AtLoc(at), ProtoLoc(protoLoc), RParenLoc(rp) {} 516193326Sed explicit ObjCProtocolExpr(EmptyShell Empty) 517327952Sdim : Expr(ObjCProtocolExprClass, Empty) {} 518193326Sed 519194613Sed ObjCProtocolDecl *getProtocol() const { return TheProtocol; } 520194613Sed void setProtocol(ObjCProtocolDecl *P) { TheProtocol = P; } 521198092Srdivacky 522239462Sdim SourceLocation getProtocolIdLoc() const { return ProtoLoc; } 523193326Sed SourceLocation getAtLoc() const { return AtLoc; } 524193326Sed SourceLocation getRParenLoc() const { return RParenLoc; } 525193326Sed void setAtLoc(SourceLocation L) { AtLoc = L; } 526193326Sed void setRParenLoc(SourceLocation L) { RParenLoc = L; } 527193326Sed 528341825Sdim SourceLocation getBeginLoc() const LLVM_READONLY { return AtLoc; } 529341825Sdim SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; } 530198092Srdivacky 531193326Sed // Iterators 532296417Sdim child_range children() { 533296417Sdim return child_range(child_iterator(), child_iterator()); 534296417Sdim } 535239462Sdim 536353358Sdim const_child_range children() const { 537353358Sdim return const_child_range(const_child_iterator(), const_child_iterator()); 538353358Sdim } 539353358Sdim 540327952Sdim static bool classof(const Stmt *T) { 541327952Sdim return T->getStmtClass() == ObjCProtocolExprClass; 542327952Sdim } 543193326Sed}; 544193326Sed 545193326Sed/// ObjCIvarRefExpr - A reference to an ObjC instance variable. 546193326Sedclass ObjCIvarRefExpr : public Expr { 547234353Sdim ObjCIvarDecl *D; 548234353Sdim Stmt *Base; 549193326Sed SourceLocation Loc; 550327952Sdim 551249423Sdim /// OpLoc - This is the location of '.' or '->' 552249423Sdim SourceLocation OpLoc; 553198092Srdivacky 554327952Sdim // True if this is "X->F", false if this is "X.F". 555327952Sdim bool IsArrow : 1; 556327952Sdim 557327952Sdim // True if ivar reference has no base (self assumed). 558327952Sdim bool IsFreeIvar : 1; 559327952Sdim 560193326Sedpublic: 561218893Sdim ObjCIvarRefExpr(ObjCIvarDecl *d, QualType t, 562249423Sdim SourceLocation l, SourceLocation oploc, 563249423Sdim Expr *base, 564327952Sdim bool arrow = false, bool freeIvar = false) 565327952Sdim : Expr(ObjCIvarRefExprClass, t, VK_LValue, 566327952Sdim d->isBitField() ? OK_BitField : OK_Ordinary, 567341825Sdim /*TypeDependent=*/false, base->isValueDependent(), 568327952Sdim base->isInstantiationDependent(), 569341825Sdim base->containsUnexpandedParameterPack()), 570327952Sdim D(d), Base(base), Loc(l), OpLoc(oploc), IsArrow(arrow), 571327952Sdim IsFreeIvar(freeIvar) {} 572198092Srdivacky 573193326Sed explicit ObjCIvarRefExpr(EmptyShell Empty) 574327952Sdim : Expr(ObjCIvarRefExprClass, Empty) {} 575193326Sed 576193326Sed ObjCIvarDecl *getDecl() { return D; } 577193326Sed const ObjCIvarDecl *getDecl() const { return D; } 578193326Sed void setDecl(ObjCIvarDecl *d) { D = d; } 579198092Srdivacky 580193326Sed const Expr *getBase() const { return cast<Expr>(Base); } 581193326Sed Expr *getBase() { return cast<Expr>(Base); } 582193326Sed void setBase(Expr * base) { Base = base; } 583198092Srdivacky 584193326Sed bool isArrow() const { return IsArrow; } 585193326Sed bool isFreeIvar() const { return IsFreeIvar; } 586193326Sed void setIsArrow(bool A) { IsArrow = A; } 587193326Sed void setIsFreeIvar(bool A) { IsFreeIvar = A; } 588198092Srdivacky 589193326Sed SourceLocation getLocation() const { return Loc; } 590193326Sed void setLocation(SourceLocation L) { Loc = L; } 591193326Sed 592341825Sdim SourceLocation getBeginLoc() const LLVM_READONLY { 593344779Sdim return isFreeIvar() ? Loc : getBase()->getBeginLoc(); 594193326Sed } 595341825Sdim SourceLocation getEndLoc() const LLVM_READONLY { return Loc; } 596341825Sdim 597249423Sdim SourceLocation getOpLoc() const { return OpLoc; } 598249423Sdim void setOpLoc(SourceLocation L) { OpLoc = L; } 599198092Srdivacky 600327952Sdim // Iterators 601327952Sdim child_range children() { return child_range(&Base, &Base+1); } 602327952Sdim 603353358Sdim const_child_range children() const { 604353358Sdim return const_child_range(&Base, &Base + 1); 605353358Sdim } 606353358Sdim 607198092Srdivacky static bool classof(const Stmt *T) { 608198092Srdivacky return T->getStmtClass() == ObjCIvarRefExprClass; 609193326Sed } 610193326Sed}; 611193326Sed 612193326Sed/// ObjCPropertyRefExpr - A dot-syntax expression to access an ObjC 613193326Sed/// property. 614193326Sedclass ObjCPropertyRefExpr : public Expr { 615193326Sedprivate: 616218893Sdim /// If the bool is true, this is an implicit property reference; the 617218893Sdim /// pointer is an (optional) ObjCMethodDecl and Setter may be set. 618218893Sdim /// if the bool is false, this is an explicit property reference; 619218893Sdim /// the pointer is an ObjCPropertyDecl and Setter is always null. 620327952Sdim llvm::PointerIntPair<NamedDecl *, 1, bool> PropertyOrGetter; 621218893Sdim 622341825Sdim /// Indicates whether the property reference will result in a message 623234353Sdim /// to the getter, the setter, or both. 624234353Sdim /// This applies to both implicit and explicit property references. 625234353Sdim enum MethodRefFlags { 626234353Sdim MethodRef_None = 0, 627234353Sdim MethodRef_Getter = 0x1, 628234353Sdim MethodRef_Setter = 0x2 629234353Sdim }; 630234353Sdim 631341825Sdim /// Contains the Setter method pointer and MethodRefFlags bit flags. 632234353Sdim llvm::PointerIntPair<ObjCMethodDecl *, 2, unsigned> SetterAndMethodRefFlags; 633234353Sdim 634234353Sdim // FIXME: Maybe we should store the property identifier here, 635234353Sdim // because it's not rederivable from the other data when there's an 636234353Sdim // implicit property with no getter (because the 'foo' -> 'setFoo:' 637234353Sdim // transformation is lossy on the first character). 638234353Sdim 639193326Sed SourceLocation IdLoc; 640341825Sdim 641341825Sdim /// When the receiver in property access is 'super', this is 642218893Sdim /// the location of the 'super' keyword. When it's an interface, 643218893Sdim /// this is that interface. 644218893Sdim SourceLocation ReceiverLoc; 645360784Sdim llvm::PointerUnion<Stmt *, const Type *, ObjCInterfaceDecl *> Receiver; 646341825Sdim 647193326Sedpublic: 648198092Srdivacky ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t, 649218893Sdim ExprValueKind VK, ExprObjectKind OK, 650193326Sed SourceLocation l, Expr *base) 651327952Sdim : Expr(ObjCPropertyRefExprClass, t, VK, OK, 652327952Sdim /*TypeDependent=*/false, base->isValueDependent(), 653327952Sdim base->isInstantiationDependent(), 654327952Sdim base->containsUnexpandedParameterPack()), 655327952Sdim PropertyOrGetter(PD, false), IdLoc(l), Receiver(base) { 656234353Sdim assert(t->isSpecificPlaceholderType(BuiltinType::PseudoObject)); 657193326Sed } 658341825Sdim 659218893Sdim ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t, 660218893Sdim ExprValueKind VK, ExprObjectKind OK, 661218893Sdim SourceLocation l, SourceLocation sl, QualType st) 662327952Sdim : Expr(ObjCPropertyRefExprClass, t, VK, OK, 663327952Sdim /*TypeDependent=*/false, false, st->isInstantiationDependentType(), 664327952Sdim st->containsUnexpandedParameterPack()), 665327952Sdim PropertyOrGetter(PD, false), IdLoc(l), ReceiverLoc(sl), 666327952Sdim Receiver(st.getTypePtr()) { 667234353Sdim assert(t->isSpecificPlaceholderType(BuiltinType::PseudoObject)); 668218893Sdim } 669198092Srdivacky 670218893Sdim ObjCPropertyRefExpr(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter, 671218893Sdim QualType T, ExprValueKind VK, ExprObjectKind OK, 672218893Sdim SourceLocation IdLoc, Expr *Base) 673327952Sdim : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, 674327952Sdim Base->isValueDependent(), Base->isInstantiationDependent(), 675327952Sdim Base->containsUnexpandedParameterPack()), 676327952Sdim PropertyOrGetter(Getter, true), SetterAndMethodRefFlags(Setter, 0), 677327952Sdim IdLoc(IdLoc), Receiver(Base) { 678234353Sdim assert(T->isSpecificPlaceholderType(BuiltinType::PseudoObject)); 679218893Sdim } 680218893Sdim 681218893Sdim ObjCPropertyRefExpr(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter, 682218893Sdim QualType T, ExprValueKind VK, ExprObjectKind OK, 683218893Sdim SourceLocation IdLoc, 684218893Sdim SourceLocation SuperLoc, QualType SuperTy) 685327952Sdim : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, false, false, false), 686327952Sdim PropertyOrGetter(Getter, true), SetterAndMethodRefFlags(Setter, 0), 687327952Sdim IdLoc(IdLoc), ReceiverLoc(SuperLoc), Receiver(SuperTy.getTypePtr()) { 688234353Sdim assert(T->isSpecificPlaceholderType(BuiltinType::PseudoObject)); 689218893Sdim } 690218893Sdim 691218893Sdim ObjCPropertyRefExpr(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter, 692218893Sdim QualType T, ExprValueKind VK, ExprObjectKind OK, 693218893Sdim SourceLocation IdLoc, 694218893Sdim SourceLocation ReceiverLoc, ObjCInterfaceDecl *Receiver) 695327952Sdim : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, false, false, false), 696327952Sdim PropertyOrGetter(Getter, true), SetterAndMethodRefFlags(Setter, 0), 697327952Sdim IdLoc(IdLoc), ReceiverLoc(ReceiverLoc), Receiver(Receiver) { 698234353Sdim assert(T->isSpecificPlaceholderType(BuiltinType::PseudoObject)); 699218893Sdim } 700218893Sdim 701193326Sed explicit ObjCPropertyRefExpr(EmptyShell Empty) 702327952Sdim : Expr(ObjCPropertyRefExprClass, Empty) {} 703193326Sed 704218893Sdim bool isImplicitProperty() const { return PropertyOrGetter.getInt(); } 705218893Sdim bool isExplicitProperty() const { return !PropertyOrGetter.getInt(); } 706198092Srdivacky 707218893Sdim ObjCPropertyDecl *getExplicitProperty() const { 708218893Sdim assert(!isImplicitProperty()); 709218893Sdim return cast<ObjCPropertyDecl>(PropertyOrGetter.getPointer()); 710218893Sdim } 711198092Srdivacky 712218893Sdim ObjCMethodDecl *getImplicitPropertyGetter() const { 713218893Sdim assert(isImplicitProperty()); 714218893Sdim return cast_or_null<ObjCMethodDecl>(PropertyOrGetter.getPointer()); 715218893Sdim } 716218893Sdim 717218893Sdim ObjCMethodDecl *getImplicitPropertySetter() const { 718218893Sdim assert(isImplicitProperty()); 719234353Sdim return SetterAndMethodRefFlags.getPointer(); 720218893Sdim } 721218893Sdim 722218893Sdim Selector getGetterSelector() const { 723218893Sdim if (isImplicitProperty()) 724218893Sdim return getImplicitPropertyGetter()->getSelector(); 725218893Sdim return getExplicitProperty()->getGetterName(); 726218893Sdim } 727218893Sdim 728218893Sdim Selector getSetterSelector() const { 729218893Sdim if (isImplicitProperty()) 730218893Sdim return getImplicitPropertySetter()->getSelector(); 731218893Sdim return getExplicitProperty()->getSetterName(); 732218893Sdim } 733218893Sdim 734341825Sdim /// True if the property reference will result in a message to the 735234353Sdim /// getter. 736234353Sdim /// This applies to both implicit and explicit property references. 737234353Sdim bool isMessagingGetter() const { 738234353Sdim return SetterAndMethodRefFlags.getInt() & MethodRef_Getter; 739234353Sdim } 740234353Sdim 741341825Sdim /// True if the property reference will result in a message to the 742234353Sdim /// setter. 743234353Sdim /// This applies to both implicit and explicit property references. 744234353Sdim bool isMessagingSetter() const { 745234353Sdim return SetterAndMethodRefFlags.getInt() & MethodRef_Setter; 746234353Sdim } 747234353Sdim 748234353Sdim void setIsMessagingGetter(bool val = true) { 749234353Sdim setMethodRefFlag(MethodRef_Getter, val); 750234353Sdim } 751234353Sdim 752234353Sdim void setIsMessagingSetter(bool val = true) { 753234353Sdim setMethodRefFlag(MethodRef_Setter, val); 754234353Sdim } 755234353Sdim 756341825Sdim const Expr *getBase() const { 757341825Sdim return cast<Expr>(Receiver.get<Stmt*>()); 758218893Sdim } 759341825Sdim Expr *getBase() { 760341825Sdim return cast<Expr>(Receiver.get<Stmt*>()); 761218893Sdim } 762218893Sdim 763193326Sed SourceLocation getLocation() const { return IdLoc; } 764341825Sdim 765218893Sdim SourceLocation getReceiverLocation() const { return ReceiverLoc; } 766327952Sdim 767341825Sdim QualType getSuperReceiverType() const { 768341825Sdim return QualType(Receiver.get<const Type*>(), 0); 769218893Sdim } 770234353Sdim 771218893Sdim ObjCInterfaceDecl *getClassReceiver() const { 772218893Sdim return Receiver.get<ObjCInterfaceDecl*>(); 773218893Sdim } 774327952Sdim 775218893Sdim bool isObjectReceiver() const { return Receiver.is<Stmt*>(); } 776218893Sdim bool isSuperReceiver() const { return Receiver.is<const Type*>(); } 777218893Sdim bool isClassReceiver() const { return Receiver.is<ObjCInterfaceDecl*>(); } 778193326Sed 779288943Sdim /// Determine the type of the base, regardless of the kind of receiver. 780288943Sdim QualType getReceiverType(const ASTContext &ctx) const; 781288943Sdim 782341825Sdim SourceLocation getBeginLoc() const LLVM_READONLY { 783344779Sdim return isObjectReceiver() ? getBase()->getBeginLoc() 784344779Sdim : getReceiverLocation(); 785193326Sed } 786327952Sdim 787341825Sdim SourceLocation getEndLoc() const LLVM_READONLY { return IdLoc; } 788198092Srdivacky 789193326Sed // Iterators 790218893Sdim child_range children() { 791218893Sdim if (Receiver.is<Stmt*>()) { 792218893Sdim Stmt **begin = reinterpret_cast<Stmt**>(&Receiver); // hack! 793218893Sdim return child_range(begin, begin+1); 794193326Sed } 795296417Sdim return child_range(child_iterator(), child_iterator()); 796193326Sed } 797198092Srdivacky 798353358Sdim const_child_range children() const { 799353358Sdim auto Children = const_cast<ObjCPropertyRefExpr *>(this)->children(); 800353358Sdim return const_child_range(Children.begin(), Children.end()); 801353358Sdim } 802353358Sdim 803327952Sdim static bool classof(const Stmt *T) { 804327952Sdim return T->getStmtClass() == ObjCPropertyRefExprClass; 805327952Sdim } 806327952Sdim 807218893Sdimprivate: 808218893Sdim friend class ASTStmtReader; 809234353Sdim friend class ASTStmtWriter; 810327952Sdim 811234353Sdim void setExplicitProperty(ObjCPropertyDecl *D, unsigned methRefFlags) { 812218893Sdim PropertyOrGetter.setPointer(D); 813218893Sdim PropertyOrGetter.setInt(false); 814276479Sdim SetterAndMethodRefFlags.setPointer(nullptr); 815234353Sdim SetterAndMethodRefFlags.setInt(methRefFlags); 816193326Sed } 817327952Sdim 818234353Sdim void setImplicitProperty(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter, 819234353Sdim unsigned methRefFlags) { 820218893Sdim PropertyOrGetter.setPointer(Getter); 821218893Sdim PropertyOrGetter.setInt(true); 822234353Sdim SetterAndMethodRefFlags.setPointer(Setter); 823234353Sdim SetterAndMethodRefFlags.setInt(methRefFlags); 824218893Sdim } 825327952Sdim 826218893Sdim void setBase(Expr *Base) { Receiver = Base; } 827218893Sdim void setSuperReceiver(QualType T) { Receiver = T.getTypePtr(); } 828218893Sdim void setClassReceiver(ObjCInterfaceDecl *D) { Receiver = D; } 829198092Srdivacky 830218893Sdim void setLocation(SourceLocation L) { IdLoc = L; } 831218893Sdim void setReceiverLocation(SourceLocation Loc) { ReceiverLoc = Loc; } 832234353Sdim 833234353Sdim void setMethodRefFlag(MethodRefFlags flag, bool val) { 834234353Sdim unsigned f = SetterAndMethodRefFlags.getInt(); 835234353Sdim if (val) 836234353Sdim f |= flag; 837234353Sdim else 838234353Sdim f &= ~flag; 839234353Sdim SetterAndMethodRefFlags.setInt(f); 840234353Sdim } 841193326Sed}; 842341825Sdim 843234353Sdim/// ObjCSubscriptRefExpr - used for array and dictionary subscripting. 844234353Sdim/// array[4] = array[3]; dictionary[key] = dictionary[alt_key]; 845234353Sdimclass ObjCSubscriptRefExpr : public Expr { 846234353Sdim // Location of ']' in an indexing expression. 847234353Sdim SourceLocation RBracket; 848327952Sdim 849234353Sdim // array/dictionary base expression. 850234353Sdim // for arrays, this is a numeric expression. For dictionaries, this is 851234353Sdim // an objective-c object pointer expression. 852234353Sdim enum { BASE, KEY, END_EXPR }; 853234353Sdim Stmt* SubExprs[END_EXPR]; 854341825Sdim 855234353Sdim ObjCMethodDecl *GetAtIndexMethodDecl; 856341825Sdim 857234353Sdim // For immutable objects this is null. When ObjCSubscriptRefExpr is to read 858234353Sdim // an indexed object this is null too. 859234353Sdim ObjCMethodDecl *SetAtIndexMethodDecl; 860341825Sdim 861234353Sdimpublic: 862234353Sdim ObjCSubscriptRefExpr(Expr *base, Expr *key, QualType T, 863234353Sdim ExprValueKind VK, ExprObjectKind OK, 864234353Sdim ObjCMethodDecl *getMethod, 865234353Sdim ObjCMethodDecl *setMethod, SourceLocation RB) 866341825Sdim : Expr(ObjCSubscriptRefExprClass, T, VK, OK, 867341825Sdim base->isTypeDependent() || key->isTypeDependent(), 868327952Sdim base->isValueDependent() || key->isValueDependent(), 869327952Sdim (base->isInstantiationDependent() || 870327952Sdim key->isInstantiationDependent()), 871327952Sdim (base->containsUnexpandedParameterPack() || 872327952Sdim key->containsUnexpandedParameterPack())), 873327952Sdim RBracket(RB), GetAtIndexMethodDecl(getMethod), 874327952Sdim SetAtIndexMethodDecl(setMethod) { 875327952Sdim SubExprs[BASE] = base; SubExprs[KEY] = key; 876327952Sdim } 877198092Srdivacky 878234353Sdim explicit ObjCSubscriptRefExpr(EmptyShell Empty) 879327952Sdim : Expr(ObjCSubscriptRefExprClass, Empty) {} 880341825Sdim 881234353Sdim SourceLocation getRBracket() const { return RBracket; } 882234353Sdim void setRBracket(SourceLocation RB) { RBracket = RB; } 883249423Sdim 884341825Sdim SourceLocation getBeginLoc() const LLVM_READONLY { 885344779Sdim return SubExprs[BASE]->getBeginLoc(); 886234353Sdim } 887327952Sdim 888341825Sdim SourceLocation getEndLoc() const LLVM_READONLY { return RBracket; } 889341825Sdim 890234353Sdim Expr *getBaseExpr() const { return cast<Expr>(SubExprs[BASE]); } 891234353Sdim void setBaseExpr(Stmt *S) { SubExprs[BASE] = S; } 892341825Sdim 893234353Sdim Expr *getKeyExpr() const { return cast<Expr>(SubExprs[KEY]); } 894234353Sdim void setKeyExpr(Stmt *S) { SubExprs[KEY] = S; } 895341825Sdim 896234353Sdim ObjCMethodDecl *getAtIndexMethodDecl() const { 897234353Sdim return GetAtIndexMethodDecl; 898234353Sdim } 899341825Sdim 900234353Sdim ObjCMethodDecl *setAtIndexMethodDecl() const { 901234353Sdim return SetAtIndexMethodDecl; 902234353Sdim } 903341825Sdim 904234353Sdim bool isArraySubscriptRefExpr() const { 905234353Sdim return getKeyExpr()->getType()->isIntegralOrEnumerationType(); 906234353Sdim } 907341825Sdim 908234353Sdim child_range children() { 909234353Sdim return child_range(SubExprs, SubExprs+END_EXPR); 910234353Sdim } 911327952Sdim 912353358Sdim const_child_range children() const { 913353358Sdim return const_child_range(SubExprs, SubExprs + END_EXPR); 914353358Sdim } 915353358Sdim 916327952Sdim static bool classof(const Stmt *T) { 917327952Sdim return T->getStmtClass() == ObjCSubscriptRefExprClass; 918327952Sdim } 919327952Sdim 920234353Sdimprivate: 921234353Sdim friend class ASTStmtReader; 922234353Sdim}; 923234353Sdim 924341825Sdim/// An expression that sends a message to the given Objective-C 925207619Srdivacky/// object or class. 926207619Srdivacky/// 927207619Srdivacky/// The following contains two message send expressions: 928207619Srdivacky/// 929207619Srdivacky/// \code 930207619Srdivacky/// [[NSString alloc] initWithString:@"Hello"] 931207619Srdivacky/// \endcode 932207619Srdivacky/// 933207619Srdivacky/// The innermost message send invokes the "alloc" class method on the 934207619Srdivacky/// NSString class, while the outermost message send invokes the 935207619Srdivacky/// "initWithString" instance method on the object returned from 936207619Srdivacky/// NSString's "alloc". In all, an Objective-C message send can take 937207619Srdivacky/// on four different (although related) forms: 938207619Srdivacky/// 939207619Srdivacky/// 1. Send to an object instance. 940207619Srdivacky/// 2. Send to a class. 941207619Srdivacky/// 3. Send to the superclass instance of the current class. 942207619Srdivacky/// 4. Send to the superclass of the current class. 943207619Srdivacky/// 944207619Srdivacky/// All four kinds of message sends are modeled by the ObjCMessageExpr 945207619Srdivacky/// class, and can be distinguished via \c getReceiverKind(). Example: 946207619Srdivacky/// 947296417Sdim/// The "void *" trailing objects are actually ONE void * (the 948296417Sdim/// receiver pointer), and NumArgs Expr *. But due to the 949296417Sdim/// implementation of children(), these must be together contiguously. 950296417Sdimclass ObjCMessageExpr final 951296417Sdim : public Expr, 952296417Sdim private llvm::TrailingObjects<ObjCMessageExpr, void *, SourceLocation> { 953341825Sdim /// Stores either the selector that this message is sending 954226633Sdim /// to (when \c HasMethod is zero) or an \c ObjCMethodDecl pointer 955226633Sdim /// referring to the method that we type-checked against. 956327952Sdim uintptr_t SelectorOrMethod = 0; 957226633Sdim 958226633Sdim enum { NumArgsBitWidth = 16 }; 959226633Sdim 960341825Sdim /// The number of arguments in the message send, not 961207619Srdivacky /// including the receiver. 962226633Sdim unsigned NumArgs : NumArgsBitWidth; 963341825Sdim 964341825Sdim /// The kind of message send this is, which is one of the 965207619Srdivacky /// ReceiverKind values. 966207619Srdivacky /// 967207619Srdivacky /// We pad this out to a byte to avoid excessive masking and shifting. 968207619Srdivacky unsigned Kind : 8; 969198092Srdivacky 970341825Sdim /// Whether we have an actual method prototype in \c 971207619Srdivacky /// SelectorOrMethod. 972207619Srdivacky /// 973207619Srdivacky /// When non-zero, we have a method declaration; otherwise, we just 974207619Srdivacky /// have a selector. 975224145Sdim unsigned HasMethod : 1; 976204962Srdivacky 977341825Sdim /// Whether this message send is a "delegate init call", 978224145Sdim /// i.e. a call of an init method on self from within an init method. 979224145Sdim unsigned IsDelegateInitCall : 1; 980234353Sdim 981341825Sdim /// Whether this message send was implicitly generated by 982234353Sdim /// the implementation rather than explicitly written by the user. 983234353Sdim unsigned IsImplicit : 1; 984234353Sdim 985341825Sdim /// Whether the locations of the selector identifiers are in a 986226633Sdim /// "standard" position, a enum SelectorLocationsKind. 987226633Sdim unsigned SelLocsKind : 2; 988224145Sdim 989341825Sdim /// When the message expression is a send to 'super', this is 990207619Srdivacky /// the location of the 'super' keyword. 991207619Srdivacky SourceLocation SuperLoc; 992198092Srdivacky 993341825Sdim /// The source locations of the open and close square 994207619Srdivacky /// brackets ('[' and ']', respectively). 995207619Srdivacky SourceLocation LBracLoc, RBracLoc; 996193326Sed 997207619Srdivacky ObjCMessageExpr(EmptyShell Empty, unsigned NumArgs) 998327952Sdim : Expr(ObjCMessageExprClass, Empty), Kind(0), HasMethod(false), 999327952Sdim IsDelegateInitCall(false), IsImplicit(false), SelLocsKind(0) { 1000226633Sdim setNumArgs(NumArgs); 1001226633Sdim } 1002193326Sed 1003218893Sdim ObjCMessageExpr(QualType T, ExprValueKind VK, 1004207619Srdivacky SourceLocation LBracLoc, 1005207619Srdivacky SourceLocation SuperLoc, 1006207619Srdivacky bool IsInstanceSuper, 1007207619Srdivacky QualType SuperType, 1008341825Sdim Selector Sel, 1009226633Sdim ArrayRef<SourceLocation> SelLocs, 1010226633Sdim SelectorLocationsKind SelLocsK, 1011207619Srdivacky ObjCMethodDecl *Method, 1012226633Sdim ArrayRef<Expr *> Args, 1013234353Sdim SourceLocation RBracLoc, 1014234353Sdim bool isImplicit); 1015218893Sdim ObjCMessageExpr(QualType T, ExprValueKind VK, 1016207619Srdivacky SourceLocation LBracLoc, 1017207619Srdivacky TypeSourceInfo *Receiver, 1018341825Sdim Selector Sel, 1019226633Sdim ArrayRef<SourceLocation> SelLocs, 1020226633Sdim SelectorLocationsKind SelLocsK, 1021207619Srdivacky ObjCMethodDecl *Method, 1022226633Sdim ArrayRef<Expr *> Args, 1023234353Sdim SourceLocation RBracLoc, 1024234353Sdim bool isImplicit); 1025218893Sdim ObjCMessageExpr(QualType T, ExprValueKind VK, 1026207619Srdivacky SourceLocation LBracLoc, 1027207619Srdivacky Expr *Receiver, 1028341825Sdim Selector Sel, 1029226633Sdim ArrayRef<SourceLocation> SelLocs, 1030226633Sdim SelectorLocationsKind SelLocsK, 1031207619Srdivacky ObjCMethodDecl *Method, 1032226633Sdim ArrayRef<Expr *> Args, 1033234353Sdim SourceLocation RBracLoc, 1034234353Sdim bool isImplicit); 1035198092Srdivacky 1036327952Sdim size_t numTrailingObjects(OverloadToken<void *>) const { return NumArgs + 1; } 1037327952Sdim 1038327952Sdim void setNumArgs(unsigned Num) { 1039327952Sdim assert((Num >> NumArgsBitWidth) == 0 && "Num of args is out of range!"); 1040327952Sdim NumArgs = Num; 1041327952Sdim } 1042327952Sdim 1043226633Sdim void initArgsAndSelLocs(ArrayRef<Expr *> Args, 1044226633Sdim ArrayRef<SourceLocation> SelLocs, 1045226633Sdim SelectorLocationsKind SelLocsK); 1046226633Sdim 1047341825Sdim /// Retrieve the pointer value of the message receiver. 1048296417Sdim void *getReceiverPointer() const { return *getTrailingObjects<void *>(); } 1049207619Srdivacky 1050341825Sdim /// Set the pointer value of the message receiver. 1051207619Srdivacky void setReceiverPointer(void *Value) { 1052296417Sdim *getTrailingObjects<void *>() = Value; 1053207619Srdivacky } 1054207619Srdivacky 1055226633Sdim SelectorLocationsKind getSelLocsKind() const { 1056226633Sdim return (SelectorLocationsKind)SelLocsKind; 1057226633Sdim } 1058327952Sdim 1059226633Sdim bool hasStandardSelLocs() const { 1060226633Sdim return getSelLocsKind() != SelLoc_NonStandard; 1061226633Sdim } 1062226633Sdim 1063341825Sdim /// Get a pointer to the stored selector identifiers locations array. 1064226633Sdim /// No locations will be stored if HasStandardSelLocs is true. 1065226633Sdim SourceLocation *getStoredSelLocs() { 1066296417Sdim return getTrailingObjects<SourceLocation>(); 1067226633Sdim } 1068226633Sdim const SourceLocation *getStoredSelLocs() const { 1069296417Sdim return getTrailingObjects<SourceLocation>(); 1070226633Sdim } 1071226633Sdim 1072341825Sdim /// Get the number of stored selector identifiers locations. 1073226633Sdim /// No locations will be stored if HasStandardSelLocs is true. 1074226633Sdim unsigned getNumStoredSelLocs() const { 1075226633Sdim if (hasStandardSelLocs()) 1076226633Sdim return 0; 1077226633Sdim return getNumSelectorLocs(); 1078226633Sdim } 1079226633Sdim 1080261991Sdim static ObjCMessageExpr *alloc(const ASTContext &C, 1081226633Sdim ArrayRef<Expr *> Args, 1082226633Sdim SourceLocation RBraceLoc, 1083226633Sdim ArrayRef<SourceLocation> SelLocs, 1084226633Sdim Selector Sel, 1085226633Sdim SelectorLocationsKind &SelLocsK); 1086261991Sdim static ObjCMessageExpr *alloc(const ASTContext &C, 1087226633Sdim unsigned NumArgs, 1088226633Sdim unsigned NumStoredSelLocs); 1089226633Sdim 1090193326Sedpublic: 1091327952Sdim friend class ASTStmtReader; 1092327952Sdim friend class ASTStmtWriter; 1093327952Sdim friend TrailingObjects; 1094327952Sdim 1095341825Sdim /// The kind of receiver this message is sending to. 1096207619Srdivacky enum ReceiverKind { 1097341825Sdim /// The receiver is a class. 1098207619Srdivacky Class = 0, 1099327952Sdim 1100341825Sdim /// The receiver is an object instance. 1101207619Srdivacky Instance, 1102327952Sdim 1103341825Sdim /// The receiver is a superclass. 1104207619Srdivacky SuperClass, 1105327952Sdim 1106341825Sdim /// The receiver is the instance of the superclass object. 1107207619Srdivacky SuperInstance 1108207619Srdivacky }; 1109193326Sed 1110341825Sdim /// Create a message send to super. 1111207619Srdivacky /// 1112207619Srdivacky /// \param Context The ASTContext in which this expression will be created. 1113207619Srdivacky /// 1114207619Srdivacky /// \param T The result type of this message. 1115207619Srdivacky /// 1116218893Sdim /// \param VK The value kind of this message. A message returning 1117218893Sdim /// a l-value or r-value reference will be an l-value or x-value, 1118218893Sdim /// respectively. 1119218893Sdim /// 1120239462Sdim /// \param LBracLoc The location of the open square bracket '['. 1121207619Srdivacky /// 1122207619Srdivacky /// \param SuperLoc The location of the "super" keyword. 1123207619Srdivacky /// 1124207619Srdivacky /// \param IsInstanceSuper Whether this is an instance "super" 1125207619Srdivacky /// message (otherwise, it's a class "super" message). 1126207619Srdivacky /// 1127207619Srdivacky /// \param Sel The selector used to determine which method gets called. 1128207619Srdivacky /// 1129207619Srdivacky /// \param Method The Objective-C method against which this message 1130327952Sdim /// send was type-checked. May be nullptr. 1131207619Srdivacky /// 1132207619Srdivacky /// \param Args The message send arguments. 1133207619Srdivacky /// 1134207619Srdivacky /// \param RBracLoc The location of the closing square bracket ']'. 1135261991Sdim static ObjCMessageExpr *Create(const ASTContext &Context, QualType T, 1136218893Sdim ExprValueKind VK, 1137207619Srdivacky SourceLocation LBracLoc, 1138207619Srdivacky SourceLocation SuperLoc, 1139207619Srdivacky bool IsInstanceSuper, 1140207619Srdivacky QualType SuperType, 1141341825Sdim Selector Sel, 1142226633Sdim ArrayRef<SourceLocation> SelLocs, 1143207619Srdivacky ObjCMethodDecl *Method, 1144226633Sdim ArrayRef<Expr *> Args, 1145234353Sdim SourceLocation RBracLoc, 1146234353Sdim bool isImplicit); 1147198092Srdivacky 1148341825Sdim /// Create a class message send. 1149207619Srdivacky /// 1150207619Srdivacky /// \param Context The ASTContext in which this expression will be created. 1151207619Srdivacky /// 1152207619Srdivacky /// \param T The result type of this message. 1153207619Srdivacky /// 1154218893Sdim /// \param VK The value kind of this message. A message returning 1155218893Sdim /// a l-value or r-value reference will be an l-value or x-value, 1156218893Sdim /// respectively. 1157218893Sdim /// 1158239462Sdim /// \param LBracLoc The location of the open square bracket '['. 1159207619Srdivacky /// 1160207619Srdivacky /// \param Receiver The type of the receiver, including 1161207619Srdivacky /// source-location information. 1162207619Srdivacky /// 1163207619Srdivacky /// \param Sel The selector used to determine which method gets called. 1164207619Srdivacky /// 1165207619Srdivacky /// \param Method The Objective-C method against which this message 1166327952Sdim /// send was type-checked. May be nullptr. 1167207619Srdivacky /// 1168207619Srdivacky /// \param Args The message send arguments. 1169207619Srdivacky /// 1170207619Srdivacky /// \param RBracLoc The location of the closing square bracket ']'. 1171261991Sdim static ObjCMessageExpr *Create(const ASTContext &Context, QualType T, 1172218893Sdim ExprValueKind VK, 1173207619Srdivacky SourceLocation LBracLoc, 1174207619Srdivacky TypeSourceInfo *Receiver, 1175341825Sdim Selector Sel, 1176226633Sdim ArrayRef<SourceLocation> SelLocs, 1177207619Srdivacky ObjCMethodDecl *Method, 1178226633Sdim ArrayRef<Expr *> Args, 1179234353Sdim SourceLocation RBracLoc, 1180234353Sdim bool isImplicit); 1181198092Srdivacky 1182341825Sdim /// Create an instance message send. 1183207619Srdivacky /// 1184207619Srdivacky /// \param Context The ASTContext in which this expression will be created. 1185207619Srdivacky /// 1186207619Srdivacky /// \param T The result type of this message. 1187207619Srdivacky /// 1188218893Sdim /// \param VK The value kind of this message. A message returning 1189218893Sdim /// a l-value or r-value reference will be an l-value or x-value, 1190218893Sdim /// respectively. 1191218893Sdim /// 1192239462Sdim /// \param LBracLoc The location of the open square bracket '['. 1193207619Srdivacky /// 1194207619Srdivacky /// \param Receiver The expression used to produce the object that 1195207619Srdivacky /// will receive this message. 1196207619Srdivacky /// 1197207619Srdivacky /// \param Sel The selector used to determine which method gets called. 1198207619Srdivacky /// 1199207619Srdivacky /// \param Method The Objective-C method against which this message 1200327952Sdim /// send was type-checked. May be nullptr. 1201207619Srdivacky /// 1202207619Srdivacky /// \param Args The message send arguments. 1203207619Srdivacky /// 1204207619Srdivacky /// \param RBracLoc The location of the closing square bracket ']'. 1205261991Sdim static ObjCMessageExpr *Create(const ASTContext &Context, QualType T, 1206218893Sdim ExprValueKind VK, 1207207619Srdivacky SourceLocation LBracLoc, 1208207619Srdivacky Expr *Receiver, 1209341825Sdim Selector Sel, 1210226633Sdim ArrayRef<SourceLocation> SeLocs, 1211207619Srdivacky ObjCMethodDecl *Method, 1212226633Sdim ArrayRef<Expr *> Args, 1213234353Sdim SourceLocation RBracLoc, 1214234353Sdim bool isImplicit); 1215198092Srdivacky 1216341825Sdim /// Create an empty Objective-C message expression, to be 1217207619Srdivacky /// filled in by subsequent calls. 1218207619Srdivacky /// 1219207619Srdivacky /// \param Context The context in which the message send will be created. 1220207619Srdivacky /// 1221207619Srdivacky /// \param NumArgs The number of message arguments, not including 1222207619Srdivacky /// the receiver. 1223261991Sdim static ObjCMessageExpr *CreateEmpty(const ASTContext &Context, 1224226633Sdim unsigned NumArgs, 1225226633Sdim unsigned NumStoredSelLocs); 1226198092Srdivacky 1227341825Sdim /// Indicates whether the message send was implicitly 1228234353Sdim /// generated by the implementation. If false, it was written explicitly 1229234353Sdim /// in the source code. 1230234353Sdim bool isImplicit() const { return IsImplicit; } 1231234353Sdim 1232341825Sdim /// Determine the kind of receiver that this message is being 1233207619Srdivacky /// sent to. 1234207619Srdivacky ReceiverKind getReceiverKind() const { return (ReceiverKind)Kind; } 1235207619Srdivacky 1236353358Sdim /// \return the return type of the message being sent. 1237353358Sdim /// This is not always the type of the message expression itself because 1238353358Sdim /// of references (the expression would not have a reference type). 1239353358Sdim /// It is also not always the declared return type of the method because 1240353358Sdim /// of `instancetype` (in that case it's an expression type). 1241353358Sdim QualType getCallReturnType(ASTContext &Ctx) const; 1242353358Sdim 1243341825Sdim /// Source range of the receiver. 1244218893Sdim SourceRange getReceiverRange() const; 1245218893Sdim 1246341825Sdim /// Determine whether this is an instance message to either a 1247207619Srdivacky /// computed object or to super. 1248207619Srdivacky bool isInstanceMessage() const { 1249207619Srdivacky return getReceiverKind() == Instance || getReceiverKind() == SuperInstance; 1250198092Srdivacky } 1251207619Srdivacky 1252341825Sdim /// Determine whether this is an class message to either a 1253207619Srdivacky /// specified class or to super. 1254207619Srdivacky bool isClassMessage() const { 1255207619Srdivacky return getReceiverKind() == Class || getReceiverKind() == SuperClass; 1256193326Sed } 1257198092Srdivacky 1258341825Sdim /// Returns the object expression (receiver) for an instance message, 1259243830Sdim /// or null for a message that is not an instance message. 1260207619Srdivacky Expr *getInstanceReceiver() { 1261207619Srdivacky if (getReceiverKind() == Instance) 1262207619Srdivacky return static_cast<Expr *>(getReceiverPointer()); 1263198092Srdivacky 1264276479Sdim return nullptr; 1265207619Srdivacky } 1266207619Srdivacky const Expr *getInstanceReceiver() const { 1267207619Srdivacky return const_cast<ObjCMessageExpr*>(this)->getInstanceReceiver(); 1268207619Srdivacky } 1269198092Srdivacky 1270341825Sdim /// Turn this message send into an instance message that 1271207619Srdivacky /// computes the receiver object with the given expression. 1272341825Sdim void setInstanceReceiver(Expr *rec) { 1273207619Srdivacky Kind = Instance; 1274207619Srdivacky setReceiverPointer(rec); 1275207619Srdivacky } 1276341825Sdim 1277341825Sdim /// Returns the type of a class message send, or NULL if the 1278207619Srdivacky /// message is not a class message. 1279341825Sdim QualType getClassReceiver() const { 1280207619Srdivacky if (TypeSourceInfo *TSInfo = getClassReceiverTypeInfo()) 1281207619Srdivacky return TSInfo->getType(); 1282204962Srdivacky 1283327952Sdim return {}; 1284207619Srdivacky } 1285204962Srdivacky 1286341825Sdim /// Returns a type-source information of a class message 1287327952Sdim /// send, or nullptr if the message is not a class message. 1288207619Srdivacky TypeSourceInfo *getClassReceiverTypeInfo() const { 1289207619Srdivacky if (getReceiverKind() == Class) 1290207619Srdivacky return reinterpret_cast<TypeSourceInfo *>(getReceiverPointer()); 1291276479Sdim return nullptr; 1292207619Srdivacky } 1293204962Srdivacky 1294207619Srdivacky void setClassReceiver(TypeSourceInfo *TSInfo) { 1295207619Srdivacky Kind = Class; 1296207619Srdivacky setReceiverPointer(TSInfo); 1297207619Srdivacky } 1298204962Srdivacky 1299341825Sdim /// Retrieve the location of the 'super' keyword for a class 1300207619Srdivacky /// or instance message to 'super', otherwise an invalid source location. 1301341825Sdim SourceLocation getSuperLoc() const { 1302207619Srdivacky if (getReceiverKind() == SuperInstance || getReceiverKind() == SuperClass) 1303207619Srdivacky return SuperLoc; 1304198092Srdivacky 1305207619Srdivacky return SourceLocation(); 1306193326Sed } 1307198092Srdivacky 1308341825Sdim /// Retrieve the receiver type to which this message is being directed. 1309243830Sdim /// 1310243830Sdim /// This routine cross-cuts all of the different kinds of message 1311243830Sdim /// sends to determine what the underlying (statically known) type 1312243830Sdim /// of the receiver will be; use \c getReceiverKind() to determine 1313243830Sdim /// whether the message is a class or an instance method, whether it 1314243830Sdim /// is a send to super or not, etc. 1315243830Sdim /// 1316243830Sdim /// \returns The type of the receiver. 1317243830Sdim QualType getReceiverType() const; 1318243830Sdim 1319341825Sdim /// Retrieve the Objective-C interface to which this message 1320207619Srdivacky /// is being directed, if known. 1321207619Srdivacky /// 1322207619Srdivacky /// This routine cross-cuts all of the different kinds of message 1323207619Srdivacky /// sends to determine what the underlying (statically known) type 1324207619Srdivacky /// of the receiver will be; use \c getReceiverKind() to determine 1325207619Srdivacky /// whether the message is a class or an instance method, whether it 1326207619Srdivacky /// is a send to super or not, etc. 1327207619Srdivacky /// 1328327952Sdim /// \returns The Objective-C interface if known, otherwise nullptr. 1329207619Srdivacky ObjCInterfaceDecl *getReceiverInterface() const; 1330207619Srdivacky 1331341825Sdim /// Retrieve the type referred to by 'super'. 1332207619Srdivacky /// 1333207619Srdivacky /// The returned type will either be an ObjCInterfaceType (for an 1334207619Srdivacky /// class message to super) or an ObjCObjectPointerType that refers 1335207619Srdivacky /// to a class (for an instance message to super); 1336207619Srdivacky QualType getSuperType() const { 1337207619Srdivacky if (getReceiverKind() == SuperInstance || getReceiverKind() == SuperClass) 1338207619Srdivacky return QualType::getFromOpaquePtr(getReceiverPointer()); 1339207619Srdivacky 1340207619Srdivacky return QualType(); 1341207619Srdivacky } 1342207619Srdivacky 1343207619Srdivacky void setSuper(SourceLocation Loc, QualType T, bool IsInstanceSuper) { 1344207619Srdivacky Kind = IsInstanceSuper? SuperInstance : SuperClass; 1345207619Srdivacky SuperLoc = Loc; 1346207619Srdivacky setReceiverPointer(T.getAsOpaquePtr()); 1347207619Srdivacky } 1348207619Srdivacky 1349207619Srdivacky Selector getSelector() const; 1350207619Srdivacky 1351341825Sdim void setSelector(Selector S) { 1352207619Srdivacky HasMethod = false; 1353207619Srdivacky SelectorOrMethod = reinterpret_cast<uintptr_t>(S.getAsOpaquePtr()); 1354207619Srdivacky } 1355207619Srdivacky 1356341825Sdim const ObjCMethodDecl *getMethodDecl() const { 1357207619Srdivacky if (HasMethod) 1358207619Srdivacky return reinterpret_cast<const ObjCMethodDecl *>(SelectorOrMethod); 1359207619Srdivacky 1360276479Sdim return nullptr; 1361207619Srdivacky } 1362207619Srdivacky 1363341825Sdim ObjCMethodDecl *getMethodDecl() { 1364207619Srdivacky if (HasMethod) 1365207619Srdivacky return reinterpret_cast<ObjCMethodDecl *>(SelectorOrMethod); 1366207619Srdivacky 1367276479Sdim return nullptr; 1368207619Srdivacky } 1369207619Srdivacky 1370341825Sdim void setMethodDecl(ObjCMethodDecl *MD) { 1371207619Srdivacky HasMethod = true; 1372207619Srdivacky SelectorOrMethod = reinterpret_cast<uintptr_t>(MD); 1373207619Srdivacky } 1374207619Srdivacky 1375221345Sdim ObjCMethodFamily getMethodFamily() const { 1376221345Sdim if (HasMethod) return getMethodDecl()->getMethodFamily(); 1377221345Sdim return getSelector().getMethodFamily(); 1378221345Sdim } 1379221345Sdim 1380341825Sdim /// Return the number of actual arguments in this message, 1381207619Srdivacky /// not counting the receiver. 1382193326Sed unsigned getNumArgs() const { return NumArgs; } 1383207619Srdivacky 1384341825Sdim /// Retrieve the arguments to this message, not including the 1385207619Srdivacky /// receiver. 1386218893Sdim Expr **getArgs() { 1387296417Sdim return reinterpret_cast<Expr **>(getTrailingObjects<void *>() + 1); 1388193326Sed } 1389218893Sdim const Expr * const *getArgs() const { 1390296417Sdim return reinterpret_cast<const Expr *const *>(getTrailingObjects<void *>() + 1391296417Sdim 1); 1392207619Srdivacky } 1393198092Srdivacky 1394193326Sed /// getArg - Return the specified argument. 1395193326Sed Expr *getArg(unsigned Arg) { 1396193326Sed assert(Arg < NumArgs && "Arg access out of range!"); 1397296417Sdim return getArgs()[Arg]; 1398193326Sed } 1399193326Sed const Expr *getArg(unsigned Arg) const { 1400193326Sed assert(Arg < NumArgs && "Arg access out of range!"); 1401296417Sdim return getArgs()[Arg]; 1402193326Sed } 1403327952Sdim 1404193326Sed /// setArg - Set the specified argument. 1405193326Sed void setArg(unsigned Arg, Expr *ArgExpr) { 1406193326Sed assert(Arg < NumArgs && "Arg access out of range!"); 1407207619Srdivacky getArgs()[Arg] = ArgExpr; 1408193326Sed } 1409198092Srdivacky 1410224145Sdim /// isDelegateInitCall - Answers whether this message send has been 1411224145Sdim /// tagged as a "delegate init call", i.e. a call to a method in the 1412224145Sdim /// -init family on self from within an -init method implementation. 1413224145Sdim bool isDelegateInitCall() const { return IsDelegateInitCall; } 1414224145Sdim void setDelegateInitCall(bool isDelegate) { IsDelegateInitCall = isDelegate; } 1415224145Sdim 1416207619Srdivacky SourceLocation getLeftLoc() const { return LBracLoc; } 1417207619Srdivacky SourceLocation getRightLoc() const { return RBracLoc; } 1418193326Sed 1419234353Sdim SourceLocation getSelectorStartLoc() const { 1420234353Sdim if (isImplicit()) 1421344779Sdim return getBeginLoc(); 1422234353Sdim return getSelectorLoc(0); 1423234353Sdim } 1424327952Sdim 1425226633Sdim SourceLocation getSelectorLoc(unsigned Index) const { 1426226633Sdim assert(Index < getNumSelectorLocs() && "Index out of range!"); 1427226633Sdim if (hasStandardSelLocs()) 1428226633Sdim return getStandardSelectorLoc(Index, getSelector(), 1429226633Sdim getSelLocsKind() == SelLoc_StandardWithSpace, 1430226633Sdim llvm::makeArrayRef(const_cast<Expr**>(getArgs()), 1431226633Sdim getNumArgs()), 1432226633Sdim RBracLoc); 1433226633Sdim return getStoredSelLocs()[Index]; 1434226633Sdim } 1435226633Sdim 1436226633Sdim void getSelectorLocs(SmallVectorImpl<SourceLocation> &SelLocs) const; 1437226633Sdim 1438226633Sdim unsigned getNumSelectorLocs() const { 1439234353Sdim if (isImplicit()) 1440234353Sdim return 0; 1441226633Sdim Selector Sel = getSelector(); 1442226633Sdim if (Sel.isUnarySelector()) 1443226633Sdim return 1; 1444226633Sdim return Sel.getNumArgs(); 1445226633Sdim } 1446226633Sdim 1447193326Sed void setSourceRange(SourceRange R) { 1448207619Srdivacky LBracLoc = R.getBegin(); 1449207619Srdivacky RBracLoc = R.getEnd(); 1450193326Sed } 1451327952Sdim 1452341825Sdim SourceLocation getBeginLoc() const LLVM_READONLY { return LBracLoc; } 1453341825Sdim SourceLocation getEndLoc() const LLVM_READONLY { return RBracLoc; } 1454193326Sed 1455193326Sed // Iterators 1456218893Sdim child_range children(); 1457198092Srdivacky 1458353358Sdim const_child_range children() const; 1459353358Sdim 1460327952Sdim using arg_iterator = ExprIterator; 1461327952Sdim using const_arg_iterator = ConstExprIterator; 1462198092Srdivacky 1463296417Sdim llvm::iterator_range<arg_iterator> arguments() { 1464296417Sdim return llvm::make_range(arg_begin(), arg_end()); 1465296417Sdim } 1466296417Sdim 1467296417Sdim llvm::iterator_range<const_arg_iterator> arguments() const { 1468296417Sdim return llvm::make_range(arg_begin(), arg_end()); 1469296417Sdim } 1470296417Sdim 1471218893Sdim arg_iterator arg_begin() { return reinterpret_cast<Stmt **>(getArgs()); } 1472327952Sdim 1473341825Sdim arg_iterator arg_end() { 1474341825Sdim return reinterpret_cast<Stmt **>(getArgs() + NumArgs); 1475193326Sed } 1476327952Sdim 1477341825Sdim const_arg_iterator arg_begin() const { 1478341825Sdim return reinterpret_cast<Stmt const * const*>(getArgs()); 1479218893Sdim } 1480327952Sdim 1481341825Sdim const_arg_iterator arg_end() const { 1482341825Sdim return reinterpret_cast<Stmt const * const*>(getArgs() + NumArgs); 1483218893Sdim } 1484193326Sed 1485327952Sdim static bool classof(const Stmt *T) { 1486327952Sdim return T->getStmtClass() == ObjCMessageExprClass; 1487327952Sdim } 1488193326Sed}; 1489193326Sed 1490198092Srdivacky/// ObjCIsaExpr - Represent X->isa and X.isa when X is an ObjC 'id' type. 1491221345Sdim/// (similar in spirit to MemberExpr). 1492198092Srdivackyclass ObjCIsaExpr : public Expr { 1493198092Srdivacky /// Base - the expression for the base object pointer. 1494198092Srdivacky Stmt *Base; 1495198092Srdivacky 1496198092Srdivacky /// IsaMemberLoc - This is the location of the 'isa'. 1497198092Srdivacky SourceLocation IsaMemberLoc; 1498341825Sdim 1499249423Sdim /// OpLoc - This is the location of '.' or '->' 1500249423Sdim SourceLocation OpLoc; 1501198092Srdivacky 1502198092Srdivacky /// IsArrow - True if this is "X->F", false if this is "X.F". 1503198092Srdivacky bool IsArrow; 1504327952Sdim 1505198092Srdivackypublic: 1506249423Sdim ObjCIsaExpr(Expr *base, bool isarrow, SourceLocation l, SourceLocation oploc, 1507249423Sdim QualType ty) 1508327952Sdim : Expr(ObjCIsaExprClass, ty, VK_LValue, OK_Ordinary, 1509327952Sdim /*TypeDependent=*/false, base->isValueDependent(), 1510327952Sdim base->isInstantiationDependent(), 1511327952Sdim /*ContainsUnexpandedParameterPack=*/false), 1512327952Sdim Base(base), IsaMemberLoc(l), OpLoc(oploc), IsArrow(isarrow) {} 1513198092Srdivacky 1514341825Sdim /// Build an empty expression. 1515327952Sdim explicit ObjCIsaExpr(EmptyShell Empty) : Expr(ObjCIsaExprClass, Empty) {} 1516198092Srdivacky 1517198092Srdivacky void setBase(Expr *E) { Base = E; } 1518198092Srdivacky Expr *getBase() const { return cast<Expr>(Base); } 1519198092Srdivacky 1520198092Srdivacky bool isArrow() const { return IsArrow; } 1521198092Srdivacky void setArrow(bool A) { IsArrow = A; } 1522198092Srdivacky 1523198092Srdivacky /// getMemberLoc - Return the location of the "member", in X->F, it is the 1524198092Srdivacky /// location of 'F'. 1525198092Srdivacky SourceLocation getIsaMemberLoc() const { return IsaMemberLoc; } 1526198092Srdivacky void setIsaMemberLoc(SourceLocation L) { IsaMemberLoc = L; } 1527341825Sdim 1528249423Sdim SourceLocation getOpLoc() const { return OpLoc; } 1529249423Sdim void setOpLoc(SourceLocation L) { OpLoc = L; } 1530198092Srdivacky 1531341825Sdim SourceLocation getBeginLoc() const LLVM_READONLY { 1532344779Sdim return getBase()->getBeginLoc(); 1533198092Srdivacky } 1534341825Sdim 1535249423Sdim SourceLocation getBaseLocEnd() const LLVM_READONLY { 1536344779Sdim return getBase()->getEndLoc(); 1537249423Sdim } 1538198092Srdivacky 1539341825Sdim SourceLocation getEndLoc() const LLVM_READONLY { return IsaMemberLoc; } 1540341825Sdim 1541234353Sdim SourceLocation getExprLoc() const LLVM_READONLY { return IsaMemberLoc; } 1542198092Srdivacky 1543327952Sdim // Iterators 1544327952Sdim child_range children() { return child_range(&Base, &Base+1); } 1545327952Sdim 1546353358Sdim const_child_range children() const { 1547353358Sdim return const_child_range(&Base, &Base + 1); 1548353358Sdim } 1549353358Sdim 1550198092Srdivacky static bool classof(const Stmt *T) { 1551198092Srdivacky return T->getStmtClass() == ObjCIsaExprClass; 1552198092Srdivacky } 1553198092Srdivacky}; 1554198092Srdivacky 1555224145Sdim/// ObjCIndirectCopyRestoreExpr - Represents the passing of a function 1556224145Sdim/// argument by indirect copy-restore in ARC. This is used to support 1557224145Sdim/// passing indirect arguments with the wrong lifetime, e.g. when 1558224145Sdim/// passing the address of a __strong local variable to an 'out' 1559224145Sdim/// parameter. This expression kind is only valid in an "argument" 1560224145Sdim/// position to some sort of call expression. 1561224145Sdim/// 1562224145Sdim/// The parameter must have type 'pointer to T', and the argument must 1563224145Sdim/// have type 'pointer to U', where T and U agree except possibly in 1564224145Sdim/// qualification. If the argument value is null, then a null pointer 1565224145Sdim/// is passed; otherwise it points to an object A, and: 1566224145Sdim/// 1. A temporary object B of type T is initialized, either by 1567224145Sdim/// zero-initialization (used when initializing an 'out' parameter) 1568224145Sdim/// or copy-initialization (used when initializing an 'inout' 1569224145Sdim/// parameter). 1570224145Sdim/// 2. The address of the temporary is passed to the function. 1571224145Sdim/// 3. If the call completes normally, A is move-assigned from B. 1572224145Sdim/// 4. Finally, A is destroyed immediately. 1573224145Sdim/// 1574224145Sdim/// Currently 'T' must be a retainable object lifetime and must be 1575224145Sdim/// __autoreleasing; this qualifier is ignored when initializing 1576224145Sdim/// the value. 1577224145Sdimclass ObjCIndirectCopyRestoreExpr : public Expr { 1578327952Sdim friend class ASTReader; 1579327952Sdim friend class ASTStmtReader; 1580327952Sdim 1581224145Sdim Stmt *Operand; 1582224145Sdim 1583224145Sdim // unsigned ObjCIndirectCopyRestoreBits.ShouldCopy : 1; 1584224145Sdim 1585327952Sdim explicit ObjCIndirectCopyRestoreExpr(EmptyShell Empty) 1586327952Sdim : Expr(ObjCIndirectCopyRestoreExprClass, Empty) {} 1587224145Sdim 1588224145Sdim void setShouldCopy(bool shouldCopy) { 1589224145Sdim ObjCIndirectCopyRestoreExprBits.ShouldCopy = shouldCopy; 1590224145Sdim } 1591224145Sdim 1592224145Sdimpublic: 1593224145Sdim ObjCIndirectCopyRestoreExpr(Expr *operand, QualType type, bool shouldCopy) 1594327952Sdim : Expr(ObjCIndirectCopyRestoreExprClass, type, VK_LValue, OK_Ordinary, 1595327952Sdim operand->isTypeDependent(), operand->isValueDependent(), 1596327952Sdim operand->isInstantiationDependent(), 1597327952Sdim operand->containsUnexpandedParameterPack()), 1598327952Sdim Operand(operand) { 1599224145Sdim setShouldCopy(shouldCopy); 1600224145Sdim } 1601224145Sdim 1602224145Sdim Expr *getSubExpr() { return cast<Expr>(Operand); } 1603224145Sdim const Expr *getSubExpr() const { return cast<Expr>(Operand); } 1604224145Sdim 1605224145Sdim /// shouldCopy - True if we should do the 'copy' part of the 1606224145Sdim /// copy-restore. If false, the temporary will be zero-initialized. 1607224145Sdim bool shouldCopy() const { return ObjCIndirectCopyRestoreExprBits.ShouldCopy; } 1608224145Sdim 1609341825Sdim child_range children() { return child_range(&Operand, &Operand+1); } 1610224145Sdim 1611353358Sdim const_child_range children() const { 1612353358Sdim return const_child_range(&Operand, &Operand + 1); 1613353358Sdim } 1614353358Sdim 1615224145Sdim // Source locations are determined by the subexpression. 1616341825Sdim SourceLocation getBeginLoc() const LLVM_READONLY { 1617344779Sdim return Operand->getBeginLoc(); 1618234353Sdim } 1619341825Sdim SourceLocation getEndLoc() const LLVM_READONLY { 1620344779Sdim return Operand->getEndLoc(); 1621341825Sdim } 1622249423Sdim 1623234353Sdim SourceLocation getExprLoc() const LLVM_READONLY { 1624234353Sdim return getSubExpr()->getExprLoc(); 1625234353Sdim } 1626224145Sdim 1627224145Sdim static bool classof(const Stmt *s) { 1628224145Sdim return s->getStmtClass() == ObjCIndirectCopyRestoreExprClass; 1629224145Sdim } 1630224145Sdim}; 1631224145Sdim 1632341825Sdim/// An Objective-C "bridged" cast expression, which casts between 1633224145Sdim/// Objective-C pointers and C pointers, transferring ownership in the process. 1634224145Sdim/// 1635224145Sdim/// \code 1636224145Sdim/// NSString *str = (__bridge_transfer NSString *)CFCreateString(); 1637224145Sdim/// \endcode 1638296417Sdimclass ObjCBridgedCastExpr final 1639296417Sdim : public ExplicitCastExpr, 1640344779Sdim private llvm::TrailingObjects<ObjCBridgedCastExpr, CXXBaseSpecifier *> { 1641327952Sdim friend class ASTStmtReader; 1642327952Sdim friend class ASTStmtWriter; 1643327952Sdim friend class CastExpr; 1644327952Sdim friend TrailingObjects; 1645327952Sdim 1646224145Sdim SourceLocation LParenLoc; 1647224145Sdim SourceLocation BridgeKeywordLoc; 1648224145Sdim unsigned Kind : 2; 1649296417Sdim 1650224145Sdimpublic: 1651224145Sdim ObjCBridgedCastExpr(SourceLocation LParenLoc, ObjCBridgeCastKind Kind, 1652226633Sdim CastKind CK, SourceLocation BridgeKeywordLoc, 1653226633Sdim TypeSourceInfo *TSInfo, Expr *Operand) 1654327952Sdim : ExplicitCastExpr(ObjCBridgedCastExprClass, TSInfo->getType(), VK_RValue, 1655327952Sdim CK, Operand, 0, TSInfo), 1656327952Sdim LParenLoc(LParenLoc), BridgeKeywordLoc(BridgeKeywordLoc), Kind(Kind) {} 1657341825Sdim 1658341825Sdim /// Construct an empty Objective-C bridged cast. 1659224145Sdim explicit ObjCBridgedCastExpr(EmptyShell Shell) 1660327952Sdim : ExplicitCastExpr(ObjCBridgedCastExprClass, Shell, 0) {} 1661224145Sdim 1662224145Sdim SourceLocation getLParenLoc() const { return LParenLoc; } 1663224145Sdim 1664341825Sdim /// Determine which kind of bridge is being performed via this cast. 1665341825Sdim ObjCBridgeCastKind getBridgeKind() const { 1666341825Sdim return static_cast<ObjCBridgeCastKind>(Kind); 1667224145Sdim } 1668341825Sdim 1669341825Sdim /// Retrieve the kind of bridge being performed as a string. 1670226633Sdim StringRef getBridgeKindName() const; 1671341825Sdim 1672341825Sdim /// The location of the bridge keyword. 1673224145Sdim SourceLocation getBridgeKeywordLoc() const { return BridgeKeywordLoc; } 1674327952Sdim 1675341825Sdim SourceLocation getBeginLoc() const LLVM_READONLY { return LParenLoc; } 1676341825Sdim 1677341825Sdim SourceLocation getEndLoc() const LLVM_READONLY { 1678344779Sdim return getSubExpr()->getEndLoc(); 1679224145Sdim } 1680341825Sdim 1681224145Sdim static bool classof(const Stmt *T) { 1682224145Sdim return T->getStmtClass() == ObjCBridgedCastExprClass; 1683224145Sdim } 1684224145Sdim}; 1685309124Sdim 1686341825Sdim/// A runtime availability query. 1687309124Sdim/// 1688309124Sdim/// There are 2 ways to spell this node: 1689309124Sdim/// \code 1690309124Sdim/// @available(macos 10.10, ios 8, *); // Objective-C 1691309124Sdim/// __builtin_available(macos 10.10, ios 8, *); // C, C++, and Objective-C 1692309124Sdim/// \endcode 1693309124Sdim/// 1694309124Sdim/// Note that we only need to keep track of one \c VersionTuple here, which is 1695309124Sdim/// the one that corresponds to the current deployment target. This is meant to 1696309124Sdim/// be used in the condition of an \c if, but it is also usable as top level 1697309124Sdim/// expressions. 1698309124Sdim/// 1699309124Sdimclass ObjCAvailabilityCheckExpr : public Expr { 1700327952Sdim friend class ASTStmtReader; 1701327952Sdim 1702309124Sdim VersionTuple VersionToCheck; 1703309124Sdim SourceLocation AtLoc, RParen; 1704309124Sdim 1705309124Sdimpublic: 1706309124Sdim ObjCAvailabilityCheckExpr(VersionTuple VersionToCheck, SourceLocation AtLoc, 1707309124Sdim SourceLocation RParen, QualType Ty) 1708309124Sdim : Expr(ObjCAvailabilityCheckExprClass, Ty, VK_RValue, OK_Ordinary, false, 1709309124Sdim false, false, false), 1710309124Sdim VersionToCheck(VersionToCheck), AtLoc(AtLoc), RParen(RParen) {} 1711309124Sdim 1712309124Sdim explicit ObjCAvailabilityCheckExpr(EmptyShell Shell) 1713309124Sdim : Expr(ObjCAvailabilityCheckExprClass, Shell) {} 1714309124Sdim 1715341825Sdim SourceLocation getBeginLoc() const { return AtLoc; } 1716341825Sdim SourceLocation getEndLoc() const { return RParen; } 1717309124Sdim SourceRange getSourceRange() const { return {AtLoc, RParen}; } 1718309124Sdim 1719341825Sdim /// This may be '*', in which case this should fold to true. 1720309124Sdim bool hasVersion() const { return !VersionToCheck.empty(); } 1721309124Sdim VersionTuple getVersion() { return VersionToCheck; } 1722309124Sdim 1723309124Sdim child_range children() { 1724309124Sdim return child_range(child_iterator(), child_iterator()); 1725309124Sdim } 1726309124Sdim 1727353358Sdim const_child_range children() const { 1728353358Sdim return const_child_range(const_child_iterator(), const_child_iterator()); 1729353358Sdim } 1730353358Sdim 1731309124Sdim static bool classof(const Stmt *T) { 1732309124Sdim return T->getStmtClass() == ObjCAvailabilityCheckExprClass; 1733309124Sdim } 1734309124Sdim}; 1735309124Sdim 1736327952Sdim} // namespace clang 1737193326Sed 1738327952Sdim#endif // LLVM_CLANG_AST_EXPROBJC_H 1739