clang API Documentation

ExprObjC.h
Go to the documentation of this file.
00001 //===--- ExprObjC.h - Classes for representing ObjC expressions -*- C++ -*-===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 //  This file defines the ExprObjC interface and subclasses.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #ifndef LLVM_CLANG_AST_EXPROBJC_H
00015 #define LLVM_CLANG_AST_EXPROBJC_H
00016 
00017 #include "clang/AST/DeclObjC.h"
00018 #include "clang/AST/Expr.h"
00019 #include "clang/AST/SelectorLocationsKind.h"
00020 #include "clang/Basic/IdentifierTable.h"
00021 #include "llvm/Support/Compiler.h"
00022 
00023 namespace clang {
00024   class IdentifierInfo;
00025   class ASTContext;
00026 
00027 /// ObjCStringLiteral, used for Objective-C string literals
00028 /// i.e. @"foo".
00029 class ObjCStringLiteral : public Expr {
00030   Stmt *String;
00031   SourceLocation AtLoc;
00032 public:
00033   ObjCStringLiteral(StringLiteral *SL, QualType T, SourceLocation L)
00034     : Expr(ObjCStringLiteralClass, T, VK_RValue, OK_Ordinary, false, false,
00035            false, false),
00036       String(SL), AtLoc(L) {}
00037   explicit ObjCStringLiteral(EmptyShell Empty)
00038     : Expr(ObjCStringLiteralClass, Empty) {}
00039 
00040   StringLiteral *getString() { return cast<StringLiteral>(String); }
00041   const StringLiteral *getString() const { return cast<StringLiteral>(String); }
00042   void setString(StringLiteral *S) { String = S; }
00043 
00044   SourceLocation getAtLoc() const { return AtLoc; }
00045   void setAtLoc(SourceLocation L) { AtLoc = L; }
00046 
00047   SourceRange getSourceRange() const LLVM_READONLY {
00048     return SourceRange(AtLoc, String->getLocEnd());
00049   }
00050 
00051   static bool classof(const Stmt *T) {
00052     return T->getStmtClass() == ObjCStringLiteralClass;
00053   }
00054   static bool classof(const ObjCStringLiteral *) { return true; }
00055 
00056   // Iterators
00057   child_range children() { return child_range(&String, &String+1); }
00058 };
00059 
00060 /// ObjCBoolLiteralExpr - Objective-C Boolean Literal.
00061 ///
00062 class ObjCBoolLiteralExpr : public Expr {
00063   bool Value;
00064   SourceLocation Loc;
00065 public:
00066   ObjCBoolLiteralExpr(bool val, QualType Ty, SourceLocation l) :
00067   Expr(ObjCBoolLiteralExprClass, Ty, VK_RValue, OK_Ordinary, false, false,
00068        false, false), Value(val), Loc(l) {}
00069     
00070   explicit ObjCBoolLiteralExpr(EmptyShell Empty)
00071   : Expr(ObjCBoolLiteralExprClass, Empty) { }
00072     
00073   bool getValue() const { return Value; }
00074   void setValue(bool V) { Value = V; }
00075     
00076   SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(Loc); }
00077     
00078   SourceLocation getLocation() const { return Loc; }
00079   void setLocation(SourceLocation L) { Loc = L; }
00080     
00081   static bool classof(const Stmt *T) {
00082     return T->getStmtClass() == ObjCBoolLiteralExprClass;
00083   }
00084   static bool classof(const ObjCBoolLiteralExpr *) { return true; }
00085     
00086   // Iterators
00087   child_range children() { return child_range(); }
00088 };
00089 
00090 /// ObjCBoxedExpr - used for generalized expression boxing.
00091 /// as in: @(strdup("hello world")) or @(random())
00092 /// Also used for boxing non-parenthesized numeric literals;
00093 /// as in: @42 or @true (c++/objc++) or @__yes (c/objc).
00094 class ObjCBoxedExpr : public Expr {
00095   Stmt *SubExpr;
00096   ObjCMethodDecl *BoxingMethod;
00097   SourceRange Range;
00098 public:
00099   ObjCBoxedExpr(Expr *E, QualType T, ObjCMethodDecl *method,
00100                      SourceRange R)
00101   : Expr(ObjCBoxedExprClass, T, VK_RValue, OK_Ordinary, 
00102          E->isTypeDependent(), E->isValueDependent(), 
00103          E->isInstantiationDependent(), E->containsUnexpandedParameterPack()), 
00104          SubExpr(E), BoxingMethod(method), Range(R) {}
00105   explicit ObjCBoxedExpr(EmptyShell Empty)
00106   : Expr(ObjCBoxedExprClass, Empty) {}
00107   
00108   Expr *getSubExpr() { return cast<Expr>(SubExpr); }
00109   const Expr *getSubExpr() const { return cast<Expr>(SubExpr); }
00110   
00111   ObjCMethodDecl *getBoxingMethod() const {
00112     return BoxingMethod; 
00113   }
00114   
00115   SourceLocation getAtLoc() const { return Range.getBegin(); }
00116   
00117   SourceRange getSourceRange() const LLVM_READONLY {
00118     return Range;
00119   }
00120   
00121   static bool classof(const Stmt *T) {
00122     return T->getStmtClass() == ObjCBoxedExprClass;
00123   }
00124   static bool classof(const ObjCBoxedExpr *) { return true; }
00125   
00126   // Iterators
00127   child_range children() { return child_range(&SubExpr, &SubExpr+1); }
00128   
00129   friend class ASTStmtReader;
00130 };
00131 
00132 /// ObjCArrayLiteral - used for objective-c array containers; as in:
00133 /// @[@"Hello", NSApp, [NSNumber numberWithInt:42]];
00134 class ObjCArrayLiteral : public Expr {
00135   unsigned NumElements;
00136   SourceRange Range;
00137   ObjCMethodDecl *ArrayWithObjectsMethod;
00138   
00139   ObjCArrayLiteral(llvm::ArrayRef<Expr *> Elements,
00140                    QualType T, ObjCMethodDecl * Method,
00141                    SourceRange SR);
00142   
00143   explicit ObjCArrayLiteral(EmptyShell Empty, unsigned NumElements)
00144     : Expr(ObjCArrayLiteralClass, Empty), NumElements(NumElements) {}
00145 
00146 public:
00147   static ObjCArrayLiteral *Create(ASTContext &C, 
00148                                   llvm::ArrayRef<Expr *> Elements,
00149                                   QualType T, ObjCMethodDecl * Method,
00150                                   SourceRange SR);
00151 
00152   static ObjCArrayLiteral *CreateEmpty(ASTContext &C, unsigned NumElements);
00153 
00154   SourceRange getSourceRange() const LLVM_READONLY { return Range; }
00155 
00156   static bool classof(const Stmt *T) {
00157       return T->getStmtClass() == ObjCArrayLiteralClass;
00158   }
00159   static bool classof(const ObjCArrayLiteral *) { return true; }
00160 
00161   /// \brief Retrieve elements of array of literals.
00162   Expr **getElements() { return reinterpret_cast<Expr **>(this + 1); }
00163 
00164   /// \brief Retrieve elements of array of literals.
00165   const Expr * const *getElements() const { 
00166     return reinterpret_cast<const Expr * const*>(this + 1); 
00167   }
00168 
00169   /// getNumElements - Return number of elements of objective-c array literal.
00170   unsigned getNumElements() const { return NumElements; }
00171     
00172     /// getExpr - Return the Expr at the specified index.
00173   Expr *getElement(unsigned Index) {
00174     assert((Index < NumElements) && "Arg access out of range!");
00175     return cast<Expr>(getElements()[Index]);
00176   }
00177   const Expr *getElement(unsigned Index) const {
00178     assert((Index < NumElements) && "Arg access out of range!");
00179     return cast<Expr>(getElements()[Index]);
00180   }
00181     
00182   ObjCMethodDecl *getArrayWithObjectsMethod() const {
00183     return ArrayWithObjectsMethod; 
00184   }
00185     
00186   // Iterators
00187   child_range children() { 
00188     return child_range((Stmt **)getElements(), 
00189                        (Stmt **)getElements() + NumElements);
00190   }
00191     
00192   friend class ASTStmtReader;
00193 };
00194 
00195 /// \brief An element in an Objective-C dictionary literal.
00196 ///
00197 struct ObjCDictionaryElement {
00198   /// \brief The key for the dictionary element.
00199   Expr *Key;
00200   
00201   /// \brief The value of the dictionary element.
00202   Expr *Value;
00203   
00204   /// \brief The location of the ellipsis, if this is a pack expansion.
00205   SourceLocation EllipsisLoc;
00206   
00207   /// \brief The number of elements this pack expansion will expand to, if
00208   /// this is a pack expansion and is known.
00209   llvm::Optional<unsigned> NumExpansions;
00210 
00211   /// \brief Determines whether this dictionary element is a pack expansion.
00212   bool isPackExpansion() const { return EllipsisLoc.isValid(); }
00213 };
00214 
00215 /// ObjCDictionaryLiteral - AST node to represent objective-c dictionary 
00216 /// literals; as in:  @{@"name" : NSUserName(), @"date" : [NSDate date] };
00217 class ObjCDictionaryLiteral : public Expr {
00218   /// \brief Key/value pair used to store the key and value of a given element.
00219   ///
00220   /// Objects of this type are stored directly after the expression.
00221   struct KeyValuePair {
00222     Expr *Key;
00223     Expr *Value;
00224   };
00225   
00226   /// \brief Data that describes an element that is a pack expansion, used if any
00227   /// of the elements in the dictionary literal are pack expansions.
00228   struct ExpansionData {
00229     /// \brief The location of the ellipsis, if this element is a pack
00230     /// expansion.
00231     SourceLocation EllipsisLoc;
00232 
00233     /// \brief If non-zero, the number of elements that this pack
00234     /// expansion will expand to (+1).
00235     unsigned NumExpansionsPlusOne;
00236   };
00237 
00238   /// \brief The number of elements in this dictionary literal.
00239   unsigned NumElements : 31;
00240   
00241   /// \brief Determine whether this dictionary literal has any pack expansions.
00242   ///
00243   /// If the dictionary literal has pack expansions, then there will
00244   /// be an array of pack expansion data following the array of
00245   /// key/value pairs, which provide the locations of the ellipses (if
00246   /// any) and number of elements in the expansion (if known). If
00247   /// there are no pack expansions, we optimize away this storage.
00248   unsigned HasPackExpansions : 1;
00249   
00250   SourceRange Range;
00251   ObjCMethodDecl *DictWithObjectsMethod;
00252     
00253   ObjCDictionaryLiteral(ArrayRef<ObjCDictionaryElement> VK, 
00254                         bool HasPackExpansions,
00255                         QualType T, ObjCMethodDecl *method,
00256                         SourceRange SR);
00257 
00258   explicit ObjCDictionaryLiteral(EmptyShell Empty, unsigned NumElements,
00259                                  bool HasPackExpansions)
00260     : Expr(ObjCDictionaryLiteralClass, Empty), NumElements(NumElements),
00261       HasPackExpansions(HasPackExpansions) {}
00262 
00263   KeyValuePair *getKeyValues() {
00264     return reinterpret_cast<KeyValuePair *>(this + 1);
00265   }
00266   
00267   const KeyValuePair *getKeyValues() const {
00268     return reinterpret_cast<const KeyValuePair *>(this + 1);
00269   }
00270 
00271   ExpansionData *getExpansionData() {
00272     if (!HasPackExpansions)
00273       return 0;
00274     
00275     return reinterpret_cast<ExpansionData *>(getKeyValues() + NumElements);
00276   }
00277 
00278   const ExpansionData *getExpansionData() const {
00279     if (!HasPackExpansions)
00280       return 0;
00281     
00282     return reinterpret_cast<const ExpansionData *>(getKeyValues()+NumElements);
00283   }
00284 
00285 public:
00286   static ObjCDictionaryLiteral *Create(ASTContext &C,
00287                                        ArrayRef<ObjCDictionaryElement> VK, 
00288                                        bool HasPackExpansions,
00289                                        QualType T, ObjCMethodDecl *method,
00290                                        SourceRange SR);
00291   
00292   static ObjCDictionaryLiteral *CreateEmpty(ASTContext &C, 
00293                                             unsigned NumElements,
00294                                             bool HasPackExpansions);
00295   
00296   /// getNumElements - Return number of elements of objective-c dictionary 
00297   /// literal.
00298   unsigned getNumElements() const { return NumElements; }
00299 
00300   ObjCDictionaryElement getKeyValueElement(unsigned Index) const {
00301     assert((Index < NumElements) && "Arg access out of range!");
00302     const KeyValuePair &KV = getKeyValues()[Index];
00303     ObjCDictionaryElement Result = { KV.Key, KV.Value, SourceLocation(),
00304                                      llvm::Optional<unsigned>() };
00305     if (HasPackExpansions) {
00306       const ExpansionData &Expansion = getExpansionData()[Index];
00307       Result.EllipsisLoc = Expansion.EllipsisLoc;
00308       if (Expansion.NumExpansionsPlusOne > 0)
00309         Result.NumExpansions = Expansion.NumExpansionsPlusOne - 1;
00310     }
00311     return Result;
00312   }
00313     
00314   ObjCMethodDecl *getDictWithObjectsMethod() const
00315     { return DictWithObjectsMethod; }
00316 
00317   SourceRange getSourceRange() const LLVM_READONLY { return Range; }
00318   
00319   static bool classof(const Stmt *T) {
00320       return T->getStmtClass() == ObjCDictionaryLiteralClass;
00321   }
00322   static bool classof(const ObjCDictionaryLiteral *) { return true; }
00323     
00324   // Iterators
00325   child_range children() { 
00326     // Note: we're taking advantage of the layout of the KeyValuePair struct
00327     // here. If that struct changes, this code will need to change as well.
00328     return child_range(reinterpret_cast<Stmt **>(this + 1),
00329                        reinterpret_cast<Stmt **>(this + 1) + NumElements * 2);
00330   }
00331     
00332   friend class ASTStmtReader;
00333   friend class ASTStmtWriter;
00334 };
00335 
00336 
00337 /// ObjCEncodeExpr, used for @encode in Objective-C.  @encode has the same type
00338 /// and behavior as StringLiteral except that the string initializer is obtained
00339 /// from ASTContext with the encoding type as an argument.
00340 class ObjCEncodeExpr : public Expr {
00341   TypeSourceInfo *EncodedType;
00342   SourceLocation AtLoc, RParenLoc;
00343 public:
00344   ObjCEncodeExpr(QualType T, TypeSourceInfo *EncodedType,
00345                  SourceLocation at, SourceLocation rp)
00346     : Expr(ObjCEncodeExprClass, T, VK_LValue, OK_Ordinary,
00347            EncodedType->getType()->isDependentType(),
00348            EncodedType->getType()->isDependentType(),
00349            EncodedType->getType()->isInstantiationDependentType(),
00350            EncodedType->getType()->containsUnexpandedParameterPack()), 
00351       EncodedType(EncodedType), AtLoc(at), RParenLoc(rp) {}
00352 
00353   explicit ObjCEncodeExpr(EmptyShell Empty) : Expr(ObjCEncodeExprClass, Empty){}
00354 
00355 
00356   SourceLocation getAtLoc() const { return AtLoc; }
00357   void setAtLoc(SourceLocation L) { AtLoc = L; }
00358   SourceLocation getRParenLoc() const { return RParenLoc; }
00359   void setRParenLoc(SourceLocation L) { RParenLoc = L; }
00360 
00361   QualType getEncodedType() const { return EncodedType->getType(); }
00362 
00363   TypeSourceInfo *getEncodedTypeSourceInfo() const { return EncodedType; }
00364   void setEncodedTypeSourceInfo(TypeSourceInfo *EncType) { 
00365     EncodedType = EncType; 
00366   }
00367 
00368   SourceRange getSourceRange() const LLVM_READONLY {
00369     return SourceRange(AtLoc, RParenLoc);
00370   }
00371 
00372   static bool classof(const Stmt *T) {
00373     return T->getStmtClass() == ObjCEncodeExprClass;
00374   }
00375   static bool classof(const ObjCEncodeExpr *) { return true; }
00376 
00377   // Iterators
00378   child_range children() { return child_range(); }
00379 };
00380 
00381 /// ObjCSelectorExpr used for @selector in Objective-C.
00382 class ObjCSelectorExpr : public Expr {
00383   Selector SelName;
00384   SourceLocation AtLoc, RParenLoc;
00385 public:
00386   ObjCSelectorExpr(QualType T, Selector selInfo,
00387                    SourceLocation at, SourceLocation rp)
00388     : Expr(ObjCSelectorExprClass, T, VK_RValue, OK_Ordinary, false, false, 
00389            false, false),
00390     SelName(selInfo), AtLoc(at), RParenLoc(rp){}
00391   explicit ObjCSelectorExpr(EmptyShell Empty)
00392    : Expr(ObjCSelectorExprClass, Empty) {}
00393 
00394   Selector getSelector() const { return SelName; }
00395   void setSelector(Selector S) { SelName = S; }
00396 
00397   SourceLocation getAtLoc() const { return AtLoc; }
00398   SourceLocation getRParenLoc() const { return RParenLoc; }
00399   void setAtLoc(SourceLocation L) { AtLoc = L; }
00400   void setRParenLoc(SourceLocation L) { RParenLoc = L; }
00401 
00402   SourceRange getSourceRange() const LLVM_READONLY {
00403     return SourceRange(AtLoc, RParenLoc);
00404   }
00405 
00406   /// getNumArgs - Return the number of actual arguments to this call.
00407   unsigned getNumArgs() const { return SelName.getNumArgs(); }
00408 
00409   static bool classof(const Stmt *T) {
00410     return T->getStmtClass() == ObjCSelectorExprClass;
00411   }
00412   static bool classof(const ObjCSelectorExpr *) { return true; }
00413 
00414   // Iterators
00415   child_range children() { return child_range(); }
00416 };
00417 
00418 /// ObjCProtocolExpr used for protocol expression in Objective-C.  This is used
00419 /// as: @protocol(foo), as in:
00420 ///   obj conformsToProtocol:@protocol(foo)]
00421 /// The return type is "Protocol*".
00422 class ObjCProtocolExpr : public Expr {
00423   ObjCProtocolDecl *TheProtocol;
00424   SourceLocation AtLoc, ProtoLoc, RParenLoc;
00425 public:
00426   ObjCProtocolExpr(QualType T, ObjCProtocolDecl *protocol,
00427                  SourceLocation at, SourceLocation protoLoc, SourceLocation rp)
00428     : Expr(ObjCProtocolExprClass, T, VK_RValue, OK_Ordinary, false, false,
00429            false, false),
00430       TheProtocol(protocol), AtLoc(at), ProtoLoc(protoLoc), RParenLoc(rp) {}
00431   explicit ObjCProtocolExpr(EmptyShell Empty)
00432     : Expr(ObjCProtocolExprClass, Empty) {}
00433 
00434   ObjCProtocolDecl *getProtocol() const { return TheProtocol; }
00435   void setProtocol(ObjCProtocolDecl *P) { TheProtocol = P; }
00436 
00437   SourceLocation getProtocolIdLoc() const { return ProtoLoc; }
00438   SourceLocation getAtLoc() const { return AtLoc; }
00439   SourceLocation getRParenLoc() const { return RParenLoc; }
00440   void setAtLoc(SourceLocation L) { AtLoc = L; }
00441   void setRParenLoc(SourceLocation L) { RParenLoc = L; }
00442 
00443   SourceRange getSourceRange() const LLVM_READONLY {
00444     return SourceRange(AtLoc, RParenLoc);
00445   }
00446 
00447   static bool classof(const Stmt *T) {
00448     return T->getStmtClass() == ObjCProtocolExprClass;
00449   }
00450   static bool classof(const ObjCProtocolExpr *) { return true; }
00451 
00452   // Iterators
00453   child_range children() { return child_range(); }
00454 
00455   friend class ASTStmtReader;
00456   friend class ASTStmtWriter;
00457 };
00458 
00459 /// ObjCIvarRefExpr - A reference to an ObjC instance variable.
00460 class ObjCIvarRefExpr : public Expr {
00461   ObjCIvarDecl *D;
00462   Stmt *Base;
00463   SourceLocation Loc;
00464   bool IsArrow:1;      // True if this is "X->F", false if this is "X.F".
00465   bool IsFreeIvar:1;   // True if ivar reference has no base (self assumed).
00466 
00467 public:
00468   ObjCIvarRefExpr(ObjCIvarDecl *d, QualType t,
00469                   SourceLocation l, Expr *base,
00470                   bool arrow = false, bool freeIvar = false) :
00471     Expr(ObjCIvarRefExprClass, t, VK_LValue, OK_Ordinary,
00472          /*TypeDependent=*/false, base->isValueDependent(), 
00473          base->isInstantiationDependent(),
00474          base->containsUnexpandedParameterPack()), 
00475     D(d), Base(base), Loc(l), IsArrow(arrow), IsFreeIvar(freeIvar) {}
00476 
00477   explicit ObjCIvarRefExpr(EmptyShell Empty)
00478     : Expr(ObjCIvarRefExprClass, Empty) {}
00479 
00480   ObjCIvarDecl *getDecl() { return D; }
00481   const ObjCIvarDecl *getDecl() const { return D; }
00482   void setDecl(ObjCIvarDecl *d) { D = d; }
00483 
00484   const Expr *getBase() const { return cast<Expr>(Base); }
00485   Expr *getBase() { return cast<Expr>(Base); }
00486   void setBase(Expr * base) { Base = base; }
00487 
00488   bool isArrow() const { return IsArrow; }
00489   bool isFreeIvar() const { return IsFreeIvar; }
00490   void setIsArrow(bool A) { IsArrow = A; }
00491   void setIsFreeIvar(bool A) { IsFreeIvar = A; }
00492 
00493   SourceLocation getLocation() const { return Loc; }
00494   void setLocation(SourceLocation L) { Loc = L; }
00495 
00496   SourceRange getSourceRange() const LLVM_READONLY {
00497     return isFreeIvar() ? SourceRange(Loc)
00498     : SourceRange(getBase()->getLocStart(), Loc);
00499   }
00500 
00501   static bool classof(const Stmt *T) {
00502     return T->getStmtClass() == ObjCIvarRefExprClass;
00503   }
00504   static bool classof(const ObjCIvarRefExpr *) { return true; }
00505 
00506   // Iterators
00507   child_range children() { return child_range(&Base, &Base+1); }
00508 };
00509 
00510 /// ObjCPropertyRefExpr - A dot-syntax expression to access an ObjC
00511 /// property.
00512 class ObjCPropertyRefExpr : public Expr {
00513 private:
00514   /// If the bool is true, this is an implicit property reference; the
00515   /// pointer is an (optional) ObjCMethodDecl and Setter may be set.
00516   /// if the bool is false, this is an explicit property reference;
00517   /// the pointer is an ObjCPropertyDecl and Setter is always null.
00518   llvm::PointerIntPair<NamedDecl*, 1, bool> PropertyOrGetter;
00519 
00520   /// \brief Indicates whether the property reference will result in a message
00521   /// to the getter, the setter, or both.
00522   /// This applies to both implicit and explicit property references.
00523   enum MethodRefFlags {
00524     MethodRef_None = 0,
00525     MethodRef_Getter = 0x1,
00526     MethodRef_Setter = 0x2
00527   };
00528 
00529   /// \brief Contains the Setter method pointer and MethodRefFlags bit flags.
00530   llvm::PointerIntPair<ObjCMethodDecl *, 2, unsigned> SetterAndMethodRefFlags;
00531 
00532   // FIXME: Maybe we should store the property identifier here,
00533   // because it's not rederivable from the other data when there's an
00534   // implicit property with no getter (because the 'foo' -> 'setFoo:'
00535   // transformation is lossy on the first character).
00536 
00537   SourceLocation IdLoc;
00538   
00539   /// \brief When the receiver in property access is 'super', this is
00540   /// the location of the 'super' keyword.  When it's an interface,
00541   /// this is that interface.
00542   SourceLocation ReceiverLoc;
00543   llvm::PointerUnion3<Stmt*, const Type*, ObjCInterfaceDecl*> Receiver;
00544   
00545 public:
00546   ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t,
00547                       ExprValueKind VK, ExprObjectKind OK,
00548                       SourceLocation l, Expr *base)
00549     : Expr(ObjCPropertyRefExprClass, t, VK, OK,
00550            /*TypeDependent=*/false, base->isValueDependent(),
00551            base->isInstantiationDependent(),
00552            base->containsUnexpandedParameterPack()),
00553       PropertyOrGetter(PD, false), SetterAndMethodRefFlags(),
00554       IdLoc(l), ReceiverLoc(), Receiver(base) {
00555     assert(t->isSpecificPlaceholderType(BuiltinType::PseudoObject));
00556   }
00557   
00558   ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t,
00559                       ExprValueKind VK, ExprObjectKind OK,
00560                       SourceLocation l, SourceLocation sl, QualType st)
00561     : Expr(ObjCPropertyRefExprClass, t, VK, OK,
00562            /*TypeDependent=*/false, false, st->isInstantiationDependentType(),
00563            st->containsUnexpandedParameterPack()),
00564       PropertyOrGetter(PD, false), SetterAndMethodRefFlags(),
00565       IdLoc(l), ReceiverLoc(sl), Receiver(st.getTypePtr()) {
00566     assert(t->isSpecificPlaceholderType(BuiltinType::PseudoObject));
00567   }
00568 
00569   ObjCPropertyRefExpr(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter,
00570                       QualType T, ExprValueKind VK, ExprObjectKind OK,
00571                       SourceLocation IdLoc, Expr *Base)
00572     : Expr(ObjCPropertyRefExprClass, T, VK, OK, false,
00573            Base->isValueDependent(), Base->isInstantiationDependent(),
00574            Base->containsUnexpandedParameterPack()),
00575       PropertyOrGetter(Getter, true), SetterAndMethodRefFlags(Setter, 0),
00576       IdLoc(IdLoc), ReceiverLoc(), Receiver(Base) {
00577     assert(T->isSpecificPlaceholderType(BuiltinType::PseudoObject));
00578   }
00579 
00580   ObjCPropertyRefExpr(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter,
00581                       QualType T, ExprValueKind VK, ExprObjectKind OK,
00582                       SourceLocation IdLoc,
00583                       SourceLocation SuperLoc, QualType SuperTy)
00584     : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, false, false, false),
00585       PropertyOrGetter(Getter, true), SetterAndMethodRefFlags(Setter, 0),
00586       IdLoc(IdLoc), ReceiverLoc(SuperLoc), Receiver(SuperTy.getTypePtr()) {
00587     assert(T->isSpecificPlaceholderType(BuiltinType::PseudoObject));
00588   }
00589 
00590   ObjCPropertyRefExpr(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter,
00591                       QualType T, ExprValueKind VK, ExprObjectKind OK,
00592                       SourceLocation IdLoc,
00593                       SourceLocation ReceiverLoc, ObjCInterfaceDecl *Receiver)
00594     : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, false, false, false),
00595       PropertyOrGetter(Getter, true), SetterAndMethodRefFlags(Setter, 0),
00596       IdLoc(IdLoc), ReceiverLoc(ReceiverLoc), Receiver(Receiver) {
00597     assert(T->isSpecificPlaceholderType(BuiltinType::PseudoObject));
00598   }
00599 
00600   explicit ObjCPropertyRefExpr(EmptyShell Empty)
00601     : Expr(ObjCPropertyRefExprClass, Empty) {}
00602 
00603   bool isImplicitProperty() const { return PropertyOrGetter.getInt(); }
00604   bool isExplicitProperty() const { return !PropertyOrGetter.getInt(); }
00605 
00606   ObjCPropertyDecl *getExplicitProperty() const {
00607     assert(!isImplicitProperty());
00608     return cast<ObjCPropertyDecl>(PropertyOrGetter.getPointer());
00609   }
00610 
00611   ObjCMethodDecl *getImplicitPropertyGetter() const {
00612     assert(isImplicitProperty());
00613     return cast_or_null<ObjCMethodDecl>(PropertyOrGetter.getPointer());
00614   }
00615 
00616   ObjCMethodDecl *getImplicitPropertySetter() const {
00617     assert(isImplicitProperty());
00618     return SetterAndMethodRefFlags.getPointer();
00619   }
00620 
00621   Selector getGetterSelector() const {
00622     if (isImplicitProperty())
00623       return getImplicitPropertyGetter()->getSelector();
00624     return getExplicitProperty()->getGetterName();
00625   }
00626 
00627   Selector getSetterSelector() const {
00628     if (isImplicitProperty())
00629       return getImplicitPropertySetter()->getSelector();
00630     return getExplicitProperty()->getSetterName();
00631   }
00632 
00633   /// \brief True if the property reference will result in a message to the
00634   /// getter.
00635   /// This applies to both implicit and explicit property references.
00636   bool isMessagingGetter() const {
00637     return SetterAndMethodRefFlags.getInt() & MethodRef_Getter;
00638   }
00639 
00640   /// \brief True if the property reference will result in a message to the
00641   /// setter.
00642   /// This applies to both implicit and explicit property references.
00643   bool isMessagingSetter() const {
00644     return SetterAndMethodRefFlags.getInt() & MethodRef_Setter;
00645   }
00646 
00647   void setIsMessagingGetter(bool val = true) {
00648     setMethodRefFlag(MethodRef_Getter, val);
00649   }
00650 
00651   void setIsMessagingSetter(bool val = true) {
00652     setMethodRefFlag(MethodRef_Setter, val);
00653   }
00654 
00655   const Expr *getBase() const { 
00656     return cast<Expr>(Receiver.get<Stmt*>()); 
00657   }
00658   Expr *getBase() { 
00659     return cast<Expr>(Receiver.get<Stmt*>()); 
00660   }
00661 
00662   SourceLocation getLocation() const { return IdLoc; }
00663   
00664   SourceLocation getReceiverLocation() const { return ReceiverLoc; }
00665   QualType getSuperReceiverType() const { 
00666     return QualType(Receiver.get<const Type*>(), 0); 
00667   }
00668   QualType getGetterResultType() const {
00669     QualType ResultType;
00670     if (isExplicitProperty()) {
00671       const ObjCPropertyDecl *PDecl = getExplicitProperty();
00672       if (const ObjCMethodDecl *Getter = PDecl->getGetterMethodDecl())
00673         ResultType = Getter->getResultType();
00674       else
00675         ResultType = PDecl->getType();
00676     } else {
00677       const ObjCMethodDecl *Getter = getImplicitPropertyGetter();
00678       if (Getter)
00679         ResultType = Getter->getResultType(); // with reference!
00680     }
00681     return ResultType;
00682   }
00683 
00684   QualType getSetterArgType() const {
00685     QualType ArgType;
00686     if (isImplicitProperty()) {
00687       const ObjCMethodDecl *Setter = getImplicitPropertySetter();
00688       ObjCMethodDecl::param_const_iterator P = Setter->param_begin(); 
00689       ArgType = (*P)->getType();
00690     } else {
00691       if (ObjCPropertyDecl *PDecl = getExplicitProperty())
00692         if (const ObjCMethodDecl *Setter = PDecl->getSetterMethodDecl()) {
00693           ObjCMethodDecl::param_const_iterator P = Setter->param_begin(); 
00694           ArgType = (*P)->getType();
00695         }
00696       if (ArgType.isNull())
00697         ArgType = getType();
00698     }
00699     return ArgType;
00700   }
00701   
00702   ObjCInterfaceDecl *getClassReceiver() const {
00703     return Receiver.get<ObjCInterfaceDecl*>();
00704   }
00705   bool isObjectReceiver() const { return Receiver.is<Stmt*>(); }
00706   bool isSuperReceiver() const { return Receiver.is<const Type*>(); }
00707   bool isClassReceiver() const { return Receiver.is<ObjCInterfaceDecl*>(); }
00708 
00709   SourceRange getSourceRange() const LLVM_READONLY {
00710     return SourceRange((isObjectReceiver() ? getBase()->getLocStart()
00711                                            : getReceiverLocation()), 
00712                        IdLoc);
00713   }
00714 
00715   static bool classof(const Stmt *T) {
00716     return T->getStmtClass() == ObjCPropertyRefExprClass;
00717   }
00718   static bool classof(const ObjCPropertyRefExpr *) { return true; }
00719 
00720   // Iterators
00721   child_range children() {
00722     if (Receiver.is<Stmt*>()) {
00723       Stmt **begin = reinterpret_cast<Stmt**>(&Receiver); // hack!
00724       return child_range(begin, begin+1);
00725     }
00726     return child_range();
00727   }
00728 
00729 private:
00730   friend class ASTStmtReader;
00731   friend class ASTStmtWriter;
00732   void setExplicitProperty(ObjCPropertyDecl *D, unsigned methRefFlags) {
00733     PropertyOrGetter.setPointer(D);
00734     PropertyOrGetter.setInt(false);
00735     SetterAndMethodRefFlags.setPointer(0);
00736     SetterAndMethodRefFlags.setInt(methRefFlags);
00737   }
00738   void setImplicitProperty(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter,
00739                            unsigned methRefFlags) {
00740     PropertyOrGetter.setPointer(Getter);
00741     PropertyOrGetter.setInt(true);
00742     SetterAndMethodRefFlags.setPointer(Setter);
00743     SetterAndMethodRefFlags.setInt(methRefFlags);
00744   }
00745   void setBase(Expr *Base) { Receiver = Base; }
00746   void setSuperReceiver(QualType T) { Receiver = T.getTypePtr(); }
00747   void setClassReceiver(ObjCInterfaceDecl *D) { Receiver = D; }
00748 
00749   void setLocation(SourceLocation L) { IdLoc = L; }
00750   void setReceiverLocation(SourceLocation Loc) { ReceiverLoc = Loc; }
00751 
00752   void setMethodRefFlag(MethodRefFlags flag, bool val) {
00753     unsigned f = SetterAndMethodRefFlags.getInt();
00754     if (val)
00755       f |= flag;
00756     else
00757       f &= ~flag;
00758     SetterAndMethodRefFlags.setInt(f);
00759   }
00760 };
00761   
00762 /// ObjCSubscriptRefExpr - used for array and dictionary subscripting.
00763 /// array[4] = array[3]; dictionary[key] = dictionary[alt_key];
00764 ///
00765 class ObjCSubscriptRefExpr : public Expr {
00766   // Location of ']' in an indexing expression.
00767   SourceLocation RBracket;
00768   // array/dictionary base expression.
00769   // for arrays, this is a numeric expression. For dictionaries, this is
00770   // an objective-c object pointer expression.
00771   enum { BASE, KEY, END_EXPR };
00772   Stmt* SubExprs[END_EXPR];
00773   
00774   ObjCMethodDecl *GetAtIndexMethodDecl;
00775   
00776   // For immutable objects this is null. When ObjCSubscriptRefExpr is to read
00777   // an indexed object this is null too.
00778   ObjCMethodDecl *SetAtIndexMethodDecl;
00779   
00780 public:
00781   
00782   ObjCSubscriptRefExpr(Expr *base, Expr *key, QualType T,
00783                        ExprValueKind VK, ExprObjectKind OK,
00784                        ObjCMethodDecl *getMethod,
00785                        ObjCMethodDecl *setMethod, SourceLocation RB)
00786     : Expr(ObjCSubscriptRefExprClass, T, VK, OK, 
00787            base->isTypeDependent() || key->isTypeDependent(), 
00788            base->isValueDependent() || key->isValueDependent(),
00789            base->isInstantiationDependent() || key->isInstantiationDependent(),
00790            (base->containsUnexpandedParameterPack() ||
00791             key->containsUnexpandedParameterPack())),
00792       RBracket(RB), 
00793   GetAtIndexMethodDecl(getMethod), 
00794   SetAtIndexMethodDecl(setMethod) 
00795     {SubExprs[BASE] = base; SubExprs[KEY] = key;}
00796 
00797   explicit ObjCSubscriptRefExpr(EmptyShell Empty)
00798     : Expr(ObjCSubscriptRefExprClass, Empty) {}
00799   
00800   static ObjCSubscriptRefExpr *Create(ASTContext &C,
00801                                       Expr *base,
00802                                       Expr *key, QualType T, 
00803                                       ObjCMethodDecl *getMethod,
00804                                       ObjCMethodDecl *setMethod, 
00805                                       SourceLocation RB);
00806   
00807   SourceLocation getRBracket() const { return RBracket; }
00808   void setRBracket(SourceLocation RB) { RBracket = RB; }
00809   SourceRange getSourceRange() const LLVM_READONLY {
00810     return SourceRange(SubExprs[BASE]->getLocStart(), RBracket);
00811   }
00812   
00813   static bool classof(const Stmt *T) {
00814     return T->getStmtClass() == ObjCSubscriptRefExprClass;
00815   }
00816   static bool classof(const ObjCSubscriptRefExpr *) { return true; }
00817   
00818   Expr *getBaseExpr() const { return cast<Expr>(SubExprs[BASE]); }
00819   void setBaseExpr(Stmt *S) { SubExprs[BASE] = S; }
00820   
00821   Expr *getKeyExpr() const { return cast<Expr>(SubExprs[KEY]); }
00822   void setKeyExpr(Stmt *S) { SubExprs[KEY] = S; }
00823   
00824   ObjCMethodDecl *getAtIndexMethodDecl() const {
00825     return GetAtIndexMethodDecl;
00826   }
00827  
00828   ObjCMethodDecl *setAtIndexMethodDecl() const {
00829     return SetAtIndexMethodDecl;
00830   }
00831   
00832   bool isArraySubscriptRefExpr() const {
00833     return getKeyExpr()->getType()->isIntegralOrEnumerationType();
00834   }
00835   
00836   child_range children() {
00837     return child_range(SubExprs, SubExprs+END_EXPR);
00838   }
00839 private:
00840   friend class ASTStmtReader;
00841 };
00842   
00843 
00844 /// \brief An expression that sends a message to the given Objective-C
00845 /// object or class.
00846 ///
00847 /// The following contains two message send expressions:
00848 ///
00849 /// \code
00850 ///   [[NSString alloc] initWithString:@"Hello"]
00851 /// \endcode
00852 ///
00853 /// The innermost message send invokes the "alloc" class method on the
00854 /// NSString class, while the outermost message send invokes the
00855 /// "initWithString" instance method on the object returned from
00856 /// NSString's "alloc". In all, an Objective-C message send can take
00857 /// on four different (although related) forms:
00858 ///
00859 ///   1. Send to an object instance.
00860 ///   2. Send to a class.
00861 ///   3. Send to the superclass instance of the current class.
00862 ///   4. Send to the superclass of the current class.
00863 ///
00864 /// All four kinds of message sends are modeled by the ObjCMessageExpr
00865 /// class, and can be distinguished via \c getReceiverKind(). Example:
00866 ///
00867 class ObjCMessageExpr : public Expr {
00868   /// \brief Stores either the selector that this message is sending
00869   /// to (when \c HasMethod is zero) or an \c ObjCMethodDecl pointer
00870   /// referring to the method that we type-checked against.
00871   uintptr_t SelectorOrMethod;
00872 
00873   enum { NumArgsBitWidth = 16 };
00874 
00875   /// \brief The number of arguments in the message send, not
00876   /// including the receiver.
00877   unsigned NumArgs : NumArgsBitWidth;
00878   
00879   void setNumArgs(unsigned Num) {
00880     assert((Num >> NumArgsBitWidth) == 0 && "Num of args is out of range!");
00881     NumArgs = Num;
00882   }
00883 
00884   /// \brief The kind of message send this is, which is one of the
00885   /// ReceiverKind values.
00886   ///
00887   /// We pad this out to a byte to avoid excessive masking and shifting.
00888   unsigned Kind : 8;
00889 
00890   /// \brief Whether we have an actual method prototype in \c
00891   /// SelectorOrMethod.
00892   ///
00893   /// When non-zero, we have a method declaration; otherwise, we just
00894   /// have a selector.
00895   unsigned HasMethod : 1;
00896 
00897   /// \brief Whether this message send is a "delegate init call",
00898   /// i.e. a call of an init method on self from within an init method.
00899   unsigned IsDelegateInitCall : 1;
00900 
00901   /// \brief Whether this message send was implicitly generated by
00902   /// the implementation rather than explicitly written by the user.
00903   unsigned IsImplicit : 1;
00904 
00905   /// \brief Whether the locations of the selector identifiers are in a
00906   /// "standard" position, a enum SelectorLocationsKind.
00907   unsigned SelLocsKind : 2;
00908 
00909   /// \brief When the message expression is a send to 'super', this is
00910   /// the location of the 'super' keyword.
00911   SourceLocation SuperLoc;
00912 
00913   /// \brief The source locations of the open and close square
00914   /// brackets ('[' and ']', respectively).
00915   SourceLocation LBracLoc, RBracLoc;
00916 
00917   ObjCMessageExpr(EmptyShell Empty, unsigned NumArgs)
00918     : Expr(ObjCMessageExprClass, Empty), SelectorOrMethod(0), Kind(0), 
00919       HasMethod(0), IsDelegateInitCall(0), IsImplicit(0), SelLocsKind(0) {
00920     setNumArgs(NumArgs);
00921   }
00922 
00923   ObjCMessageExpr(QualType T, ExprValueKind VK,
00924                   SourceLocation LBracLoc,
00925                   SourceLocation SuperLoc,
00926                   bool IsInstanceSuper,
00927                   QualType SuperType,
00928                   Selector Sel, 
00929                   ArrayRef<SourceLocation> SelLocs,
00930                   SelectorLocationsKind SelLocsK,
00931                   ObjCMethodDecl *Method,
00932                   ArrayRef<Expr *> Args,
00933                   SourceLocation RBracLoc,
00934                   bool isImplicit);
00935   ObjCMessageExpr(QualType T, ExprValueKind VK,
00936                   SourceLocation LBracLoc,
00937                   TypeSourceInfo *Receiver,
00938                   Selector Sel, 
00939                   ArrayRef<SourceLocation> SelLocs,
00940                   SelectorLocationsKind SelLocsK,
00941                   ObjCMethodDecl *Method,
00942                   ArrayRef<Expr *> Args,
00943                   SourceLocation RBracLoc,
00944                   bool isImplicit);
00945   ObjCMessageExpr(QualType T, ExprValueKind VK,
00946                   SourceLocation LBracLoc,
00947                   Expr *Receiver,
00948                   Selector Sel, 
00949                   ArrayRef<SourceLocation> SelLocs,
00950                   SelectorLocationsKind SelLocsK,
00951                   ObjCMethodDecl *Method,
00952                   ArrayRef<Expr *> Args,
00953                   SourceLocation RBracLoc,
00954                   bool isImplicit);
00955 
00956   void initArgsAndSelLocs(ArrayRef<Expr *> Args,
00957                           ArrayRef<SourceLocation> SelLocs,
00958                           SelectorLocationsKind SelLocsK);
00959 
00960   /// \brief Retrieve the pointer value of the message receiver.
00961   void *getReceiverPointer() const {
00962     return *const_cast<void **>(
00963                              reinterpret_cast<const void * const*>(this + 1));
00964   }
00965 
00966   /// \brief Set the pointer value of the message receiver.
00967   void setReceiverPointer(void *Value) {
00968     *reinterpret_cast<void **>(this + 1) = Value;
00969   }
00970 
00971   SelectorLocationsKind getSelLocsKind() const {
00972     return (SelectorLocationsKind)SelLocsKind;
00973   }
00974   bool hasStandardSelLocs() const {
00975     return getSelLocsKind() != SelLoc_NonStandard;
00976   }
00977 
00978   /// \brief Get a pointer to the stored selector identifiers locations array.
00979   /// No locations will be stored if HasStandardSelLocs is true.
00980   SourceLocation *getStoredSelLocs() {
00981     return reinterpret_cast<SourceLocation*>(getArgs() + getNumArgs());
00982   }
00983   const SourceLocation *getStoredSelLocs() const {
00984     return reinterpret_cast<const SourceLocation*>(getArgs() + getNumArgs());
00985   }
00986 
00987   /// \brief Get the number of stored selector identifiers locations.
00988   /// No locations will be stored if HasStandardSelLocs is true.
00989   unsigned getNumStoredSelLocs() const {
00990     if (hasStandardSelLocs())
00991       return 0;
00992     return getNumSelectorLocs();
00993   }
00994 
00995   static ObjCMessageExpr *alloc(ASTContext &C,
00996                                 ArrayRef<Expr *> Args,
00997                                 SourceLocation RBraceLoc,
00998                                 ArrayRef<SourceLocation> SelLocs,
00999                                 Selector Sel,
01000                                 SelectorLocationsKind &SelLocsK);
01001   static ObjCMessageExpr *alloc(ASTContext &C,
01002                                 unsigned NumArgs,
01003                                 unsigned NumStoredSelLocs);
01004 
01005 public:
01006   /// \brief The kind of receiver this message is sending to.
01007   enum ReceiverKind {
01008     /// \brief The receiver is a class.
01009     Class = 0,
01010     /// \brief The receiver is an object instance.
01011     Instance,
01012     /// \brief The receiver is a superclass.
01013     SuperClass,
01014     /// \brief The receiver is the instance of the superclass object.
01015     SuperInstance
01016   };
01017 
01018   /// \brief Create a message send to super.
01019   ///
01020   /// \param Context The ASTContext in which this expression will be created.
01021   ///
01022   /// \param T The result type of this message.
01023   ///
01024   /// \param VK The value kind of this message.  A message returning
01025   /// a l-value or r-value reference will be an l-value or x-value,
01026   /// respectively.
01027   ///
01028   /// \param LBrac The location of the open square bracket '['.
01029   ///
01030   /// \param SuperLoc The location of the "super" keyword.
01031   ///
01032   /// \param IsInstanceSuper Whether this is an instance "super"
01033   /// message (otherwise, it's a class "super" message).
01034   ///
01035   /// \param Sel The selector used to determine which method gets called.
01036   ///
01037   /// \param Method The Objective-C method against which this message
01038   /// send was type-checked. May be NULL.
01039   ///
01040   /// \param Args The message send arguments.
01041   ///
01042   /// \param NumArgs The number of arguments.
01043   ///
01044   /// \param RBracLoc The location of the closing square bracket ']'.
01045   static ObjCMessageExpr *Create(ASTContext &Context, QualType T, 
01046                                  ExprValueKind VK,
01047                                  SourceLocation LBracLoc,
01048                                  SourceLocation SuperLoc,
01049                                  bool IsInstanceSuper,
01050                                  QualType SuperType,
01051                                  Selector Sel, 
01052                                  ArrayRef<SourceLocation> SelLocs,
01053                                  ObjCMethodDecl *Method,
01054                                  ArrayRef<Expr *> Args,
01055                                  SourceLocation RBracLoc,
01056                                  bool isImplicit);
01057 
01058   /// \brief Create a class message send.
01059   ///
01060   /// \param Context The ASTContext in which this expression will be created.
01061   ///
01062   /// \param T The result type of this message.
01063   ///
01064   /// \param VK The value kind of this message.  A message returning
01065   /// a l-value or r-value reference will be an l-value or x-value,
01066   /// respectively.
01067   ///
01068   /// \param LBrac The location of the open square bracket '['.
01069   ///
01070   /// \param Receiver The type of the receiver, including
01071   /// source-location information.
01072   ///
01073   /// \param Sel The selector used to determine which method gets called.
01074   ///
01075   /// \param Method The Objective-C method against which this message
01076   /// send was type-checked. May be NULL.
01077   ///
01078   /// \param Args The message send arguments.
01079   ///
01080   /// \param NumArgs The number of arguments.
01081   ///
01082   /// \param RBracLoc The location of the closing square bracket ']'.
01083   static ObjCMessageExpr *Create(ASTContext &Context, QualType T,
01084                                  ExprValueKind VK,
01085                                  SourceLocation LBracLoc,
01086                                  TypeSourceInfo *Receiver,
01087                                  Selector Sel, 
01088                                  ArrayRef<SourceLocation> SelLocs,
01089                                  ObjCMethodDecl *Method,
01090                                  ArrayRef<Expr *> Args,
01091                                  SourceLocation RBracLoc,
01092                                  bool isImplicit);
01093 
01094   /// \brief Create an instance message send.
01095   ///
01096   /// \param Context The ASTContext in which this expression will be created.
01097   ///
01098   /// \param T The result type of this message.
01099   ///
01100   /// \param VK The value kind of this message.  A message returning
01101   /// a l-value or r-value reference will be an l-value or x-value,
01102   /// respectively.
01103   ///
01104   /// \param LBrac The location of the open square bracket '['.
01105   ///
01106   /// \param Receiver The expression used to produce the object that
01107   /// will receive this message.
01108   ///
01109   /// \param Sel The selector used to determine which method gets called.
01110   ///
01111   /// \param Method The Objective-C method against which this message
01112   /// send was type-checked. May be NULL.
01113   ///
01114   /// \param Args The message send arguments.
01115   ///
01116   /// \param NumArgs The number of arguments.
01117   ///
01118   /// \param RBracLoc The location of the closing square bracket ']'.
01119   static ObjCMessageExpr *Create(ASTContext &Context, QualType T,
01120                                  ExprValueKind VK,
01121                                  SourceLocation LBracLoc,
01122                                  Expr *Receiver,
01123                                  Selector Sel, 
01124                                  ArrayRef<SourceLocation> SeLocs,
01125                                  ObjCMethodDecl *Method,
01126                                  ArrayRef<Expr *> Args,
01127                                  SourceLocation RBracLoc,
01128                                  bool isImplicit);
01129 
01130   /// \brief Create an empty Objective-C message expression, to be
01131   /// filled in by subsequent calls.
01132   ///
01133   /// \param Context The context in which the message send will be created.
01134   ///
01135   /// \param NumArgs The number of message arguments, not including
01136   /// the receiver.
01137   static ObjCMessageExpr *CreateEmpty(ASTContext &Context,
01138                                       unsigned NumArgs,
01139                                       unsigned NumStoredSelLocs);
01140 
01141   /// \brief Indicates whether the message send was implicitly
01142   /// generated by the implementation. If false, it was written explicitly
01143   /// in the source code.
01144   bool isImplicit() const { return IsImplicit; }
01145 
01146   /// \brief Determine the kind of receiver that this message is being
01147   /// sent to.
01148   ReceiverKind getReceiverKind() const { return (ReceiverKind)Kind; }
01149 
01150   /// \brief Source range of the receiver.
01151   SourceRange getReceiverRange() const;
01152 
01153   /// \brief Determine whether this is an instance message to either a
01154   /// computed object or to super.
01155   bool isInstanceMessage() const {
01156     return getReceiverKind() == Instance || getReceiverKind() == SuperInstance;
01157   }
01158 
01159   /// \brief Determine whether this is an class message to either a
01160   /// specified class or to super.
01161   bool isClassMessage() const {
01162     return getReceiverKind() == Class || getReceiverKind() == SuperClass;
01163   }
01164 
01165   /// \brief Returns the receiver of an instance message.
01166   ///
01167   /// \brief Returns the object expression for an instance message, or
01168   /// NULL for a message that is not an instance message.
01169   Expr *getInstanceReceiver() {
01170     if (getReceiverKind() == Instance)
01171       return static_cast<Expr *>(getReceiverPointer());
01172 
01173     return 0;
01174   }
01175   const Expr *getInstanceReceiver() const {
01176     return const_cast<ObjCMessageExpr*>(this)->getInstanceReceiver();
01177   }
01178 
01179   /// \brief Turn this message send into an instance message that
01180   /// computes the receiver object with the given expression.
01181   void setInstanceReceiver(Expr *rec) { 
01182     Kind = Instance;
01183     setReceiverPointer(rec);
01184   }
01185   
01186   /// \brief Returns the type of a class message send, or NULL if the
01187   /// message is not a class message.
01188   QualType getClassReceiver() const { 
01189     if (TypeSourceInfo *TSInfo = getClassReceiverTypeInfo())
01190       return TSInfo->getType();
01191 
01192     return QualType();
01193   }
01194 
01195   /// \brief Returns a type-source information of a class message
01196   /// send, or NULL if the message is not a class message.
01197   TypeSourceInfo *getClassReceiverTypeInfo() const {
01198     if (getReceiverKind() == Class)
01199       return reinterpret_cast<TypeSourceInfo *>(getReceiverPointer());
01200     return 0;
01201   }
01202 
01203   void setClassReceiver(TypeSourceInfo *TSInfo) {
01204     Kind = Class;
01205     setReceiverPointer(TSInfo);
01206   }
01207 
01208   /// \brief Retrieve the location of the 'super' keyword for a class
01209   /// or instance message to 'super', otherwise an invalid source location.
01210   SourceLocation getSuperLoc() const { 
01211     if (getReceiverKind() == SuperInstance || getReceiverKind() == SuperClass)
01212       return SuperLoc;
01213 
01214     return SourceLocation();
01215   }
01216 
01217   /// \brief Retrieve the Objective-C interface to which this message
01218   /// is being directed, if known.
01219   ///
01220   /// This routine cross-cuts all of the different kinds of message
01221   /// sends to determine what the underlying (statically known) type
01222   /// of the receiver will be; use \c getReceiverKind() to determine
01223   /// whether the message is a class or an instance method, whether it
01224   /// is a send to super or not, etc.
01225   ///
01226   /// \returns The Objective-C interface if known, otherwise NULL.
01227   ObjCInterfaceDecl *getReceiverInterface() const;
01228 
01229   /// \brief Retrieve the type referred to by 'super'. 
01230   ///
01231   /// The returned type will either be an ObjCInterfaceType (for an
01232   /// class message to super) or an ObjCObjectPointerType that refers
01233   /// to a class (for an instance message to super);
01234   QualType getSuperType() const {
01235     if (getReceiverKind() == SuperInstance || getReceiverKind() == SuperClass)
01236       return QualType::getFromOpaquePtr(getReceiverPointer());
01237 
01238     return QualType();
01239   }
01240 
01241   void setSuper(SourceLocation Loc, QualType T, bool IsInstanceSuper) {
01242     Kind = IsInstanceSuper? SuperInstance : SuperClass;
01243     SuperLoc = Loc;
01244     setReceiverPointer(T.getAsOpaquePtr());
01245   }
01246 
01247   Selector getSelector() const;
01248 
01249   void setSelector(Selector S) { 
01250     HasMethod = false;
01251     SelectorOrMethod = reinterpret_cast<uintptr_t>(S.getAsOpaquePtr());
01252   }
01253 
01254   const ObjCMethodDecl *getMethodDecl() const { 
01255     if (HasMethod)
01256       return reinterpret_cast<const ObjCMethodDecl *>(SelectorOrMethod);
01257 
01258     return 0;
01259   }
01260 
01261   ObjCMethodDecl *getMethodDecl() { 
01262     if (HasMethod)
01263       return reinterpret_cast<ObjCMethodDecl *>(SelectorOrMethod);
01264 
01265     return 0;
01266   }
01267 
01268   void setMethodDecl(ObjCMethodDecl *MD) { 
01269     HasMethod = true;
01270     SelectorOrMethod = reinterpret_cast<uintptr_t>(MD);
01271   }
01272 
01273   ObjCMethodFamily getMethodFamily() const {
01274     if (HasMethod) return getMethodDecl()->getMethodFamily();
01275     return getSelector().getMethodFamily();
01276   }
01277 
01278   /// \brief Return the number of actual arguments in this message,
01279   /// not counting the receiver.
01280   unsigned getNumArgs() const { return NumArgs; }
01281 
01282   /// \brief Retrieve the arguments to this message, not including the
01283   /// receiver.
01284   Expr **getArgs() {
01285     return reinterpret_cast<Expr **>(this + 1) + 1;
01286   }
01287   const Expr * const *getArgs() const {
01288     return reinterpret_cast<const Expr * const *>(this + 1) + 1;
01289   }
01290 
01291   /// getArg - Return the specified argument.
01292   Expr *getArg(unsigned Arg) {
01293     assert(Arg < NumArgs && "Arg access out of range!");
01294     return cast<Expr>(getArgs()[Arg]);
01295   }
01296   const Expr *getArg(unsigned Arg) const {
01297     assert(Arg < NumArgs && "Arg access out of range!");
01298     return cast<Expr>(getArgs()[Arg]);
01299   }
01300   /// setArg - Set the specified argument.
01301   void setArg(unsigned Arg, Expr *ArgExpr) {
01302     assert(Arg < NumArgs && "Arg access out of range!");
01303     getArgs()[Arg] = ArgExpr;
01304   }
01305 
01306   /// isDelegateInitCall - Answers whether this message send has been
01307   /// tagged as a "delegate init call", i.e. a call to a method in the
01308   /// -init family on self from within an -init method implementation.
01309   bool isDelegateInitCall() const { return IsDelegateInitCall; }
01310   void setDelegateInitCall(bool isDelegate) { IsDelegateInitCall = isDelegate; }
01311 
01312   SourceLocation getLeftLoc() const { return LBracLoc; }
01313   SourceLocation getRightLoc() const { return RBracLoc; }
01314 
01315   SourceLocation getSelectorStartLoc() const {
01316     if (isImplicit())
01317       return getLocStart();
01318     return getSelectorLoc(0);
01319   }
01320   SourceLocation getSelectorLoc(unsigned Index) const {
01321     assert(Index < getNumSelectorLocs() && "Index out of range!");
01322     if (hasStandardSelLocs())
01323       return getStandardSelectorLoc(Index, getSelector(),
01324                                    getSelLocsKind() == SelLoc_StandardWithSpace,
01325                                llvm::makeArrayRef(const_cast<Expr**>(getArgs()),
01326                                                   getNumArgs()),
01327                                    RBracLoc);
01328     return getStoredSelLocs()[Index];
01329   }
01330 
01331   void getSelectorLocs(SmallVectorImpl<SourceLocation> &SelLocs) const;
01332 
01333   unsigned getNumSelectorLocs() const {
01334     if (isImplicit())
01335       return 0;
01336     Selector Sel = getSelector();
01337     if (Sel.isUnarySelector())
01338       return 1;
01339     return Sel.getNumArgs();
01340   }
01341 
01342   void setSourceRange(SourceRange R) {
01343     LBracLoc = R.getBegin();
01344     RBracLoc = R.getEnd();
01345   }
01346   SourceRange getSourceRange() const LLVM_READONLY {
01347     return SourceRange(LBracLoc, RBracLoc);
01348   }
01349 
01350   static bool classof(const Stmt *T) {
01351     return T->getStmtClass() == ObjCMessageExprClass;
01352   }
01353   static bool classof(const ObjCMessageExpr *) { return true; }
01354 
01355   // Iterators
01356   child_range children();
01357 
01358   typedef ExprIterator arg_iterator;
01359   typedef ConstExprIterator const_arg_iterator;
01360 
01361   arg_iterator arg_begin() { return reinterpret_cast<Stmt **>(getArgs()); }
01362   arg_iterator arg_end()   { 
01363     return reinterpret_cast<Stmt **>(getArgs() + NumArgs); 
01364   }
01365   const_arg_iterator arg_begin() const { 
01366     return reinterpret_cast<Stmt const * const*>(getArgs()); 
01367   }
01368   const_arg_iterator arg_end() const { 
01369     return reinterpret_cast<Stmt const * const*>(getArgs() + NumArgs); 
01370   }
01371 
01372   friend class ASTStmtReader;
01373   friend class ASTStmtWriter;
01374 };
01375 
01376 /// ObjCIsaExpr - Represent X->isa and X.isa when X is an ObjC 'id' type.
01377 /// (similar in spirit to MemberExpr).
01378 class ObjCIsaExpr : public Expr {
01379   /// Base - the expression for the base object pointer.
01380   Stmt *Base;
01381 
01382   /// IsaMemberLoc - This is the location of the 'isa'.
01383   SourceLocation IsaMemberLoc;
01384 
01385   /// IsArrow - True if this is "X->F", false if this is "X.F".
01386   bool IsArrow;
01387 public:
01388   ObjCIsaExpr(Expr *base, bool isarrow, SourceLocation l, QualType ty)
01389     : Expr(ObjCIsaExprClass, ty, VK_LValue, OK_Ordinary,
01390            /*TypeDependent=*/false, base->isValueDependent(),
01391            base->isInstantiationDependent(),
01392            /*ContainsUnexpandedParameterPack=*/false),
01393       Base(base), IsaMemberLoc(l), IsArrow(isarrow) {}
01394 
01395   /// \brief Build an empty expression.
01396   explicit ObjCIsaExpr(EmptyShell Empty) : Expr(ObjCIsaExprClass, Empty) { }
01397 
01398   void setBase(Expr *E) { Base = E; }
01399   Expr *getBase() const { return cast<Expr>(Base); }
01400 
01401   bool isArrow() const { return IsArrow; }
01402   void setArrow(bool A) { IsArrow = A; }
01403 
01404   /// getMemberLoc - Return the location of the "member", in X->F, it is the
01405   /// location of 'F'.
01406   SourceLocation getIsaMemberLoc() const { return IsaMemberLoc; }
01407   void setIsaMemberLoc(SourceLocation L) { IsaMemberLoc = L; }
01408 
01409   SourceRange getSourceRange() const LLVM_READONLY {
01410     return SourceRange(getBase()->getLocStart(), IsaMemberLoc);
01411   }
01412 
01413   SourceLocation getExprLoc() const LLVM_READONLY { return IsaMemberLoc; }
01414 
01415   static bool classof(const Stmt *T) {
01416     return T->getStmtClass() == ObjCIsaExprClass;
01417   }
01418   static bool classof(const ObjCIsaExpr *) { return true; }
01419 
01420   // Iterators
01421   child_range children() { return child_range(&Base, &Base+1); }
01422 };
01423 
01424 
01425 /// ObjCIndirectCopyRestoreExpr - Represents the passing of a function
01426 /// argument by indirect copy-restore in ARC.  This is used to support
01427 /// passing indirect arguments with the wrong lifetime, e.g. when
01428 /// passing the address of a __strong local variable to an 'out'
01429 /// parameter.  This expression kind is only valid in an "argument"
01430 /// position to some sort of call expression.
01431 ///
01432 /// The parameter must have type 'pointer to T', and the argument must
01433 /// have type 'pointer to U', where T and U agree except possibly in
01434 /// qualification.  If the argument value is null, then a null pointer
01435 /// is passed;  otherwise it points to an object A, and:
01436 /// 1. A temporary object B of type T is initialized, either by
01437 ///    zero-initialization (used when initializing an 'out' parameter)
01438 ///    or copy-initialization (used when initializing an 'inout'
01439 ///    parameter).
01440 /// 2. The address of the temporary is passed to the function.
01441 /// 3. If the call completes normally, A is move-assigned from B.
01442 /// 4. Finally, A is destroyed immediately.
01443 ///
01444 /// Currently 'T' must be a retainable object lifetime and must be
01445 /// __autoreleasing;  this qualifier is ignored when initializing
01446 /// the value.
01447 class ObjCIndirectCopyRestoreExpr : public Expr {
01448   Stmt *Operand;
01449 
01450   // unsigned ObjCIndirectCopyRestoreBits.ShouldCopy : 1;
01451 
01452   friend class ASTReader;
01453   friend class ASTStmtReader;
01454 
01455   void setShouldCopy(bool shouldCopy) {
01456     ObjCIndirectCopyRestoreExprBits.ShouldCopy = shouldCopy;
01457   }
01458 
01459   explicit ObjCIndirectCopyRestoreExpr(EmptyShell Empty)
01460     : Expr(ObjCIndirectCopyRestoreExprClass, Empty) { }
01461 
01462 public:
01463   ObjCIndirectCopyRestoreExpr(Expr *operand, QualType type, bool shouldCopy)
01464     : Expr(ObjCIndirectCopyRestoreExprClass, type, VK_LValue, OK_Ordinary,
01465            operand->isTypeDependent(), operand->isValueDependent(),
01466            operand->isInstantiationDependent(),
01467            operand->containsUnexpandedParameterPack()),
01468       Operand(operand) {
01469     setShouldCopy(shouldCopy);
01470   }
01471 
01472   Expr *getSubExpr() { return cast<Expr>(Operand); }
01473   const Expr *getSubExpr() const { return cast<Expr>(Operand); }
01474 
01475   /// shouldCopy - True if we should do the 'copy' part of the
01476   /// copy-restore.  If false, the temporary will be zero-initialized.
01477   bool shouldCopy() const { return ObjCIndirectCopyRestoreExprBits.ShouldCopy; }
01478 
01479   child_range children() { return child_range(&Operand, &Operand+1); }  
01480 
01481   // Source locations are determined by the subexpression.
01482   SourceRange getSourceRange() const LLVM_READONLY {
01483     return Operand->getSourceRange();
01484   }
01485   SourceLocation getExprLoc() const LLVM_READONLY {
01486     return getSubExpr()->getExprLoc();
01487   }
01488 
01489   static bool classof(const Stmt *s) {
01490     return s->getStmtClass() == ObjCIndirectCopyRestoreExprClass;
01491   }
01492   static bool classof(const ObjCIndirectCopyRestoreExpr *) { return true; }
01493 };
01494 
01495 /// \brief An Objective-C "bridged" cast expression, which casts between
01496 /// Objective-C pointers and C pointers, transferring ownership in the process.
01497 ///
01498 /// \code
01499 /// NSString *str = (__bridge_transfer NSString *)CFCreateString();
01500 /// \endcode
01501 class ObjCBridgedCastExpr : public ExplicitCastExpr {
01502   SourceLocation LParenLoc;
01503   SourceLocation BridgeKeywordLoc;
01504   unsigned Kind : 2;
01505   
01506   friend class ASTStmtReader;
01507   friend class ASTStmtWriter;
01508   
01509 public:
01510   ObjCBridgedCastExpr(SourceLocation LParenLoc, ObjCBridgeCastKind Kind,
01511                       CastKind CK, SourceLocation BridgeKeywordLoc,
01512                       TypeSourceInfo *TSInfo, Expr *Operand)
01513     : ExplicitCastExpr(ObjCBridgedCastExprClass, TSInfo->getType(), VK_RValue,
01514                        CK, Operand, 0, TSInfo),
01515       LParenLoc(LParenLoc), BridgeKeywordLoc(BridgeKeywordLoc), Kind(Kind) { }
01516   
01517   /// \brief Construct an empty Objective-C bridged cast.
01518   explicit ObjCBridgedCastExpr(EmptyShell Shell)
01519     : ExplicitCastExpr(ObjCBridgedCastExprClass, Shell, 0) { }
01520 
01521   SourceLocation getLParenLoc() const { return LParenLoc; }
01522 
01523   /// \brief Determine which kind of bridge is being performed via this cast.
01524   ObjCBridgeCastKind getBridgeKind() const { 
01525     return static_cast<ObjCBridgeCastKind>(Kind); 
01526   }
01527   
01528   /// \brief Retrieve the kind of bridge being performed as a string.
01529   StringRef getBridgeKindName() const;
01530   
01531   /// \brief The location of the bridge keyword.
01532   SourceLocation getBridgeKeywordLoc() const { return BridgeKeywordLoc; }
01533   
01534   SourceRange getSourceRange() const LLVM_READONLY {
01535     return SourceRange(LParenLoc, getSubExpr()->getLocEnd());
01536   }
01537   
01538   static bool classof(const Stmt *T) {
01539     return T->getStmtClass() == ObjCBridgedCastExprClass;
01540   }
01541   static bool classof(const ObjCBridgedCastExpr *) { return true; }
01542  
01543 };
01544   
01545 }  // end namespace clang
01546 
01547 #endif