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