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