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