1 //===- ExprObjC.h - Classes for representing ObjC expressions ---*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file defines the ExprObjC interface and subclasses. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #ifndef LLVM_CLANG_AST_EXPROBJC_H 14 #define LLVM_CLANG_AST_EXPROBJC_H 15 16 #include "clang/AST/Decl.h" 17 #include "clang/AST/DeclObjC.h" 18 #include "clang/AST/Expr.h" 19 #include "clang/AST/OperationKinds.h" 20 #include "clang/AST/SelectorLocationsKind.h" 21 #include "clang/AST/Stmt.h" 22 #include "clang/AST/Type.h" 23 #include "clang/Basic/IdentifierTable.h" 24 #include "clang/Basic/LLVM.h" 25 #include "clang/Basic/SourceLocation.h" 26 #include "clang/Basic/Specifiers.h" 27 #include "llvm/ADT/ArrayRef.h" 28 #include "llvm/ADT/None.h" 29 #include "llvm/ADT/Optional.h" 30 #include "llvm/ADT/PointerIntPair.h" 31 #include "llvm/ADT/PointerUnion.h" 32 #include "llvm/ADT/StringRef.h" 33 #include "llvm/ADT/iterator_range.h" 34 #include "llvm/Support/Casting.h" 35 #include "llvm/Support/Compiler.h" 36 #include "llvm/Support/TrailingObjects.h" 37 #include "llvm/Support/VersionTuple.h" 38 #include "llvm/Support/type_traits.h" 39 #include <cassert> 40 #include <cstddef> 41 #include <cstdint> 42 43 namespace clang { 44 45 class ASTContext; 46 class CXXBaseSpecifier; 47 48 /// ObjCStringLiteral, used for Objective-C string literals 49 /// i.e. @"foo". 50 class ObjCStringLiteral : public Expr { 51 Stmt *String; 52 SourceLocation AtLoc; 53 54 public: ObjCStringLiteral(StringLiteral * SL,QualType T,SourceLocation L)55 ObjCStringLiteral(StringLiteral *SL, QualType T, SourceLocation L) 56 : Expr(ObjCStringLiteralClass, T, VK_RValue, OK_Ordinary, false, false, 57 false, false), 58 String(SL), AtLoc(L) {} ObjCStringLiteral(EmptyShell Empty)59 explicit ObjCStringLiteral(EmptyShell Empty) 60 : Expr(ObjCStringLiteralClass, Empty) {} 61 getString()62 StringLiteral *getString() { return cast<StringLiteral>(String); } getString()63 const StringLiteral *getString() const { return cast<StringLiteral>(String); } setString(StringLiteral * S)64 void setString(StringLiteral *S) { String = S; } 65 getAtLoc()66 SourceLocation getAtLoc() const { return AtLoc; } setAtLoc(SourceLocation L)67 void setAtLoc(SourceLocation L) { AtLoc = L; } 68 getBeginLoc()69 SourceLocation getBeginLoc() const LLVM_READONLY { return AtLoc; } getEndLoc()70 SourceLocation getEndLoc() const LLVM_READONLY { return String->getEndLoc(); } 71 72 // Iterators children()73 child_range children() { return child_range(&String, &String+1); } 74 children()75 const_child_range children() const { 76 return const_child_range(&String, &String + 1); 77 } 78 classof(const Stmt * T)79 static bool classof(const Stmt *T) { 80 return T->getStmtClass() == ObjCStringLiteralClass; 81 } 82 }; 83 84 /// ObjCBoolLiteralExpr - Objective-C Boolean Literal. 85 class ObjCBoolLiteralExpr : public Expr { 86 bool Value; 87 SourceLocation Loc; 88 89 public: ObjCBoolLiteralExpr(bool val,QualType Ty,SourceLocation l)90 ObjCBoolLiteralExpr(bool val, QualType Ty, SourceLocation l) 91 : Expr(ObjCBoolLiteralExprClass, Ty, VK_RValue, OK_Ordinary, false, false, 92 false, false), 93 Value(val), Loc(l) {} ObjCBoolLiteralExpr(EmptyShell Empty)94 explicit ObjCBoolLiteralExpr(EmptyShell Empty) 95 : Expr(ObjCBoolLiteralExprClass, Empty) {} 96 getValue()97 bool getValue() const { return Value; } setValue(bool V)98 void setValue(bool V) { Value = V; } 99 getBeginLoc()100 SourceLocation getBeginLoc() const LLVM_READONLY { return Loc; } getEndLoc()101 SourceLocation getEndLoc() const LLVM_READONLY { return Loc; } 102 getLocation()103 SourceLocation getLocation() const { return Loc; } setLocation(SourceLocation L)104 void setLocation(SourceLocation L) { Loc = L; } 105 106 // Iterators children()107 child_range children() { 108 return child_range(child_iterator(), child_iterator()); 109 } 110 children()111 const_child_range children() const { 112 return const_child_range(const_child_iterator(), const_child_iterator()); 113 } 114 classof(const Stmt * T)115 static bool classof(const Stmt *T) { 116 return T->getStmtClass() == ObjCBoolLiteralExprClass; 117 } 118 }; 119 120 /// ObjCBoxedExpr - used for generalized expression boxing. 121 /// as in: @(strdup("hello world")), @(random()) or @(view.frame) 122 /// Also used for boxing non-parenthesized numeric literals; 123 /// as in: @42 or \@true (c++/objc++) or \@__objc_yes (c/objc). 124 class ObjCBoxedExpr : public Expr { 125 Stmt *SubExpr; 126 ObjCMethodDecl *BoxingMethod; 127 SourceRange Range; 128 129 public: 130 friend class ASTStmtReader; 131 ObjCBoxedExpr(Expr * E,QualType T,ObjCMethodDecl * method,SourceRange R)132 ObjCBoxedExpr(Expr *E, QualType T, ObjCMethodDecl *method, 133 SourceRange R) 134 : Expr(ObjCBoxedExprClass, T, VK_RValue, OK_Ordinary, 135 E->isTypeDependent(), E->isValueDependent(), 136 E->isInstantiationDependent(), 137 E->containsUnexpandedParameterPack()), 138 SubExpr(E), BoxingMethod(method), Range(R) {} ObjCBoxedExpr(EmptyShell Empty)139 explicit ObjCBoxedExpr(EmptyShell Empty) 140 : Expr(ObjCBoxedExprClass, Empty) {} 141 getSubExpr()142 Expr *getSubExpr() { return cast<Expr>(SubExpr); } getSubExpr()143 const Expr *getSubExpr() const { return cast<Expr>(SubExpr); } 144 getBoxingMethod()145 ObjCMethodDecl *getBoxingMethod() const { 146 return BoxingMethod; 147 } 148 149 // Indicates whether this boxed expression can be emitted as a compile-time 150 // constant. isExpressibleAsConstantInitializer()151 bool isExpressibleAsConstantInitializer() const { 152 return !BoxingMethod && SubExpr; 153 } 154 getAtLoc()155 SourceLocation getAtLoc() const { return Range.getBegin(); } 156 getBeginLoc()157 SourceLocation getBeginLoc() const LLVM_READONLY { return Range.getBegin(); } getEndLoc()158 SourceLocation getEndLoc() const LLVM_READONLY { return Range.getEnd(); } 159 getSourceRange()160 SourceRange getSourceRange() const LLVM_READONLY { 161 return Range; 162 } 163 164 // Iterators children()165 child_range children() { return child_range(&SubExpr, &SubExpr+1); } 166 children()167 const_child_range children() const { 168 return const_child_range(&SubExpr, &SubExpr + 1); 169 } 170 171 using const_arg_iterator = ConstExprIterator; 172 arg_begin()173 const_arg_iterator arg_begin() const { 174 return reinterpret_cast<Stmt const * const*>(&SubExpr); 175 } 176 arg_end()177 const_arg_iterator arg_end() const { 178 return reinterpret_cast<Stmt const * const*>(&SubExpr + 1); 179 } 180 classof(const Stmt * T)181 static bool classof(const Stmt *T) { 182 return T->getStmtClass() == ObjCBoxedExprClass; 183 } 184 }; 185 186 /// ObjCArrayLiteral - used for objective-c array containers; as in: 187 /// @[@"Hello", NSApp, [NSNumber numberWithInt:42]]; 188 class ObjCArrayLiteral final 189 : public Expr, 190 private llvm::TrailingObjects<ObjCArrayLiteral, Expr *> { 191 unsigned NumElements; 192 SourceRange Range; 193 ObjCMethodDecl *ArrayWithObjectsMethod; 194 195 ObjCArrayLiteral(ArrayRef<Expr *> Elements, 196 QualType T, ObjCMethodDecl * Method, 197 SourceRange SR); 198 ObjCArrayLiteral(EmptyShell Empty,unsigned NumElements)199 explicit ObjCArrayLiteral(EmptyShell Empty, unsigned NumElements) 200 : Expr(ObjCArrayLiteralClass, Empty), NumElements(NumElements) {} 201 202 public: 203 friend class ASTStmtReader; 204 friend TrailingObjects; 205 206 static ObjCArrayLiteral *Create(const ASTContext &C, 207 ArrayRef<Expr *> Elements, 208 QualType T, ObjCMethodDecl * Method, 209 SourceRange SR); 210 211 static ObjCArrayLiteral *CreateEmpty(const ASTContext &C, 212 unsigned NumElements); 213 getBeginLoc()214 SourceLocation getBeginLoc() const LLVM_READONLY { return Range.getBegin(); } getEndLoc()215 SourceLocation getEndLoc() const LLVM_READONLY { return Range.getEnd(); } getSourceRange()216 SourceRange getSourceRange() const LLVM_READONLY { return Range; } 217 218 /// Retrieve elements of array of literals. getElements()219 Expr **getElements() { return getTrailingObjects<Expr *>(); } 220 221 /// Retrieve elements of array of literals. getElements()222 const Expr * const *getElements() const { 223 return getTrailingObjects<Expr *>(); 224 } 225 226 /// getNumElements - Return number of elements of objective-c array literal. getNumElements()227 unsigned getNumElements() const { return NumElements; } 228 229 /// getElement - Return the Element at the specified index. getElement(unsigned Index)230 Expr *getElement(unsigned Index) { 231 assert((Index < NumElements) && "Arg access out of range!"); 232 return getElements()[Index]; 233 } getElement(unsigned Index)234 const Expr *getElement(unsigned Index) const { 235 assert((Index < NumElements) && "Arg access out of range!"); 236 return getElements()[Index]; 237 } 238 getArrayWithObjectsMethod()239 ObjCMethodDecl *getArrayWithObjectsMethod() const { 240 return ArrayWithObjectsMethod; 241 } 242 243 // Iterators children()244 child_range children() { 245 return child_range(reinterpret_cast<Stmt **>(getElements()), 246 reinterpret_cast<Stmt **>(getElements()) + NumElements); 247 } 248 children()249 const_child_range children() const { 250 auto Children = const_cast<ObjCArrayLiteral *>(this)->children(); 251 return const_child_range(Children.begin(), Children.end()); 252 } 253 classof(const Stmt * T)254 static bool classof(const Stmt *T) { 255 return T->getStmtClass() == ObjCArrayLiteralClass; 256 } 257 }; 258 259 /// An element in an Objective-C dictionary literal. 260 /// 261 struct ObjCDictionaryElement { 262 /// The key for the dictionary element. 263 Expr *Key; 264 265 /// The value of the dictionary element. 266 Expr *Value; 267 268 /// The location of the ellipsis, if this is a pack expansion. 269 SourceLocation EllipsisLoc; 270 271 /// The number of elements this pack expansion will expand to, if 272 /// this is a pack expansion and is known. 273 Optional<unsigned> NumExpansions; 274 275 /// Determines whether this dictionary element is a pack expansion. isPackExpansionObjCDictionaryElement276 bool isPackExpansion() const { return EllipsisLoc.isValid(); } 277 }; 278 279 } // namespace clang 280 281 namespace clang { 282 283 /// Internal struct for storing Key/value pair. 284 struct ObjCDictionaryLiteral_KeyValuePair { 285 Expr *Key; 286 Expr *Value; 287 }; 288 289 /// Internal struct to describes an element that is a pack 290 /// expansion, used if any of the elements in the dictionary literal 291 /// are pack expansions. 292 struct ObjCDictionaryLiteral_ExpansionData { 293 /// The location of the ellipsis, if this element is a pack 294 /// expansion. 295 SourceLocation EllipsisLoc; 296 297 /// If non-zero, the number of elements that this pack 298 /// expansion will expand to (+1). 299 unsigned NumExpansionsPlusOne; 300 }; 301 302 /// ObjCDictionaryLiteral - AST node to represent objective-c dictionary 303 /// literals; as in: @{@"name" : NSUserName(), @"date" : [NSDate date] }; 304 class ObjCDictionaryLiteral final 305 : public Expr, 306 private llvm::TrailingObjects<ObjCDictionaryLiteral, 307 ObjCDictionaryLiteral_KeyValuePair, 308 ObjCDictionaryLiteral_ExpansionData> { 309 /// The number of elements in this dictionary literal. 310 unsigned NumElements : 31; 311 312 /// Determine whether this dictionary literal has any pack expansions. 313 /// 314 /// If the dictionary literal has pack expansions, then there will 315 /// be an array of pack expansion data following the array of 316 /// key/value pairs, which provide the locations of the ellipses (if 317 /// any) and number of elements in the expansion (if known). If 318 /// there are no pack expansions, we optimize away this storage. 319 unsigned HasPackExpansions : 1; 320 321 SourceRange Range; 322 ObjCMethodDecl *DictWithObjectsMethod; 323 324 using KeyValuePair = ObjCDictionaryLiteral_KeyValuePair; 325 using ExpansionData = ObjCDictionaryLiteral_ExpansionData; 326 327 ObjCDictionaryLiteral(ArrayRef<ObjCDictionaryElement> VK, 328 bool HasPackExpansions, 329 QualType T, ObjCMethodDecl *method, 330 SourceRange SR); 331 ObjCDictionaryLiteral(EmptyShell Empty,unsigned NumElements,bool HasPackExpansions)332 explicit ObjCDictionaryLiteral(EmptyShell Empty, unsigned NumElements, 333 bool HasPackExpansions) 334 : Expr(ObjCDictionaryLiteralClass, Empty), NumElements(NumElements), 335 HasPackExpansions(HasPackExpansions) {} 336 numTrailingObjects(OverloadToken<KeyValuePair>)337 size_t numTrailingObjects(OverloadToken<KeyValuePair>) const { 338 return NumElements; 339 } 340 341 public: 342 friend class ASTStmtReader; 343 friend class ASTStmtWriter; 344 friend TrailingObjects; 345 346 static ObjCDictionaryLiteral *Create(const ASTContext &C, 347 ArrayRef<ObjCDictionaryElement> VK, 348 bool HasPackExpansions, 349 QualType T, ObjCMethodDecl *method, 350 SourceRange SR); 351 352 static ObjCDictionaryLiteral *CreateEmpty(const ASTContext &C, 353 unsigned NumElements, 354 bool HasPackExpansions); 355 356 /// getNumElements - Return number of elements of objective-c dictionary 357 /// literal. getNumElements()358 unsigned getNumElements() const { return NumElements; } 359 getKeyValueElement(unsigned Index)360 ObjCDictionaryElement getKeyValueElement(unsigned Index) const { 361 assert((Index < NumElements) && "Arg access out of range!"); 362 const KeyValuePair &KV = getTrailingObjects<KeyValuePair>()[Index]; 363 ObjCDictionaryElement Result = { KV.Key, KV.Value, SourceLocation(), None }; 364 if (HasPackExpansions) { 365 const ExpansionData &Expansion = 366 getTrailingObjects<ExpansionData>()[Index]; 367 Result.EllipsisLoc = Expansion.EllipsisLoc; 368 if (Expansion.NumExpansionsPlusOne > 0) 369 Result.NumExpansions = Expansion.NumExpansionsPlusOne - 1; 370 } 371 return Result; 372 } 373 getDictWithObjectsMethod()374 ObjCMethodDecl *getDictWithObjectsMethod() const { 375 return DictWithObjectsMethod; 376 } 377 getBeginLoc()378 SourceLocation getBeginLoc() const LLVM_READONLY { return Range.getBegin(); } getEndLoc()379 SourceLocation getEndLoc() const LLVM_READONLY { return Range.getEnd(); } getSourceRange()380 SourceRange getSourceRange() const LLVM_READONLY { return Range; } 381 382 // Iterators children()383 child_range children() { 384 // Note: we're taking advantage of the layout of the KeyValuePair struct 385 // here. If that struct changes, this code will need to change as well. 386 static_assert(sizeof(KeyValuePair) == sizeof(Stmt *) * 2, 387 "KeyValuePair is expected size"); 388 return child_range( 389 reinterpret_cast<Stmt **>(getTrailingObjects<KeyValuePair>()), 390 reinterpret_cast<Stmt **>(getTrailingObjects<KeyValuePair>()) + 391 NumElements * 2); 392 } 393 children()394 const_child_range children() const { 395 auto Children = const_cast<ObjCDictionaryLiteral *>(this)->children(); 396 return const_child_range(Children.begin(), Children.end()); 397 } 398 classof(const Stmt * T)399 static bool classof(const Stmt *T) { 400 return T->getStmtClass() == ObjCDictionaryLiteralClass; 401 } 402 }; 403 404 /// ObjCEncodeExpr, used for \@encode in Objective-C. \@encode has the same 405 /// type and behavior as StringLiteral except that the string initializer is 406 /// obtained from ASTContext with the encoding type as an argument. 407 class ObjCEncodeExpr : public Expr { 408 TypeSourceInfo *EncodedType; 409 SourceLocation AtLoc, RParenLoc; 410 411 public: ObjCEncodeExpr(QualType T,TypeSourceInfo * EncodedType,SourceLocation at,SourceLocation rp)412 ObjCEncodeExpr(QualType T, TypeSourceInfo *EncodedType, 413 SourceLocation at, SourceLocation rp) 414 : Expr(ObjCEncodeExprClass, T, VK_LValue, OK_Ordinary, 415 EncodedType->getType()->isDependentType(), 416 EncodedType->getType()->isDependentType(), 417 EncodedType->getType()->isInstantiationDependentType(), 418 EncodedType->getType()->containsUnexpandedParameterPack()), 419 EncodedType(EncodedType), AtLoc(at), RParenLoc(rp) {} 420 ObjCEncodeExpr(EmptyShell Empty)421 explicit ObjCEncodeExpr(EmptyShell Empty) : Expr(ObjCEncodeExprClass, Empty){} 422 getAtLoc()423 SourceLocation getAtLoc() const { return AtLoc; } setAtLoc(SourceLocation L)424 void setAtLoc(SourceLocation L) { AtLoc = L; } getRParenLoc()425 SourceLocation getRParenLoc() const { return RParenLoc; } setRParenLoc(SourceLocation L)426 void setRParenLoc(SourceLocation L) { RParenLoc = L; } 427 getEncodedType()428 QualType getEncodedType() const { return EncodedType->getType(); } 429 getEncodedTypeSourceInfo()430 TypeSourceInfo *getEncodedTypeSourceInfo() const { return EncodedType; } 431 setEncodedTypeSourceInfo(TypeSourceInfo * EncType)432 void setEncodedTypeSourceInfo(TypeSourceInfo *EncType) { 433 EncodedType = EncType; 434 } 435 getBeginLoc()436 SourceLocation getBeginLoc() const LLVM_READONLY { return AtLoc; } getEndLoc()437 SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; } 438 439 // Iterators children()440 child_range children() { 441 return child_range(child_iterator(), child_iterator()); 442 } 443 children()444 const_child_range children() const { 445 return const_child_range(const_child_iterator(), const_child_iterator()); 446 } 447 classof(const Stmt * T)448 static bool classof(const Stmt *T) { 449 return T->getStmtClass() == ObjCEncodeExprClass; 450 } 451 }; 452 453 /// ObjCSelectorExpr used for \@selector in Objective-C. 454 class ObjCSelectorExpr : public Expr { 455 Selector SelName; 456 SourceLocation AtLoc, RParenLoc; 457 458 public: ObjCSelectorExpr(QualType T,Selector selInfo,SourceLocation at,SourceLocation rp)459 ObjCSelectorExpr(QualType T, Selector selInfo, 460 SourceLocation at, SourceLocation rp) 461 : Expr(ObjCSelectorExprClass, T, VK_RValue, OK_Ordinary, false, false, 462 false, false), 463 SelName(selInfo), AtLoc(at), RParenLoc(rp) {} ObjCSelectorExpr(EmptyShell Empty)464 explicit ObjCSelectorExpr(EmptyShell Empty) 465 : Expr(ObjCSelectorExprClass, Empty) {} 466 getSelector()467 Selector getSelector() const { return SelName; } setSelector(Selector S)468 void setSelector(Selector S) { SelName = S; } 469 getAtLoc()470 SourceLocation getAtLoc() const { return AtLoc; } getRParenLoc()471 SourceLocation getRParenLoc() const { return RParenLoc; } setAtLoc(SourceLocation L)472 void setAtLoc(SourceLocation L) { AtLoc = L; } setRParenLoc(SourceLocation L)473 void setRParenLoc(SourceLocation L) { RParenLoc = L; } 474 getBeginLoc()475 SourceLocation getBeginLoc() const LLVM_READONLY { return AtLoc; } getEndLoc()476 SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; } 477 478 /// getNumArgs - Return the number of actual arguments to this call. getNumArgs()479 unsigned getNumArgs() const { return SelName.getNumArgs(); } 480 481 // Iterators children()482 child_range children() { 483 return child_range(child_iterator(), child_iterator()); 484 } 485 children()486 const_child_range children() const { 487 return const_child_range(const_child_iterator(), const_child_iterator()); 488 } 489 classof(const Stmt * T)490 static bool classof(const Stmt *T) { 491 return T->getStmtClass() == ObjCSelectorExprClass; 492 } 493 }; 494 495 /// ObjCProtocolExpr used for protocol expression in Objective-C. 496 /// 497 /// This is used as: \@protocol(foo), as in: 498 /// \code 499 /// [obj conformsToProtocol:@protocol(foo)] 500 /// \endcode 501 /// 502 /// The return type is "Protocol*". 503 class ObjCProtocolExpr : public Expr { 504 ObjCProtocolDecl *TheProtocol; 505 SourceLocation AtLoc, ProtoLoc, RParenLoc; 506 507 public: 508 friend class ASTStmtReader; 509 friend class ASTStmtWriter; 510 ObjCProtocolExpr(QualType T,ObjCProtocolDecl * protocol,SourceLocation at,SourceLocation protoLoc,SourceLocation rp)511 ObjCProtocolExpr(QualType T, ObjCProtocolDecl *protocol, 512 SourceLocation at, SourceLocation protoLoc, SourceLocation rp) 513 : Expr(ObjCProtocolExprClass, T, VK_RValue, OK_Ordinary, false, false, 514 false, false), 515 TheProtocol(protocol), AtLoc(at), ProtoLoc(protoLoc), RParenLoc(rp) {} ObjCProtocolExpr(EmptyShell Empty)516 explicit ObjCProtocolExpr(EmptyShell Empty) 517 : Expr(ObjCProtocolExprClass, Empty) {} 518 getProtocol()519 ObjCProtocolDecl *getProtocol() const { return TheProtocol; } setProtocol(ObjCProtocolDecl * P)520 void setProtocol(ObjCProtocolDecl *P) { TheProtocol = P; } 521 getProtocolIdLoc()522 SourceLocation getProtocolIdLoc() const { return ProtoLoc; } getAtLoc()523 SourceLocation getAtLoc() const { return AtLoc; } getRParenLoc()524 SourceLocation getRParenLoc() const { return RParenLoc; } setAtLoc(SourceLocation L)525 void setAtLoc(SourceLocation L) { AtLoc = L; } setRParenLoc(SourceLocation L)526 void setRParenLoc(SourceLocation L) { RParenLoc = L; } 527 getBeginLoc()528 SourceLocation getBeginLoc() const LLVM_READONLY { return AtLoc; } getEndLoc()529 SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; } 530 531 // Iterators children()532 child_range children() { 533 return child_range(child_iterator(), child_iterator()); 534 } 535 children()536 const_child_range children() const { 537 return const_child_range(const_child_iterator(), const_child_iterator()); 538 } 539 classof(const Stmt * T)540 static bool classof(const Stmt *T) { 541 return T->getStmtClass() == ObjCProtocolExprClass; 542 } 543 }; 544 545 /// ObjCIvarRefExpr - A reference to an ObjC instance variable. 546 class ObjCIvarRefExpr : public Expr { 547 ObjCIvarDecl *D; 548 Stmt *Base; 549 SourceLocation Loc; 550 551 /// OpLoc - This is the location of '.' or '->' 552 SourceLocation OpLoc; 553 554 // True if this is "X->F", false if this is "X.F". 555 bool IsArrow : 1; 556 557 // True if ivar reference has no base (self assumed). 558 bool IsFreeIvar : 1; 559 560 public: 561 ObjCIvarRefExpr(ObjCIvarDecl *d, QualType t, 562 SourceLocation l, SourceLocation oploc, 563 Expr *base, 564 bool arrow = false, bool freeIvar = false) 565 : Expr(ObjCIvarRefExprClass, t, VK_LValue, 566 d->isBitField() ? OK_BitField : OK_Ordinary, 567 /*TypeDependent=*/false, base->isValueDependent(), 568 base->isInstantiationDependent(), 569 base->containsUnexpandedParameterPack()), 570 D(d), Base(base), Loc(l), OpLoc(oploc), IsArrow(arrow), 571 IsFreeIvar(freeIvar) {} 572 ObjCIvarRefExpr(EmptyShell Empty)573 explicit ObjCIvarRefExpr(EmptyShell Empty) 574 : Expr(ObjCIvarRefExprClass, Empty) {} 575 getDecl()576 ObjCIvarDecl *getDecl() { return D; } getDecl()577 const ObjCIvarDecl *getDecl() const { return D; } setDecl(ObjCIvarDecl * d)578 void setDecl(ObjCIvarDecl *d) { D = d; } 579 getBase()580 const Expr *getBase() const { return cast<Expr>(Base); } getBase()581 Expr *getBase() { return cast<Expr>(Base); } setBase(Expr * base)582 void setBase(Expr * base) { Base = base; } 583 isArrow()584 bool isArrow() const { return IsArrow; } isFreeIvar()585 bool isFreeIvar() const { return IsFreeIvar; } setIsArrow(bool A)586 void setIsArrow(bool A) { IsArrow = A; } setIsFreeIvar(bool A)587 void setIsFreeIvar(bool A) { IsFreeIvar = A; } 588 getLocation()589 SourceLocation getLocation() const { return Loc; } setLocation(SourceLocation L)590 void setLocation(SourceLocation L) { Loc = L; } 591 getBeginLoc()592 SourceLocation getBeginLoc() const LLVM_READONLY { 593 return isFreeIvar() ? Loc : getBase()->getBeginLoc(); 594 } getEndLoc()595 SourceLocation getEndLoc() const LLVM_READONLY { return Loc; } 596 getOpLoc()597 SourceLocation getOpLoc() const { return OpLoc; } setOpLoc(SourceLocation L)598 void setOpLoc(SourceLocation L) { OpLoc = L; } 599 600 // Iterators children()601 child_range children() { return child_range(&Base, &Base+1); } 602 children()603 const_child_range children() const { 604 return const_child_range(&Base, &Base + 1); 605 } 606 classof(const Stmt * T)607 static bool classof(const Stmt *T) { 608 return T->getStmtClass() == ObjCIvarRefExprClass; 609 } 610 }; 611 612 /// ObjCPropertyRefExpr - A dot-syntax expression to access an ObjC 613 /// property. 614 class ObjCPropertyRefExpr : public Expr { 615 private: 616 /// If the bool is true, this is an implicit property reference; the 617 /// pointer is an (optional) ObjCMethodDecl and Setter may be set. 618 /// if the bool is false, this is an explicit property reference; 619 /// the pointer is an ObjCPropertyDecl and Setter is always null. 620 llvm::PointerIntPair<NamedDecl *, 1, bool> PropertyOrGetter; 621 622 /// Indicates whether the property reference will result in a message 623 /// to the getter, the setter, or both. 624 /// This applies to both implicit and explicit property references. 625 enum MethodRefFlags { 626 MethodRef_None = 0, 627 MethodRef_Getter = 0x1, 628 MethodRef_Setter = 0x2 629 }; 630 631 /// Contains the Setter method pointer and MethodRefFlags bit flags. 632 llvm::PointerIntPair<ObjCMethodDecl *, 2, unsigned> SetterAndMethodRefFlags; 633 634 // FIXME: Maybe we should store the property identifier here, 635 // because it's not rederivable from the other data when there's an 636 // implicit property with no getter (because the 'foo' -> 'setFoo:' 637 // transformation is lossy on the first character). 638 639 SourceLocation IdLoc; 640 641 /// When the receiver in property access is 'super', this is 642 /// the location of the 'super' keyword. When it's an interface, 643 /// this is that interface. 644 SourceLocation ReceiverLoc; 645 llvm::PointerUnion3<Stmt *, const Type *, ObjCInterfaceDecl *> Receiver; 646 647 public: ObjCPropertyRefExpr(ObjCPropertyDecl * PD,QualType t,ExprValueKind VK,ExprObjectKind OK,SourceLocation l,Expr * base)648 ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t, 649 ExprValueKind VK, ExprObjectKind OK, 650 SourceLocation l, Expr *base) 651 : Expr(ObjCPropertyRefExprClass, t, VK, OK, 652 /*TypeDependent=*/false, base->isValueDependent(), 653 base->isInstantiationDependent(), 654 base->containsUnexpandedParameterPack()), 655 PropertyOrGetter(PD, false), IdLoc(l), Receiver(base) { 656 assert(t->isSpecificPlaceholderType(BuiltinType::PseudoObject)); 657 } 658 ObjCPropertyRefExpr(ObjCPropertyDecl * PD,QualType t,ExprValueKind VK,ExprObjectKind OK,SourceLocation l,SourceLocation sl,QualType st)659 ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t, 660 ExprValueKind VK, ExprObjectKind OK, 661 SourceLocation l, SourceLocation sl, QualType st) 662 : Expr(ObjCPropertyRefExprClass, t, VK, OK, 663 /*TypeDependent=*/false, false, st->isInstantiationDependentType(), 664 st->containsUnexpandedParameterPack()), 665 PropertyOrGetter(PD, false), IdLoc(l), ReceiverLoc(sl), 666 Receiver(st.getTypePtr()) { 667 assert(t->isSpecificPlaceholderType(BuiltinType::PseudoObject)); 668 } 669 ObjCPropertyRefExpr(ObjCMethodDecl * Getter,ObjCMethodDecl * Setter,QualType T,ExprValueKind VK,ExprObjectKind OK,SourceLocation IdLoc,Expr * Base)670 ObjCPropertyRefExpr(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter, 671 QualType T, ExprValueKind VK, ExprObjectKind OK, 672 SourceLocation IdLoc, Expr *Base) 673 : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, 674 Base->isValueDependent(), Base->isInstantiationDependent(), 675 Base->containsUnexpandedParameterPack()), 676 PropertyOrGetter(Getter, true), SetterAndMethodRefFlags(Setter, 0), 677 IdLoc(IdLoc), Receiver(Base) { 678 assert(T->isSpecificPlaceholderType(BuiltinType::PseudoObject)); 679 } 680 ObjCPropertyRefExpr(ObjCMethodDecl * Getter,ObjCMethodDecl * Setter,QualType T,ExprValueKind VK,ExprObjectKind OK,SourceLocation IdLoc,SourceLocation SuperLoc,QualType SuperTy)681 ObjCPropertyRefExpr(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter, 682 QualType T, ExprValueKind VK, ExprObjectKind OK, 683 SourceLocation IdLoc, 684 SourceLocation SuperLoc, QualType SuperTy) 685 : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, false, false, false), 686 PropertyOrGetter(Getter, true), SetterAndMethodRefFlags(Setter, 0), 687 IdLoc(IdLoc), ReceiverLoc(SuperLoc), Receiver(SuperTy.getTypePtr()) { 688 assert(T->isSpecificPlaceholderType(BuiltinType::PseudoObject)); 689 } 690 ObjCPropertyRefExpr(ObjCMethodDecl * Getter,ObjCMethodDecl * Setter,QualType T,ExprValueKind VK,ExprObjectKind OK,SourceLocation IdLoc,SourceLocation ReceiverLoc,ObjCInterfaceDecl * Receiver)691 ObjCPropertyRefExpr(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter, 692 QualType T, ExprValueKind VK, ExprObjectKind OK, 693 SourceLocation IdLoc, 694 SourceLocation ReceiverLoc, ObjCInterfaceDecl *Receiver) 695 : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, false, false, false), 696 PropertyOrGetter(Getter, true), SetterAndMethodRefFlags(Setter, 0), 697 IdLoc(IdLoc), ReceiverLoc(ReceiverLoc), Receiver(Receiver) { 698 assert(T->isSpecificPlaceholderType(BuiltinType::PseudoObject)); 699 } 700 ObjCPropertyRefExpr(EmptyShell Empty)701 explicit ObjCPropertyRefExpr(EmptyShell Empty) 702 : Expr(ObjCPropertyRefExprClass, Empty) {} 703 isImplicitProperty()704 bool isImplicitProperty() const { return PropertyOrGetter.getInt(); } isExplicitProperty()705 bool isExplicitProperty() const { return !PropertyOrGetter.getInt(); } 706 getExplicitProperty()707 ObjCPropertyDecl *getExplicitProperty() const { 708 assert(!isImplicitProperty()); 709 return cast<ObjCPropertyDecl>(PropertyOrGetter.getPointer()); 710 } 711 getImplicitPropertyGetter()712 ObjCMethodDecl *getImplicitPropertyGetter() const { 713 assert(isImplicitProperty()); 714 return cast_or_null<ObjCMethodDecl>(PropertyOrGetter.getPointer()); 715 } 716 getImplicitPropertySetter()717 ObjCMethodDecl *getImplicitPropertySetter() const { 718 assert(isImplicitProperty()); 719 return SetterAndMethodRefFlags.getPointer(); 720 } 721 getGetterSelector()722 Selector getGetterSelector() const { 723 if (isImplicitProperty()) 724 return getImplicitPropertyGetter()->getSelector(); 725 return getExplicitProperty()->getGetterName(); 726 } 727 getSetterSelector()728 Selector getSetterSelector() const { 729 if (isImplicitProperty()) 730 return getImplicitPropertySetter()->getSelector(); 731 return getExplicitProperty()->getSetterName(); 732 } 733 734 /// True if the property reference will result in a message to the 735 /// getter. 736 /// This applies to both implicit and explicit property references. isMessagingGetter()737 bool isMessagingGetter() const { 738 return SetterAndMethodRefFlags.getInt() & MethodRef_Getter; 739 } 740 741 /// True if the property reference will result in a message to the 742 /// setter. 743 /// This applies to both implicit and explicit property references. isMessagingSetter()744 bool isMessagingSetter() const { 745 return SetterAndMethodRefFlags.getInt() & MethodRef_Setter; 746 } 747 748 void setIsMessagingGetter(bool val = true) { 749 setMethodRefFlag(MethodRef_Getter, val); 750 } 751 752 void setIsMessagingSetter(bool val = true) { 753 setMethodRefFlag(MethodRef_Setter, val); 754 } 755 getBase()756 const Expr *getBase() const { 757 return cast<Expr>(Receiver.get<Stmt*>()); 758 } getBase()759 Expr *getBase() { 760 return cast<Expr>(Receiver.get<Stmt*>()); 761 } 762 getLocation()763 SourceLocation getLocation() const { return IdLoc; } 764 getReceiverLocation()765 SourceLocation getReceiverLocation() const { return ReceiverLoc; } 766 getSuperReceiverType()767 QualType getSuperReceiverType() const { 768 return QualType(Receiver.get<const Type*>(), 0); 769 } 770 getClassReceiver()771 ObjCInterfaceDecl *getClassReceiver() const { 772 return Receiver.get<ObjCInterfaceDecl*>(); 773 } 774 isObjectReceiver()775 bool isObjectReceiver() const { return Receiver.is<Stmt*>(); } isSuperReceiver()776 bool isSuperReceiver() const { return Receiver.is<const Type*>(); } isClassReceiver()777 bool isClassReceiver() const { return Receiver.is<ObjCInterfaceDecl*>(); } 778 779 /// Determine the type of the base, regardless of the kind of receiver. 780 QualType getReceiverType(const ASTContext &ctx) const; 781 getBeginLoc()782 SourceLocation getBeginLoc() const LLVM_READONLY { 783 return isObjectReceiver() ? getBase()->getBeginLoc() 784 : getReceiverLocation(); 785 } 786 getEndLoc()787 SourceLocation getEndLoc() const LLVM_READONLY { return IdLoc; } 788 789 // Iterators children()790 child_range children() { 791 if (Receiver.is<Stmt*>()) { 792 Stmt **begin = reinterpret_cast<Stmt**>(&Receiver); // hack! 793 return child_range(begin, begin+1); 794 } 795 return child_range(child_iterator(), child_iterator()); 796 } 797 children()798 const_child_range children() const { 799 auto Children = const_cast<ObjCPropertyRefExpr *>(this)->children(); 800 return const_child_range(Children.begin(), Children.end()); 801 } 802 classof(const Stmt * T)803 static bool classof(const Stmt *T) { 804 return T->getStmtClass() == ObjCPropertyRefExprClass; 805 } 806 807 private: 808 friend class ASTStmtReader; 809 friend class ASTStmtWriter; 810 setExplicitProperty(ObjCPropertyDecl * D,unsigned methRefFlags)811 void setExplicitProperty(ObjCPropertyDecl *D, unsigned methRefFlags) { 812 PropertyOrGetter.setPointer(D); 813 PropertyOrGetter.setInt(false); 814 SetterAndMethodRefFlags.setPointer(nullptr); 815 SetterAndMethodRefFlags.setInt(methRefFlags); 816 } 817 setImplicitProperty(ObjCMethodDecl * Getter,ObjCMethodDecl * Setter,unsigned methRefFlags)818 void setImplicitProperty(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter, 819 unsigned methRefFlags) { 820 PropertyOrGetter.setPointer(Getter); 821 PropertyOrGetter.setInt(true); 822 SetterAndMethodRefFlags.setPointer(Setter); 823 SetterAndMethodRefFlags.setInt(methRefFlags); 824 } 825 setBase(Expr * Base)826 void setBase(Expr *Base) { Receiver = Base; } setSuperReceiver(QualType T)827 void setSuperReceiver(QualType T) { Receiver = T.getTypePtr(); } setClassReceiver(ObjCInterfaceDecl * D)828 void setClassReceiver(ObjCInterfaceDecl *D) { Receiver = D; } 829 setLocation(SourceLocation L)830 void setLocation(SourceLocation L) { IdLoc = L; } setReceiverLocation(SourceLocation Loc)831 void setReceiverLocation(SourceLocation Loc) { ReceiverLoc = Loc; } 832 setMethodRefFlag(MethodRefFlags flag,bool val)833 void setMethodRefFlag(MethodRefFlags flag, bool val) { 834 unsigned f = SetterAndMethodRefFlags.getInt(); 835 if (val) 836 f |= flag; 837 else 838 f &= ~flag; 839 SetterAndMethodRefFlags.setInt(f); 840 } 841 }; 842 843 /// ObjCSubscriptRefExpr - used for array and dictionary subscripting. 844 /// array[4] = array[3]; dictionary[key] = dictionary[alt_key]; 845 class ObjCSubscriptRefExpr : public Expr { 846 // Location of ']' in an indexing expression. 847 SourceLocation RBracket; 848 849 // array/dictionary base expression. 850 // for arrays, this is a numeric expression. For dictionaries, this is 851 // an objective-c object pointer expression. 852 enum { BASE, KEY, END_EXPR }; 853 Stmt* SubExprs[END_EXPR]; 854 855 ObjCMethodDecl *GetAtIndexMethodDecl; 856 857 // For immutable objects this is null. When ObjCSubscriptRefExpr is to read 858 // an indexed object this is null too. 859 ObjCMethodDecl *SetAtIndexMethodDecl; 860 861 public: ObjCSubscriptRefExpr(Expr * base,Expr * key,QualType T,ExprValueKind VK,ExprObjectKind OK,ObjCMethodDecl * getMethod,ObjCMethodDecl * setMethod,SourceLocation RB)862 ObjCSubscriptRefExpr(Expr *base, Expr *key, QualType T, 863 ExprValueKind VK, ExprObjectKind OK, 864 ObjCMethodDecl *getMethod, 865 ObjCMethodDecl *setMethod, SourceLocation RB) 866 : Expr(ObjCSubscriptRefExprClass, T, VK, OK, 867 base->isTypeDependent() || key->isTypeDependent(), 868 base->isValueDependent() || key->isValueDependent(), 869 (base->isInstantiationDependent() || 870 key->isInstantiationDependent()), 871 (base->containsUnexpandedParameterPack() || 872 key->containsUnexpandedParameterPack())), 873 RBracket(RB), GetAtIndexMethodDecl(getMethod), 874 SetAtIndexMethodDecl(setMethod) { 875 SubExprs[BASE] = base; SubExprs[KEY] = key; 876 } 877 ObjCSubscriptRefExpr(EmptyShell Empty)878 explicit ObjCSubscriptRefExpr(EmptyShell Empty) 879 : Expr(ObjCSubscriptRefExprClass, Empty) {} 880 getRBracket()881 SourceLocation getRBracket() const { return RBracket; } setRBracket(SourceLocation RB)882 void setRBracket(SourceLocation RB) { RBracket = RB; } 883 getBeginLoc()884 SourceLocation getBeginLoc() const LLVM_READONLY { 885 return SubExprs[BASE]->getBeginLoc(); 886 } 887 getEndLoc()888 SourceLocation getEndLoc() const LLVM_READONLY { return RBracket; } 889 getBaseExpr()890 Expr *getBaseExpr() const { return cast<Expr>(SubExprs[BASE]); } setBaseExpr(Stmt * S)891 void setBaseExpr(Stmt *S) { SubExprs[BASE] = S; } 892 getKeyExpr()893 Expr *getKeyExpr() const { return cast<Expr>(SubExprs[KEY]); } setKeyExpr(Stmt * S)894 void setKeyExpr(Stmt *S) { SubExprs[KEY] = S; } 895 getAtIndexMethodDecl()896 ObjCMethodDecl *getAtIndexMethodDecl() const { 897 return GetAtIndexMethodDecl; 898 } 899 setAtIndexMethodDecl()900 ObjCMethodDecl *setAtIndexMethodDecl() const { 901 return SetAtIndexMethodDecl; 902 } 903 isArraySubscriptRefExpr()904 bool isArraySubscriptRefExpr() const { 905 return getKeyExpr()->getType()->isIntegralOrEnumerationType(); 906 } 907 children()908 child_range children() { 909 return child_range(SubExprs, SubExprs+END_EXPR); 910 } 911 children()912 const_child_range children() const { 913 return const_child_range(SubExprs, SubExprs + END_EXPR); 914 } 915 classof(const Stmt * T)916 static bool classof(const Stmt *T) { 917 return T->getStmtClass() == ObjCSubscriptRefExprClass; 918 } 919 920 private: 921 friend class ASTStmtReader; 922 }; 923 924 /// An expression that sends a message to the given Objective-C 925 /// object or class. 926 /// 927 /// The following contains two message send expressions: 928 /// 929 /// \code 930 /// [[NSString alloc] initWithString:@"Hello"] 931 /// \endcode 932 /// 933 /// The innermost message send invokes the "alloc" class method on the 934 /// NSString class, while the outermost message send invokes the 935 /// "initWithString" instance method on the object returned from 936 /// NSString's "alloc". In all, an Objective-C message send can take 937 /// on four different (although related) forms: 938 /// 939 /// 1. Send to an object instance. 940 /// 2. Send to a class. 941 /// 3. Send to the superclass instance of the current class. 942 /// 4. Send to the superclass of the current class. 943 /// 944 /// All four kinds of message sends are modeled by the ObjCMessageExpr 945 /// class, and can be distinguished via \c getReceiverKind(). Example: 946 /// 947 /// The "void *" trailing objects are actually ONE void * (the 948 /// receiver pointer), and NumArgs Expr *. But due to the 949 /// implementation of children(), these must be together contiguously. 950 class ObjCMessageExpr final 951 : public Expr, 952 private llvm::TrailingObjects<ObjCMessageExpr, void *, SourceLocation> { 953 /// Stores either the selector that this message is sending 954 /// to (when \c HasMethod is zero) or an \c ObjCMethodDecl pointer 955 /// referring to the method that we type-checked against. 956 uintptr_t SelectorOrMethod = 0; 957 958 enum { NumArgsBitWidth = 16 }; 959 960 /// The number of arguments in the message send, not 961 /// including the receiver. 962 unsigned NumArgs : NumArgsBitWidth; 963 964 /// The kind of message send this is, which is one of the 965 /// ReceiverKind values. 966 /// 967 /// We pad this out to a byte to avoid excessive masking and shifting. 968 unsigned Kind : 8; 969 970 /// Whether we have an actual method prototype in \c 971 /// SelectorOrMethod. 972 /// 973 /// When non-zero, we have a method declaration; otherwise, we just 974 /// have a selector. 975 unsigned HasMethod : 1; 976 977 /// Whether this message send is a "delegate init call", 978 /// i.e. a call of an init method on self from within an init method. 979 unsigned IsDelegateInitCall : 1; 980 981 /// Whether this message send was implicitly generated by 982 /// the implementation rather than explicitly written by the user. 983 unsigned IsImplicit : 1; 984 985 /// Whether the locations of the selector identifiers are in a 986 /// "standard" position, a enum SelectorLocationsKind. 987 unsigned SelLocsKind : 2; 988 989 /// When the message expression is a send to 'super', this is 990 /// the location of the 'super' keyword. 991 SourceLocation SuperLoc; 992 993 /// The source locations of the open and close square 994 /// brackets ('[' and ']', respectively). 995 SourceLocation LBracLoc, RBracLoc; 996 ObjCMessageExpr(EmptyShell Empty,unsigned NumArgs)997 ObjCMessageExpr(EmptyShell Empty, unsigned NumArgs) 998 : Expr(ObjCMessageExprClass, Empty), Kind(0), HasMethod(false), 999 IsDelegateInitCall(false), IsImplicit(false), SelLocsKind(0) { 1000 setNumArgs(NumArgs); 1001 } 1002 1003 ObjCMessageExpr(QualType T, ExprValueKind VK, 1004 SourceLocation LBracLoc, 1005 SourceLocation SuperLoc, 1006 bool IsInstanceSuper, 1007 QualType SuperType, 1008 Selector Sel, 1009 ArrayRef<SourceLocation> SelLocs, 1010 SelectorLocationsKind SelLocsK, 1011 ObjCMethodDecl *Method, 1012 ArrayRef<Expr *> Args, 1013 SourceLocation RBracLoc, 1014 bool isImplicit); 1015 ObjCMessageExpr(QualType T, ExprValueKind VK, 1016 SourceLocation LBracLoc, 1017 TypeSourceInfo *Receiver, 1018 Selector Sel, 1019 ArrayRef<SourceLocation> SelLocs, 1020 SelectorLocationsKind SelLocsK, 1021 ObjCMethodDecl *Method, 1022 ArrayRef<Expr *> Args, 1023 SourceLocation RBracLoc, 1024 bool isImplicit); 1025 ObjCMessageExpr(QualType T, ExprValueKind VK, 1026 SourceLocation LBracLoc, 1027 Expr *Receiver, 1028 Selector Sel, 1029 ArrayRef<SourceLocation> SelLocs, 1030 SelectorLocationsKind SelLocsK, 1031 ObjCMethodDecl *Method, 1032 ArrayRef<Expr *> Args, 1033 SourceLocation RBracLoc, 1034 bool isImplicit); 1035 numTrailingObjects(OverloadToken<void * >)1036 size_t numTrailingObjects(OverloadToken<void *>) const { return NumArgs + 1; } 1037 setNumArgs(unsigned Num)1038 void setNumArgs(unsigned Num) { 1039 assert((Num >> NumArgsBitWidth) == 0 && "Num of args is out of range!"); 1040 NumArgs = Num; 1041 } 1042 1043 void initArgsAndSelLocs(ArrayRef<Expr *> Args, 1044 ArrayRef<SourceLocation> SelLocs, 1045 SelectorLocationsKind SelLocsK); 1046 1047 /// Retrieve the pointer value of the message receiver. getReceiverPointer()1048 void *getReceiverPointer() const { return *getTrailingObjects<void *>(); } 1049 1050 /// Set the pointer value of the message receiver. setReceiverPointer(void * Value)1051 void setReceiverPointer(void *Value) { 1052 *getTrailingObjects<void *>() = Value; 1053 } 1054 getSelLocsKind()1055 SelectorLocationsKind getSelLocsKind() const { 1056 return (SelectorLocationsKind)SelLocsKind; 1057 } 1058 hasStandardSelLocs()1059 bool hasStandardSelLocs() const { 1060 return getSelLocsKind() != SelLoc_NonStandard; 1061 } 1062 1063 /// Get a pointer to the stored selector identifiers locations array. 1064 /// No locations will be stored if HasStandardSelLocs is true. getStoredSelLocs()1065 SourceLocation *getStoredSelLocs() { 1066 return getTrailingObjects<SourceLocation>(); 1067 } getStoredSelLocs()1068 const SourceLocation *getStoredSelLocs() const { 1069 return getTrailingObjects<SourceLocation>(); 1070 } 1071 1072 /// Get the number of stored selector identifiers locations. 1073 /// No locations will be stored if HasStandardSelLocs is true. getNumStoredSelLocs()1074 unsigned getNumStoredSelLocs() const { 1075 if (hasStandardSelLocs()) 1076 return 0; 1077 return getNumSelectorLocs(); 1078 } 1079 1080 static ObjCMessageExpr *alloc(const ASTContext &C, 1081 ArrayRef<Expr *> Args, 1082 SourceLocation RBraceLoc, 1083 ArrayRef<SourceLocation> SelLocs, 1084 Selector Sel, 1085 SelectorLocationsKind &SelLocsK); 1086 static ObjCMessageExpr *alloc(const ASTContext &C, 1087 unsigned NumArgs, 1088 unsigned NumStoredSelLocs); 1089 1090 public: 1091 friend class ASTStmtReader; 1092 friend class ASTStmtWriter; 1093 friend TrailingObjects; 1094 1095 /// The kind of receiver this message is sending to. 1096 enum ReceiverKind { 1097 /// The receiver is a class. 1098 Class = 0, 1099 1100 /// The receiver is an object instance. 1101 Instance, 1102 1103 /// The receiver is a superclass. 1104 SuperClass, 1105 1106 /// The receiver is the instance of the superclass object. 1107 SuperInstance 1108 }; 1109 1110 /// Create a message send to super. 1111 /// 1112 /// \param Context The ASTContext in which this expression will be created. 1113 /// 1114 /// \param T The result type of this message. 1115 /// 1116 /// \param VK The value kind of this message. A message returning 1117 /// a l-value or r-value reference will be an l-value or x-value, 1118 /// respectively. 1119 /// 1120 /// \param LBracLoc The location of the open square bracket '['. 1121 /// 1122 /// \param SuperLoc The location of the "super" keyword. 1123 /// 1124 /// \param IsInstanceSuper Whether this is an instance "super" 1125 /// message (otherwise, it's a class "super" message). 1126 /// 1127 /// \param Sel The selector used to determine which method gets called. 1128 /// 1129 /// \param Method The Objective-C method against which this message 1130 /// send was type-checked. May be nullptr. 1131 /// 1132 /// \param Args The message send arguments. 1133 /// 1134 /// \param RBracLoc The location of the closing square bracket ']'. 1135 static ObjCMessageExpr *Create(const ASTContext &Context, QualType T, 1136 ExprValueKind VK, 1137 SourceLocation LBracLoc, 1138 SourceLocation SuperLoc, 1139 bool IsInstanceSuper, 1140 QualType SuperType, 1141 Selector Sel, 1142 ArrayRef<SourceLocation> SelLocs, 1143 ObjCMethodDecl *Method, 1144 ArrayRef<Expr *> Args, 1145 SourceLocation RBracLoc, 1146 bool isImplicit); 1147 1148 /// Create a class message send. 1149 /// 1150 /// \param Context The ASTContext in which this expression will be created. 1151 /// 1152 /// \param T The result type of this message. 1153 /// 1154 /// \param VK The value kind of this message. A message returning 1155 /// a l-value or r-value reference will be an l-value or x-value, 1156 /// respectively. 1157 /// 1158 /// \param LBracLoc The location of the open square bracket '['. 1159 /// 1160 /// \param Receiver The type of the receiver, including 1161 /// source-location information. 1162 /// 1163 /// \param Sel The selector used to determine which method gets called. 1164 /// 1165 /// \param Method The Objective-C method against which this message 1166 /// send was type-checked. May be nullptr. 1167 /// 1168 /// \param Args The message send arguments. 1169 /// 1170 /// \param RBracLoc The location of the closing square bracket ']'. 1171 static ObjCMessageExpr *Create(const ASTContext &Context, QualType T, 1172 ExprValueKind VK, 1173 SourceLocation LBracLoc, 1174 TypeSourceInfo *Receiver, 1175 Selector Sel, 1176 ArrayRef<SourceLocation> SelLocs, 1177 ObjCMethodDecl *Method, 1178 ArrayRef<Expr *> Args, 1179 SourceLocation RBracLoc, 1180 bool isImplicit); 1181 1182 /// Create an instance message send. 1183 /// 1184 /// \param Context The ASTContext in which this expression will be created. 1185 /// 1186 /// \param T The result type of this message. 1187 /// 1188 /// \param VK The value kind of this message. A message returning 1189 /// a l-value or r-value reference will be an l-value or x-value, 1190 /// respectively. 1191 /// 1192 /// \param LBracLoc The location of the open square bracket '['. 1193 /// 1194 /// \param Receiver The expression used to produce the object that 1195 /// will receive this message. 1196 /// 1197 /// \param Sel The selector used to determine which method gets called. 1198 /// 1199 /// \param Method The Objective-C method against which this message 1200 /// send was type-checked. May be nullptr. 1201 /// 1202 /// \param Args The message send arguments. 1203 /// 1204 /// \param RBracLoc The location of the closing square bracket ']'. 1205 static ObjCMessageExpr *Create(const ASTContext &Context, QualType T, 1206 ExprValueKind VK, 1207 SourceLocation LBracLoc, 1208 Expr *Receiver, 1209 Selector Sel, 1210 ArrayRef<SourceLocation> SeLocs, 1211 ObjCMethodDecl *Method, 1212 ArrayRef<Expr *> Args, 1213 SourceLocation RBracLoc, 1214 bool isImplicit); 1215 1216 /// Create an empty Objective-C message expression, to be 1217 /// filled in by subsequent calls. 1218 /// 1219 /// \param Context The context in which the message send will be created. 1220 /// 1221 /// \param NumArgs The number of message arguments, not including 1222 /// the receiver. 1223 static ObjCMessageExpr *CreateEmpty(const ASTContext &Context, 1224 unsigned NumArgs, 1225 unsigned NumStoredSelLocs); 1226 1227 /// Indicates whether the message send was implicitly 1228 /// generated by the implementation. If false, it was written explicitly 1229 /// in the source code. isImplicit()1230 bool isImplicit() const { return IsImplicit; } 1231 1232 /// Determine the kind of receiver that this message is being 1233 /// sent to. getReceiverKind()1234 ReceiverKind getReceiverKind() const { return (ReceiverKind)Kind; } 1235 1236 /// \return the return type of the message being sent. 1237 /// This is not always the type of the message expression itself because 1238 /// of references (the expression would not have a reference type). 1239 /// It is also not always the declared return type of the method because 1240 /// of `instancetype` (in that case it's an expression type). 1241 QualType getCallReturnType(ASTContext &Ctx) const; 1242 1243 /// Source range of the receiver. 1244 SourceRange getReceiverRange() const; 1245 1246 /// Determine whether this is an instance message to either a 1247 /// computed object or to super. isInstanceMessage()1248 bool isInstanceMessage() const { 1249 return getReceiverKind() == Instance || getReceiverKind() == SuperInstance; 1250 } 1251 1252 /// Determine whether this is an class message to either a 1253 /// specified class or to super. isClassMessage()1254 bool isClassMessage() const { 1255 return getReceiverKind() == Class || getReceiverKind() == SuperClass; 1256 } 1257 1258 /// Returns the object expression (receiver) for an instance message, 1259 /// or null for a message that is not an instance message. getInstanceReceiver()1260 Expr *getInstanceReceiver() { 1261 if (getReceiverKind() == Instance) 1262 return static_cast<Expr *>(getReceiverPointer()); 1263 1264 return nullptr; 1265 } getInstanceReceiver()1266 const Expr *getInstanceReceiver() const { 1267 return const_cast<ObjCMessageExpr*>(this)->getInstanceReceiver(); 1268 } 1269 1270 /// Turn this message send into an instance message that 1271 /// computes the receiver object with the given expression. setInstanceReceiver(Expr * rec)1272 void setInstanceReceiver(Expr *rec) { 1273 Kind = Instance; 1274 setReceiverPointer(rec); 1275 } 1276 1277 /// Returns the type of a class message send, or NULL if the 1278 /// message is not a class message. getClassReceiver()1279 QualType getClassReceiver() const { 1280 if (TypeSourceInfo *TSInfo = getClassReceiverTypeInfo()) 1281 return TSInfo->getType(); 1282 1283 return {}; 1284 } 1285 1286 /// Returns a type-source information of a class message 1287 /// send, or nullptr if the message is not a class message. getClassReceiverTypeInfo()1288 TypeSourceInfo *getClassReceiverTypeInfo() const { 1289 if (getReceiverKind() == Class) 1290 return reinterpret_cast<TypeSourceInfo *>(getReceiverPointer()); 1291 return nullptr; 1292 } 1293 setClassReceiver(TypeSourceInfo * TSInfo)1294 void setClassReceiver(TypeSourceInfo *TSInfo) { 1295 Kind = Class; 1296 setReceiverPointer(TSInfo); 1297 } 1298 1299 /// Retrieve the location of the 'super' keyword for a class 1300 /// or instance message to 'super', otherwise an invalid source location. getSuperLoc()1301 SourceLocation getSuperLoc() const { 1302 if (getReceiverKind() == SuperInstance || getReceiverKind() == SuperClass) 1303 return SuperLoc; 1304 1305 return SourceLocation(); 1306 } 1307 1308 /// Retrieve the receiver type to which this message is being directed. 1309 /// 1310 /// This routine cross-cuts all of the different kinds of message 1311 /// sends to determine what the underlying (statically known) type 1312 /// of the receiver will be; use \c getReceiverKind() to determine 1313 /// whether the message is a class or an instance method, whether it 1314 /// is a send to super or not, etc. 1315 /// 1316 /// \returns The type of the receiver. 1317 QualType getReceiverType() const; 1318 1319 /// Retrieve the Objective-C interface to which this message 1320 /// is being directed, if known. 1321 /// 1322 /// This routine cross-cuts all of the different kinds of message 1323 /// sends to determine what the underlying (statically known) type 1324 /// of the receiver will be; use \c getReceiverKind() to determine 1325 /// whether the message is a class or an instance method, whether it 1326 /// is a send to super or not, etc. 1327 /// 1328 /// \returns The Objective-C interface if known, otherwise nullptr. 1329 ObjCInterfaceDecl *getReceiverInterface() const; 1330 1331 /// Retrieve the type referred to by 'super'. 1332 /// 1333 /// The returned type will either be an ObjCInterfaceType (for an 1334 /// class message to super) or an ObjCObjectPointerType that refers 1335 /// to a class (for an instance message to super); getSuperType()1336 QualType getSuperType() const { 1337 if (getReceiverKind() == SuperInstance || getReceiverKind() == SuperClass) 1338 return QualType::getFromOpaquePtr(getReceiverPointer()); 1339 1340 return QualType(); 1341 } 1342 setSuper(SourceLocation Loc,QualType T,bool IsInstanceSuper)1343 void setSuper(SourceLocation Loc, QualType T, bool IsInstanceSuper) { 1344 Kind = IsInstanceSuper? SuperInstance : SuperClass; 1345 SuperLoc = Loc; 1346 setReceiverPointer(T.getAsOpaquePtr()); 1347 } 1348 1349 Selector getSelector() const; 1350 setSelector(Selector S)1351 void setSelector(Selector S) { 1352 HasMethod = false; 1353 SelectorOrMethod = reinterpret_cast<uintptr_t>(S.getAsOpaquePtr()); 1354 } 1355 getMethodDecl()1356 const ObjCMethodDecl *getMethodDecl() const { 1357 if (HasMethod) 1358 return reinterpret_cast<const ObjCMethodDecl *>(SelectorOrMethod); 1359 1360 return nullptr; 1361 } 1362 getMethodDecl()1363 ObjCMethodDecl *getMethodDecl() { 1364 if (HasMethod) 1365 return reinterpret_cast<ObjCMethodDecl *>(SelectorOrMethod); 1366 1367 return nullptr; 1368 } 1369 setMethodDecl(ObjCMethodDecl * MD)1370 void setMethodDecl(ObjCMethodDecl *MD) { 1371 HasMethod = true; 1372 SelectorOrMethod = reinterpret_cast<uintptr_t>(MD); 1373 } 1374 getMethodFamily()1375 ObjCMethodFamily getMethodFamily() const { 1376 if (HasMethod) return getMethodDecl()->getMethodFamily(); 1377 return getSelector().getMethodFamily(); 1378 } 1379 1380 /// Return the number of actual arguments in this message, 1381 /// not counting the receiver. getNumArgs()1382 unsigned getNumArgs() const { return NumArgs; } 1383 1384 /// Retrieve the arguments to this message, not including the 1385 /// receiver. getArgs()1386 Expr **getArgs() { 1387 return reinterpret_cast<Expr **>(getTrailingObjects<void *>() + 1); 1388 } getArgs()1389 const Expr * const *getArgs() const { 1390 return reinterpret_cast<const Expr *const *>(getTrailingObjects<void *>() + 1391 1); 1392 } 1393 1394 /// getArg - Return the specified argument. getArg(unsigned Arg)1395 Expr *getArg(unsigned Arg) { 1396 assert(Arg < NumArgs && "Arg access out of range!"); 1397 return getArgs()[Arg]; 1398 } getArg(unsigned Arg)1399 const Expr *getArg(unsigned Arg) const { 1400 assert(Arg < NumArgs && "Arg access out of range!"); 1401 return getArgs()[Arg]; 1402 } 1403 1404 /// setArg - Set the specified argument. setArg(unsigned Arg,Expr * ArgExpr)1405 void setArg(unsigned Arg, Expr *ArgExpr) { 1406 assert(Arg < NumArgs && "Arg access out of range!"); 1407 getArgs()[Arg] = ArgExpr; 1408 } 1409 1410 /// isDelegateInitCall - Answers whether this message send has been 1411 /// tagged as a "delegate init call", i.e. a call to a method in the 1412 /// -init family on self from within an -init method implementation. isDelegateInitCall()1413 bool isDelegateInitCall() const { return IsDelegateInitCall; } setDelegateInitCall(bool isDelegate)1414 void setDelegateInitCall(bool isDelegate) { IsDelegateInitCall = isDelegate; } 1415 getLeftLoc()1416 SourceLocation getLeftLoc() const { return LBracLoc; } getRightLoc()1417 SourceLocation getRightLoc() const { return RBracLoc; } 1418 getSelectorStartLoc()1419 SourceLocation getSelectorStartLoc() const { 1420 if (isImplicit()) 1421 return getBeginLoc(); 1422 return getSelectorLoc(0); 1423 } 1424 getSelectorLoc(unsigned Index)1425 SourceLocation getSelectorLoc(unsigned Index) const { 1426 assert(Index < getNumSelectorLocs() && "Index out of range!"); 1427 if (hasStandardSelLocs()) 1428 return getStandardSelectorLoc(Index, getSelector(), 1429 getSelLocsKind() == SelLoc_StandardWithSpace, 1430 llvm::makeArrayRef(const_cast<Expr**>(getArgs()), 1431 getNumArgs()), 1432 RBracLoc); 1433 return getStoredSelLocs()[Index]; 1434 } 1435 1436 void getSelectorLocs(SmallVectorImpl<SourceLocation> &SelLocs) const; 1437 getNumSelectorLocs()1438 unsigned getNumSelectorLocs() const { 1439 if (isImplicit()) 1440 return 0; 1441 Selector Sel = getSelector(); 1442 if (Sel.isUnarySelector()) 1443 return 1; 1444 return Sel.getNumArgs(); 1445 } 1446 setSourceRange(SourceRange R)1447 void setSourceRange(SourceRange R) { 1448 LBracLoc = R.getBegin(); 1449 RBracLoc = R.getEnd(); 1450 } 1451 getBeginLoc()1452 SourceLocation getBeginLoc() const LLVM_READONLY { return LBracLoc; } getEndLoc()1453 SourceLocation getEndLoc() const LLVM_READONLY { return RBracLoc; } 1454 1455 // Iterators 1456 child_range children(); 1457 1458 const_child_range children() const; 1459 1460 using arg_iterator = ExprIterator; 1461 using const_arg_iterator = ConstExprIterator; 1462 arguments()1463 llvm::iterator_range<arg_iterator> arguments() { 1464 return llvm::make_range(arg_begin(), arg_end()); 1465 } 1466 arguments()1467 llvm::iterator_range<const_arg_iterator> arguments() const { 1468 return llvm::make_range(arg_begin(), arg_end()); 1469 } 1470 arg_begin()1471 arg_iterator arg_begin() { return reinterpret_cast<Stmt **>(getArgs()); } 1472 arg_end()1473 arg_iterator arg_end() { 1474 return reinterpret_cast<Stmt **>(getArgs() + NumArgs); 1475 } 1476 arg_begin()1477 const_arg_iterator arg_begin() const { 1478 return reinterpret_cast<Stmt const * const*>(getArgs()); 1479 } 1480 arg_end()1481 const_arg_iterator arg_end() const { 1482 return reinterpret_cast<Stmt const * const*>(getArgs() + NumArgs); 1483 } 1484 classof(const Stmt * T)1485 static bool classof(const Stmt *T) { 1486 return T->getStmtClass() == ObjCMessageExprClass; 1487 } 1488 }; 1489 1490 /// ObjCIsaExpr - Represent X->isa and X.isa when X is an ObjC 'id' type. 1491 /// (similar in spirit to MemberExpr). 1492 class ObjCIsaExpr : public Expr { 1493 /// Base - the expression for the base object pointer. 1494 Stmt *Base; 1495 1496 /// IsaMemberLoc - This is the location of the 'isa'. 1497 SourceLocation IsaMemberLoc; 1498 1499 /// OpLoc - This is the location of '.' or '->' 1500 SourceLocation OpLoc; 1501 1502 /// IsArrow - True if this is "X->F", false if this is "X.F". 1503 bool IsArrow; 1504 1505 public: ObjCIsaExpr(Expr * base,bool isarrow,SourceLocation l,SourceLocation oploc,QualType ty)1506 ObjCIsaExpr(Expr *base, bool isarrow, SourceLocation l, SourceLocation oploc, 1507 QualType ty) 1508 : Expr(ObjCIsaExprClass, ty, VK_LValue, OK_Ordinary, 1509 /*TypeDependent=*/false, base->isValueDependent(), 1510 base->isInstantiationDependent(), 1511 /*ContainsUnexpandedParameterPack=*/false), 1512 Base(base), IsaMemberLoc(l), OpLoc(oploc), IsArrow(isarrow) {} 1513 1514 /// Build an empty expression. ObjCIsaExpr(EmptyShell Empty)1515 explicit ObjCIsaExpr(EmptyShell Empty) : Expr(ObjCIsaExprClass, Empty) {} 1516 setBase(Expr * E)1517 void setBase(Expr *E) { Base = E; } getBase()1518 Expr *getBase() const { return cast<Expr>(Base); } 1519 isArrow()1520 bool isArrow() const { return IsArrow; } setArrow(bool A)1521 void setArrow(bool A) { IsArrow = A; } 1522 1523 /// getMemberLoc - Return the location of the "member", in X->F, it is the 1524 /// location of 'F'. getIsaMemberLoc()1525 SourceLocation getIsaMemberLoc() const { return IsaMemberLoc; } setIsaMemberLoc(SourceLocation L)1526 void setIsaMemberLoc(SourceLocation L) { IsaMemberLoc = L; } 1527 getOpLoc()1528 SourceLocation getOpLoc() const { return OpLoc; } setOpLoc(SourceLocation L)1529 void setOpLoc(SourceLocation L) { OpLoc = L; } 1530 getBeginLoc()1531 SourceLocation getBeginLoc() const LLVM_READONLY { 1532 return getBase()->getBeginLoc(); 1533 } 1534 getBaseLocEnd()1535 SourceLocation getBaseLocEnd() const LLVM_READONLY { 1536 return getBase()->getEndLoc(); 1537 } 1538 getEndLoc()1539 SourceLocation getEndLoc() const LLVM_READONLY { return IsaMemberLoc; } 1540 getExprLoc()1541 SourceLocation getExprLoc() const LLVM_READONLY { return IsaMemberLoc; } 1542 1543 // Iterators children()1544 child_range children() { return child_range(&Base, &Base+1); } 1545 children()1546 const_child_range children() const { 1547 return const_child_range(&Base, &Base + 1); 1548 } 1549 classof(const Stmt * T)1550 static bool classof(const Stmt *T) { 1551 return T->getStmtClass() == ObjCIsaExprClass; 1552 } 1553 }; 1554 1555 /// ObjCIndirectCopyRestoreExpr - Represents the passing of a function 1556 /// argument by indirect copy-restore in ARC. This is used to support 1557 /// passing indirect arguments with the wrong lifetime, e.g. when 1558 /// passing the address of a __strong local variable to an 'out' 1559 /// parameter. This expression kind is only valid in an "argument" 1560 /// position to some sort of call expression. 1561 /// 1562 /// The parameter must have type 'pointer to T', and the argument must 1563 /// have type 'pointer to U', where T and U agree except possibly in 1564 /// qualification. If the argument value is null, then a null pointer 1565 /// is passed; otherwise it points to an object A, and: 1566 /// 1. A temporary object B of type T is initialized, either by 1567 /// zero-initialization (used when initializing an 'out' parameter) 1568 /// or copy-initialization (used when initializing an 'inout' 1569 /// parameter). 1570 /// 2. The address of the temporary is passed to the function. 1571 /// 3. If the call completes normally, A is move-assigned from B. 1572 /// 4. Finally, A is destroyed immediately. 1573 /// 1574 /// Currently 'T' must be a retainable object lifetime and must be 1575 /// __autoreleasing; this qualifier is ignored when initializing 1576 /// the value. 1577 class ObjCIndirectCopyRestoreExpr : public Expr { 1578 friend class ASTReader; 1579 friend class ASTStmtReader; 1580 1581 Stmt *Operand; 1582 1583 // unsigned ObjCIndirectCopyRestoreBits.ShouldCopy : 1; 1584 ObjCIndirectCopyRestoreExpr(EmptyShell Empty)1585 explicit ObjCIndirectCopyRestoreExpr(EmptyShell Empty) 1586 : Expr(ObjCIndirectCopyRestoreExprClass, Empty) {} 1587 setShouldCopy(bool shouldCopy)1588 void setShouldCopy(bool shouldCopy) { 1589 ObjCIndirectCopyRestoreExprBits.ShouldCopy = shouldCopy; 1590 } 1591 1592 public: ObjCIndirectCopyRestoreExpr(Expr * operand,QualType type,bool shouldCopy)1593 ObjCIndirectCopyRestoreExpr(Expr *operand, QualType type, bool shouldCopy) 1594 : Expr(ObjCIndirectCopyRestoreExprClass, type, VK_LValue, OK_Ordinary, 1595 operand->isTypeDependent(), operand->isValueDependent(), 1596 operand->isInstantiationDependent(), 1597 operand->containsUnexpandedParameterPack()), 1598 Operand(operand) { 1599 setShouldCopy(shouldCopy); 1600 } 1601 getSubExpr()1602 Expr *getSubExpr() { return cast<Expr>(Operand); } getSubExpr()1603 const Expr *getSubExpr() const { return cast<Expr>(Operand); } 1604 1605 /// shouldCopy - True if we should do the 'copy' part of the 1606 /// copy-restore. If false, the temporary will be zero-initialized. shouldCopy()1607 bool shouldCopy() const { return ObjCIndirectCopyRestoreExprBits.ShouldCopy; } 1608 children()1609 child_range children() { return child_range(&Operand, &Operand+1); } 1610 children()1611 const_child_range children() const { 1612 return const_child_range(&Operand, &Operand + 1); 1613 } 1614 1615 // Source locations are determined by the subexpression. getBeginLoc()1616 SourceLocation getBeginLoc() const LLVM_READONLY { 1617 return Operand->getBeginLoc(); 1618 } getEndLoc()1619 SourceLocation getEndLoc() const LLVM_READONLY { 1620 return Operand->getEndLoc(); 1621 } 1622 getExprLoc()1623 SourceLocation getExprLoc() const LLVM_READONLY { 1624 return getSubExpr()->getExprLoc(); 1625 } 1626 classof(const Stmt * s)1627 static bool classof(const Stmt *s) { 1628 return s->getStmtClass() == ObjCIndirectCopyRestoreExprClass; 1629 } 1630 }; 1631 1632 /// An Objective-C "bridged" cast expression, which casts between 1633 /// Objective-C pointers and C pointers, transferring ownership in the process. 1634 /// 1635 /// \code 1636 /// NSString *str = (__bridge_transfer NSString *)CFCreateString(); 1637 /// \endcode 1638 class ObjCBridgedCastExpr final 1639 : public ExplicitCastExpr, 1640 private llvm::TrailingObjects<ObjCBridgedCastExpr, CXXBaseSpecifier *> { 1641 friend class ASTStmtReader; 1642 friend class ASTStmtWriter; 1643 friend class CastExpr; 1644 friend TrailingObjects; 1645 1646 SourceLocation LParenLoc; 1647 SourceLocation BridgeKeywordLoc; 1648 unsigned Kind : 2; 1649 1650 public: ObjCBridgedCastExpr(SourceLocation LParenLoc,ObjCBridgeCastKind Kind,CastKind CK,SourceLocation BridgeKeywordLoc,TypeSourceInfo * TSInfo,Expr * Operand)1651 ObjCBridgedCastExpr(SourceLocation LParenLoc, ObjCBridgeCastKind Kind, 1652 CastKind CK, SourceLocation BridgeKeywordLoc, 1653 TypeSourceInfo *TSInfo, Expr *Operand) 1654 : ExplicitCastExpr(ObjCBridgedCastExprClass, TSInfo->getType(), VK_RValue, 1655 CK, Operand, 0, TSInfo), 1656 LParenLoc(LParenLoc), BridgeKeywordLoc(BridgeKeywordLoc), Kind(Kind) {} 1657 1658 /// Construct an empty Objective-C bridged cast. ObjCBridgedCastExpr(EmptyShell Shell)1659 explicit ObjCBridgedCastExpr(EmptyShell Shell) 1660 : ExplicitCastExpr(ObjCBridgedCastExprClass, Shell, 0) {} 1661 getLParenLoc()1662 SourceLocation getLParenLoc() const { return LParenLoc; } 1663 1664 /// Determine which kind of bridge is being performed via this cast. getBridgeKind()1665 ObjCBridgeCastKind getBridgeKind() const { 1666 return static_cast<ObjCBridgeCastKind>(Kind); 1667 } 1668 1669 /// Retrieve the kind of bridge being performed as a string. 1670 StringRef getBridgeKindName() const; 1671 1672 /// The location of the bridge keyword. getBridgeKeywordLoc()1673 SourceLocation getBridgeKeywordLoc() const { return BridgeKeywordLoc; } 1674 getBeginLoc()1675 SourceLocation getBeginLoc() const LLVM_READONLY { return LParenLoc; } 1676 getEndLoc()1677 SourceLocation getEndLoc() const LLVM_READONLY { 1678 return getSubExpr()->getEndLoc(); 1679 } 1680 classof(const Stmt * T)1681 static bool classof(const Stmt *T) { 1682 return T->getStmtClass() == ObjCBridgedCastExprClass; 1683 } 1684 }; 1685 1686 /// A runtime availability query. 1687 /// 1688 /// There are 2 ways to spell this node: 1689 /// \code 1690 /// @available(macos 10.10, ios 8, *); // Objective-C 1691 /// __builtin_available(macos 10.10, ios 8, *); // C, C++, and Objective-C 1692 /// \endcode 1693 /// 1694 /// Note that we only need to keep track of one \c VersionTuple here, which is 1695 /// the one that corresponds to the current deployment target. This is meant to 1696 /// be used in the condition of an \c if, but it is also usable as top level 1697 /// expressions. 1698 /// 1699 class ObjCAvailabilityCheckExpr : public Expr { 1700 friend class ASTStmtReader; 1701 1702 VersionTuple VersionToCheck; 1703 SourceLocation AtLoc, RParen; 1704 1705 public: ObjCAvailabilityCheckExpr(VersionTuple VersionToCheck,SourceLocation AtLoc,SourceLocation RParen,QualType Ty)1706 ObjCAvailabilityCheckExpr(VersionTuple VersionToCheck, SourceLocation AtLoc, 1707 SourceLocation RParen, QualType Ty) 1708 : Expr(ObjCAvailabilityCheckExprClass, Ty, VK_RValue, OK_Ordinary, false, 1709 false, false, false), 1710 VersionToCheck(VersionToCheck), AtLoc(AtLoc), RParen(RParen) {} 1711 ObjCAvailabilityCheckExpr(EmptyShell Shell)1712 explicit ObjCAvailabilityCheckExpr(EmptyShell Shell) 1713 : Expr(ObjCAvailabilityCheckExprClass, Shell) {} 1714 getBeginLoc()1715 SourceLocation getBeginLoc() const { return AtLoc; } getEndLoc()1716 SourceLocation getEndLoc() const { return RParen; } getSourceRange()1717 SourceRange getSourceRange() const { return {AtLoc, RParen}; } 1718 1719 /// This may be '*', in which case this should fold to true. hasVersion()1720 bool hasVersion() const { return !VersionToCheck.empty(); } getVersion()1721 VersionTuple getVersion() { return VersionToCheck; } 1722 children()1723 child_range children() { 1724 return child_range(child_iterator(), child_iterator()); 1725 } 1726 children()1727 const_child_range children() const { 1728 return const_child_range(const_child_iterator(), const_child_iterator()); 1729 } 1730 classof(const Stmt * T)1731 static bool classof(const Stmt *T) { 1732 return T->getStmtClass() == ObjCAvailabilityCheckExprClass; 1733 } 1734 }; 1735 1736 } // namespace clang 1737 1738 #endif // LLVM_CLANG_AST_EXPROBJC_H 1739