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