xref: /freebsd-src/contrib/llvm-project/clang/lib/AST/ExprObjC.cpp (revision 349cc55c9796c4596a5b9904cd3281af295f878f)
10b57cec5SDimitry Andric //===- ExprObjC.cpp - (ObjC) Expression AST Node Implementation -----------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file implements the subclesses of Expr class declared in ExprObjC.h
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #include "clang/AST/ExprObjC.h"
140b57cec5SDimitry Andric #include "clang/AST/ASTContext.h"
155ffd83dbSDimitry Andric #include "clang/AST/ComputeDependence.h"
165ffd83dbSDimitry Andric #include "clang/AST/DependenceFlags.h"
170b57cec5SDimitry Andric #include "clang/AST/SelectorLocationsKind.h"
180b57cec5SDimitry Andric #include "clang/AST/Type.h"
190b57cec5SDimitry Andric #include "clang/AST/TypeLoc.h"
200b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h"
210b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
220b57cec5SDimitry Andric #include <algorithm>
230b57cec5SDimitry Andric #include <cassert>
240b57cec5SDimitry Andric #include <cstdint>
250b57cec5SDimitry Andric 
260b57cec5SDimitry Andric using namespace clang;
270b57cec5SDimitry Andric 
ObjCArrayLiteral(ArrayRef<Expr * > Elements,QualType T,ObjCMethodDecl * Method,SourceRange SR)280b57cec5SDimitry Andric ObjCArrayLiteral::ObjCArrayLiteral(ArrayRef<Expr *> Elements, QualType T,
290b57cec5SDimitry Andric                                    ObjCMethodDecl *Method, SourceRange SR)
30fe6060f1SDimitry Andric     : Expr(ObjCArrayLiteralClass, T, VK_PRValue, OK_Ordinary),
310b57cec5SDimitry Andric       NumElements(Elements.size()), Range(SR), ArrayWithObjectsMethod(Method) {
320b57cec5SDimitry Andric   Expr **SaveElements = getElements();
335ffd83dbSDimitry Andric   for (unsigned I = 0, N = Elements.size(); I != N; ++I)
340b57cec5SDimitry Andric     SaveElements[I] = Elements[I];
355ffd83dbSDimitry Andric 
365ffd83dbSDimitry Andric   setDependence(computeDependence(this));
370b57cec5SDimitry Andric }
380b57cec5SDimitry Andric 
Create(const ASTContext & C,ArrayRef<Expr * > Elements,QualType T,ObjCMethodDecl * Method,SourceRange SR)390b57cec5SDimitry Andric ObjCArrayLiteral *ObjCArrayLiteral::Create(const ASTContext &C,
400b57cec5SDimitry Andric                                            ArrayRef<Expr *> Elements,
410b57cec5SDimitry Andric                                            QualType T, ObjCMethodDecl *Method,
420b57cec5SDimitry Andric                                            SourceRange SR) {
430b57cec5SDimitry Andric   void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(Elements.size()));
440b57cec5SDimitry Andric   return new (Mem) ObjCArrayLiteral(Elements, T, Method, SR);
450b57cec5SDimitry Andric }
460b57cec5SDimitry Andric 
CreateEmpty(const ASTContext & C,unsigned NumElements)470b57cec5SDimitry Andric ObjCArrayLiteral *ObjCArrayLiteral::CreateEmpty(const ASTContext &C,
480b57cec5SDimitry Andric                                                 unsigned NumElements) {
490b57cec5SDimitry Andric   void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(NumElements));
500b57cec5SDimitry Andric   return new (Mem) ObjCArrayLiteral(EmptyShell(), NumElements);
510b57cec5SDimitry Andric }
520b57cec5SDimitry Andric 
ObjCDictionaryLiteral(ArrayRef<ObjCDictionaryElement> VK,bool HasPackExpansions,QualType T,ObjCMethodDecl * method,SourceRange SR)530b57cec5SDimitry Andric ObjCDictionaryLiteral::ObjCDictionaryLiteral(ArrayRef<ObjCDictionaryElement> VK,
540b57cec5SDimitry Andric                                              bool HasPackExpansions, QualType T,
550b57cec5SDimitry Andric                                              ObjCMethodDecl *method,
560b57cec5SDimitry Andric                                              SourceRange SR)
57fe6060f1SDimitry Andric     : Expr(ObjCDictionaryLiteralClass, T, VK_PRValue, OK_Ordinary),
580b57cec5SDimitry Andric       NumElements(VK.size()), HasPackExpansions(HasPackExpansions), Range(SR),
590b57cec5SDimitry Andric       DictWithObjectsMethod(method) {
600b57cec5SDimitry Andric   KeyValuePair *KeyValues = getTrailingObjects<KeyValuePair>();
610b57cec5SDimitry Andric   ExpansionData *Expansions =
620b57cec5SDimitry Andric       HasPackExpansions ? getTrailingObjects<ExpansionData>() : nullptr;
630b57cec5SDimitry Andric   for (unsigned I = 0; I < NumElements; I++) {
640b57cec5SDimitry Andric     KeyValues[I].Key = VK[I].Key;
650b57cec5SDimitry Andric     KeyValues[I].Value = VK[I].Value;
660b57cec5SDimitry Andric     if (Expansions) {
670b57cec5SDimitry Andric       Expansions[I].EllipsisLoc = VK[I].EllipsisLoc;
680b57cec5SDimitry Andric       if (VK[I].NumExpansions)
690b57cec5SDimitry Andric         Expansions[I].NumExpansionsPlusOne = *VK[I].NumExpansions + 1;
700b57cec5SDimitry Andric       else
710b57cec5SDimitry Andric         Expansions[I].NumExpansionsPlusOne = 0;
720b57cec5SDimitry Andric     }
730b57cec5SDimitry Andric   }
745ffd83dbSDimitry Andric   setDependence(computeDependence(this));
750b57cec5SDimitry Andric }
760b57cec5SDimitry Andric 
770b57cec5SDimitry Andric ObjCDictionaryLiteral *
Create(const ASTContext & C,ArrayRef<ObjCDictionaryElement> VK,bool HasPackExpansions,QualType T,ObjCMethodDecl * method,SourceRange SR)780b57cec5SDimitry Andric ObjCDictionaryLiteral::Create(const ASTContext &C,
790b57cec5SDimitry Andric                               ArrayRef<ObjCDictionaryElement> VK,
800b57cec5SDimitry Andric                               bool HasPackExpansions, QualType T,
810b57cec5SDimitry Andric                               ObjCMethodDecl *method, SourceRange SR) {
820b57cec5SDimitry Andric   void *Mem = C.Allocate(totalSizeToAlloc<KeyValuePair, ExpansionData>(
830b57cec5SDimitry Andric       VK.size(), HasPackExpansions ? VK.size() : 0));
840b57cec5SDimitry Andric   return new (Mem) ObjCDictionaryLiteral(VK, HasPackExpansions, T, method, SR);
850b57cec5SDimitry Andric }
860b57cec5SDimitry Andric 
870b57cec5SDimitry Andric ObjCDictionaryLiteral *
CreateEmpty(const ASTContext & C,unsigned NumElements,bool HasPackExpansions)880b57cec5SDimitry Andric ObjCDictionaryLiteral::CreateEmpty(const ASTContext &C, unsigned NumElements,
890b57cec5SDimitry Andric                                    bool HasPackExpansions) {
900b57cec5SDimitry Andric   void *Mem = C.Allocate(totalSizeToAlloc<KeyValuePair, ExpansionData>(
910b57cec5SDimitry Andric       NumElements, HasPackExpansions ? NumElements : 0));
920b57cec5SDimitry Andric   return new (Mem)
930b57cec5SDimitry Andric       ObjCDictionaryLiteral(EmptyShell(), NumElements, HasPackExpansions);
940b57cec5SDimitry Andric }
950b57cec5SDimitry Andric 
getReceiverType(const ASTContext & ctx) const960b57cec5SDimitry Andric QualType ObjCPropertyRefExpr::getReceiverType(const ASTContext &ctx) const {
970b57cec5SDimitry Andric   if (isClassReceiver())
980b57cec5SDimitry Andric     return ctx.getObjCInterfaceType(getClassReceiver());
990b57cec5SDimitry Andric 
1000b57cec5SDimitry Andric   if (isSuperReceiver())
1010b57cec5SDimitry Andric     return getSuperReceiverType();
1020b57cec5SDimitry Andric 
1030b57cec5SDimitry Andric   return getBase()->getType();
1040b57cec5SDimitry Andric }
1050b57cec5SDimitry Andric 
ObjCMessageExpr(QualType T,ExprValueKind VK,SourceLocation LBracLoc,SourceLocation SuperLoc,bool IsInstanceSuper,QualType SuperType,Selector Sel,ArrayRef<SourceLocation> SelLocs,SelectorLocationsKind SelLocsK,ObjCMethodDecl * Method,ArrayRef<Expr * > Args,SourceLocation RBracLoc,bool isImplicit)1060b57cec5SDimitry Andric ObjCMessageExpr::ObjCMessageExpr(QualType T, ExprValueKind VK,
1070b57cec5SDimitry Andric                                  SourceLocation LBracLoc,
1080b57cec5SDimitry Andric                                  SourceLocation SuperLoc, bool IsInstanceSuper,
1090b57cec5SDimitry Andric                                  QualType SuperType, Selector Sel,
1100b57cec5SDimitry Andric                                  ArrayRef<SourceLocation> SelLocs,
1110b57cec5SDimitry Andric                                  SelectorLocationsKind SelLocsK,
1120b57cec5SDimitry Andric                                  ObjCMethodDecl *Method, ArrayRef<Expr *> Args,
1130b57cec5SDimitry Andric                                  SourceLocation RBracLoc, bool isImplicit)
1145ffd83dbSDimitry Andric     : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary),
1150b57cec5SDimitry Andric       SelectorOrMethod(
1160b57cec5SDimitry Andric           reinterpret_cast<uintptr_t>(Method ? Method : Sel.getAsOpaquePtr())),
1170b57cec5SDimitry Andric       Kind(IsInstanceSuper ? SuperInstance : SuperClass),
1180b57cec5SDimitry Andric       HasMethod(Method != nullptr), IsDelegateInitCall(false),
1190b57cec5SDimitry Andric       IsImplicit(isImplicit), SuperLoc(SuperLoc), LBracLoc(LBracLoc),
1200b57cec5SDimitry Andric       RBracLoc(RBracLoc) {
1210b57cec5SDimitry Andric   initArgsAndSelLocs(Args, SelLocs, SelLocsK);
1220b57cec5SDimitry Andric   setReceiverPointer(SuperType.getAsOpaquePtr());
1235ffd83dbSDimitry Andric   setDependence(computeDependence(this));
1240b57cec5SDimitry Andric }
1250b57cec5SDimitry Andric 
ObjCMessageExpr(QualType T,ExprValueKind VK,SourceLocation LBracLoc,TypeSourceInfo * Receiver,Selector Sel,ArrayRef<SourceLocation> SelLocs,SelectorLocationsKind SelLocsK,ObjCMethodDecl * Method,ArrayRef<Expr * > Args,SourceLocation RBracLoc,bool isImplicit)1260b57cec5SDimitry Andric ObjCMessageExpr::ObjCMessageExpr(QualType T, ExprValueKind VK,
1270b57cec5SDimitry Andric                                  SourceLocation LBracLoc,
1280b57cec5SDimitry Andric                                  TypeSourceInfo *Receiver, Selector Sel,
1290b57cec5SDimitry Andric                                  ArrayRef<SourceLocation> SelLocs,
1300b57cec5SDimitry Andric                                  SelectorLocationsKind SelLocsK,
1310b57cec5SDimitry Andric                                  ObjCMethodDecl *Method, ArrayRef<Expr *> Args,
1320b57cec5SDimitry Andric                                  SourceLocation RBracLoc, bool isImplicit)
1335ffd83dbSDimitry Andric     : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary),
1340b57cec5SDimitry Andric       SelectorOrMethod(
1350b57cec5SDimitry Andric           reinterpret_cast<uintptr_t>(Method ? Method : Sel.getAsOpaquePtr())),
1360b57cec5SDimitry Andric       Kind(Class), HasMethod(Method != nullptr), IsDelegateInitCall(false),
1370b57cec5SDimitry Andric       IsImplicit(isImplicit), LBracLoc(LBracLoc), RBracLoc(RBracLoc) {
1380b57cec5SDimitry Andric   initArgsAndSelLocs(Args, SelLocs, SelLocsK);
1390b57cec5SDimitry Andric   setReceiverPointer(Receiver);
1405ffd83dbSDimitry Andric   setDependence(computeDependence(this));
1410b57cec5SDimitry Andric }
1420b57cec5SDimitry Andric 
ObjCMessageExpr(QualType T,ExprValueKind VK,SourceLocation LBracLoc,Expr * Receiver,Selector Sel,ArrayRef<SourceLocation> SelLocs,SelectorLocationsKind SelLocsK,ObjCMethodDecl * Method,ArrayRef<Expr * > Args,SourceLocation RBracLoc,bool isImplicit)1430b57cec5SDimitry Andric ObjCMessageExpr::ObjCMessageExpr(QualType T, ExprValueKind VK,
1440b57cec5SDimitry Andric                                  SourceLocation LBracLoc, Expr *Receiver,
1450b57cec5SDimitry Andric                                  Selector Sel, ArrayRef<SourceLocation> SelLocs,
1460b57cec5SDimitry Andric                                  SelectorLocationsKind SelLocsK,
1470b57cec5SDimitry Andric                                  ObjCMethodDecl *Method, ArrayRef<Expr *> Args,
1480b57cec5SDimitry Andric                                  SourceLocation RBracLoc, bool isImplicit)
1495ffd83dbSDimitry Andric     : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary),
1500b57cec5SDimitry Andric       SelectorOrMethod(
1510b57cec5SDimitry Andric           reinterpret_cast<uintptr_t>(Method ? Method : Sel.getAsOpaquePtr())),
1520b57cec5SDimitry Andric       Kind(Instance), HasMethod(Method != nullptr), IsDelegateInitCall(false),
1530b57cec5SDimitry Andric       IsImplicit(isImplicit), LBracLoc(LBracLoc), RBracLoc(RBracLoc) {
1540b57cec5SDimitry Andric   initArgsAndSelLocs(Args, SelLocs, SelLocsK);
1550b57cec5SDimitry Andric   setReceiverPointer(Receiver);
1565ffd83dbSDimitry Andric   setDependence(computeDependence(this));
1570b57cec5SDimitry Andric }
1580b57cec5SDimitry Andric 
initArgsAndSelLocs(ArrayRef<Expr * > Args,ArrayRef<SourceLocation> SelLocs,SelectorLocationsKind SelLocsK)1590b57cec5SDimitry Andric void ObjCMessageExpr::initArgsAndSelLocs(ArrayRef<Expr *> Args,
1600b57cec5SDimitry Andric                                          ArrayRef<SourceLocation> SelLocs,
1610b57cec5SDimitry Andric                                          SelectorLocationsKind SelLocsK) {
1620b57cec5SDimitry Andric   setNumArgs(Args.size());
1630b57cec5SDimitry Andric   Expr **MyArgs = getArgs();
1645ffd83dbSDimitry Andric   for (unsigned I = 0; I != Args.size(); ++I)
1650b57cec5SDimitry Andric     MyArgs[I] = Args[I];
1660b57cec5SDimitry Andric 
1670b57cec5SDimitry Andric   SelLocsKind = SelLocsK;
1680b57cec5SDimitry Andric   if (!isImplicit()) {
1690b57cec5SDimitry Andric     if (SelLocsK == SelLoc_NonStandard)
1700b57cec5SDimitry Andric       std::copy(SelLocs.begin(), SelLocs.end(), getStoredSelLocs());
1710b57cec5SDimitry Andric   }
1720b57cec5SDimitry Andric }
1730b57cec5SDimitry Andric 
1740b57cec5SDimitry Andric ObjCMessageExpr *
Create(const ASTContext & Context,QualType T,ExprValueKind VK,SourceLocation LBracLoc,SourceLocation SuperLoc,bool IsInstanceSuper,QualType SuperType,Selector Sel,ArrayRef<SourceLocation> SelLocs,ObjCMethodDecl * Method,ArrayRef<Expr * > Args,SourceLocation RBracLoc,bool isImplicit)1750b57cec5SDimitry Andric ObjCMessageExpr::Create(const ASTContext &Context, QualType T, ExprValueKind VK,
1760b57cec5SDimitry Andric                         SourceLocation LBracLoc, SourceLocation SuperLoc,
1770b57cec5SDimitry Andric                         bool IsInstanceSuper, QualType SuperType, Selector Sel,
1780b57cec5SDimitry Andric                         ArrayRef<SourceLocation> SelLocs,
1790b57cec5SDimitry Andric                         ObjCMethodDecl *Method, ArrayRef<Expr *> Args,
1800b57cec5SDimitry Andric                         SourceLocation RBracLoc, bool isImplicit) {
1810b57cec5SDimitry Andric   assert((!SelLocs.empty() || isImplicit) &&
1820b57cec5SDimitry Andric          "No selector locs for non-implicit message");
1830b57cec5SDimitry Andric   ObjCMessageExpr *Mem;
1840b57cec5SDimitry Andric   SelectorLocationsKind SelLocsK = SelectorLocationsKind();
1850b57cec5SDimitry Andric   if (isImplicit)
1860b57cec5SDimitry Andric     Mem = alloc(Context, Args.size(), 0);
1870b57cec5SDimitry Andric   else
1880b57cec5SDimitry Andric     Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK);
1890b57cec5SDimitry Andric   return new (Mem) ObjCMessageExpr(T, VK, LBracLoc, SuperLoc, IsInstanceSuper,
1900b57cec5SDimitry Andric                                    SuperType, Sel, SelLocs, SelLocsK, Method,
1910b57cec5SDimitry Andric                                    Args, RBracLoc, isImplicit);
1920b57cec5SDimitry Andric }
1930b57cec5SDimitry Andric 
1940b57cec5SDimitry Andric ObjCMessageExpr *
Create(const ASTContext & Context,QualType T,ExprValueKind VK,SourceLocation LBracLoc,TypeSourceInfo * Receiver,Selector Sel,ArrayRef<SourceLocation> SelLocs,ObjCMethodDecl * Method,ArrayRef<Expr * > Args,SourceLocation RBracLoc,bool isImplicit)1950b57cec5SDimitry Andric ObjCMessageExpr::Create(const ASTContext &Context, QualType T, ExprValueKind VK,
1960b57cec5SDimitry Andric                         SourceLocation LBracLoc, TypeSourceInfo *Receiver,
1970b57cec5SDimitry Andric                         Selector Sel, ArrayRef<SourceLocation> SelLocs,
1980b57cec5SDimitry Andric                         ObjCMethodDecl *Method, ArrayRef<Expr *> Args,
1990b57cec5SDimitry Andric                         SourceLocation RBracLoc, bool isImplicit) {
2000b57cec5SDimitry Andric   assert((!SelLocs.empty() || isImplicit) &&
2010b57cec5SDimitry Andric          "No selector locs for non-implicit message");
2020b57cec5SDimitry Andric   ObjCMessageExpr *Mem;
2030b57cec5SDimitry Andric   SelectorLocationsKind SelLocsK = SelectorLocationsKind();
2040b57cec5SDimitry Andric   if (isImplicit)
2050b57cec5SDimitry Andric     Mem = alloc(Context, Args.size(), 0);
2060b57cec5SDimitry Andric   else
2070b57cec5SDimitry Andric     Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK);
2080b57cec5SDimitry Andric   return new (Mem)
2090b57cec5SDimitry Andric       ObjCMessageExpr(T, VK, LBracLoc, Receiver, Sel, SelLocs, SelLocsK, Method,
2100b57cec5SDimitry Andric                       Args, RBracLoc, isImplicit);
2110b57cec5SDimitry Andric }
2120b57cec5SDimitry Andric 
2130b57cec5SDimitry Andric ObjCMessageExpr *
Create(const ASTContext & Context,QualType T,ExprValueKind VK,SourceLocation LBracLoc,Expr * Receiver,Selector Sel,ArrayRef<SourceLocation> SelLocs,ObjCMethodDecl * Method,ArrayRef<Expr * > Args,SourceLocation RBracLoc,bool isImplicit)2140b57cec5SDimitry Andric ObjCMessageExpr::Create(const ASTContext &Context, QualType T, ExprValueKind VK,
2150b57cec5SDimitry Andric                         SourceLocation LBracLoc, Expr *Receiver, Selector Sel,
2160b57cec5SDimitry Andric                         ArrayRef<SourceLocation> SelLocs,
2170b57cec5SDimitry Andric                         ObjCMethodDecl *Method, ArrayRef<Expr *> Args,
2180b57cec5SDimitry Andric                         SourceLocation RBracLoc, bool isImplicit) {
2190b57cec5SDimitry Andric   assert((!SelLocs.empty() || isImplicit) &&
2200b57cec5SDimitry Andric          "No selector locs for non-implicit message");
2210b57cec5SDimitry Andric   ObjCMessageExpr *Mem;
2220b57cec5SDimitry Andric   SelectorLocationsKind SelLocsK = SelectorLocationsKind();
2230b57cec5SDimitry Andric   if (isImplicit)
2240b57cec5SDimitry Andric     Mem = alloc(Context, Args.size(), 0);
2250b57cec5SDimitry Andric   else
2260b57cec5SDimitry Andric     Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK);
2270b57cec5SDimitry Andric   return new (Mem)
2280b57cec5SDimitry Andric       ObjCMessageExpr(T, VK, LBracLoc, Receiver, Sel, SelLocs, SelLocsK, Method,
2290b57cec5SDimitry Andric                       Args, RBracLoc, isImplicit);
2300b57cec5SDimitry Andric }
2310b57cec5SDimitry Andric 
CreateEmpty(const ASTContext & Context,unsigned NumArgs,unsigned NumStoredSelLocs)2320b57cec5SDimitry Andric ObjCMessageExpr *ObjCMessageExpr::CreateEmpty(const ASTContext &Context,
2330b57cec5SDimitry Andric                                               unsigned NumArgs,
2340b57cec5SDimitry Andric                                               unsigned NumStoredSelLocs) {
2350b57cec5SDimitry Andric   ObjCMessageExpr *Mem = alloc(Context, NumArgs, NumStoredSelLocs);
2360b57cec5SDimitry Andric   return new (Mem) ObjCMessageExpr(EmptyShell(), NumArgs);
2370b57cec5SDimitry Andric }
2380b57cec5SDimitry Andric 
alloc(const ASTContext & C,ArrayRef<Expr * > Args,SourceLocation RBraceLoc,ArrayRef<SourceLocation> SelLocs,Selector Sel,SelectorLocationsKind & SelLocsK)2390b57cec5SDimitry Andric ObjCMessageExpr *ObjCMessageExpr::alloc(const ASTContext &C,
2400b57cec5SDimitry Andric                                         ArrayRef<Expr *> Args,
2410b57cec5SDimitry Andric                                         SourceLocation RBraceLoc,
2420b57cec5SDimitry Andric                                         ArrayRef<SourceLocation> SelLocs,
2430b57cec5SDimitry Andric                                         Selector Sel,
2440b57cec5SDimitry Andric                                         SelectorLocationsKind &SelLocsK) {
2450b57cec5SDimitry Andric   SelLocsK = hasStandardSelectorLocs(Sel, SelLocs, Args, RBraceLoc);
2460b57cec5SDimitry Andric   unsigned NumStoredSelLocs =
2470b57cec5SDimitry Andric       (SelLocsK == SelLoc_NonStandard) ? SelLocs.size() : 0;
2480b57cec5SDimitry Andric   return alloc(C, Args.size(), NumStoredSelLocs);
2490b57cec5SDimitry Andric }
2500b57cec5SDimitry Andric 
alloc(const ASTContext & C,unsigned NumArgs,unsigned NumStoredSelLocs)2510b57cec5SDimitry Andric ObjCMessageExpr *ObjCMessageExpr::alloc(const ASTContext &C, unsigned NumArgs,
2520b57cec5SDimitry Andric                                         unsigned NumStoredSelLocs) {
2530b57cec5SDimitry Andric   return (ObjCMessageExpr *)C.Allocate(
2540b57cec5SDimitry Andric       totalSizeToAlloc<void *, SourceLocation>(NumArgs + 1, NumStoredSelLocs),
2550b57cec5SDimitry Andric       alignof(ObjCMessageExpr));
2560b57cec5SDimitry Andric }
2570b57cec5SDimitry Andric 
getSelectorLocs(SmallVectorImpl<SourceLocation> & SelLocs) const2580b57cec5SDimitry Andric void ObjCMessageExpr::getSelectorLocs(
2590b57cec5SDimitry Andric     SmallVectorImpl<SourceLocation> &SelLocs) const {
2600b57cec5SDimitry Andric   for (unsigned i = 0, e = getNumSelectorLocs(); i != e; ++i)
2610b57cec5SDimitry Andric     SelLocs.push_back(getSelectorLoc(i));
2620b57cec5SDimitry Andric }
2630b57cec5SDimitry Andric 
2640b57cec5SDimitry Andric 
getCallReturnType(ASTContext & Ctx) const2650b57cec5SDimitry Andric QualType ObjCMessageExpr::getCallReturnType(ASTContext &Ctx) const {
2660b57cec5SDimitry Andric   if (const ObjCMethodDecl *MD = getMethodDecl()) {
2670b57cec5SDimitry Andric     QualType QT = MD->getReturnType();
2680b57cec5SDimitry Andric     if (QT == Ctx.getObjCInstanceType()) {
2690b57cec5SDimitry Andric       // instancetype corresponds to expression types.
2700b57cec5SDimitry Andric       return getType();
2710b57cec5SDimitry Andric     }
2720b57cec5SDimitry Andric     return QT;
2730b57cec5SDimitry Andric   }
274*349cc55cSDimitry Andric   return Ctx.getReferenceQualifiedType(this);
2750b57cec5SDimitry Andric }
2760b57cec5SDimitry Andric 
getReceiverRange() const2770b57cec5SDimitry Andric SourceRange ObjCMessageExpr::getReceiverRange() const {
2780b57cec5SDimitry Andric   switch (getReceiverKind()) {
2790b57cec5SDimitry Andric   case Instance:
2800b57cec5SDimitry Andric     return getInstanceReceiver()->getSourceRange();
2810b57cec5SDimitry Andric 
2820b57cec5SDimitry Andric   case Class:
2830b57cec5SDimitry Andric     return getClassReceiverTypeInfo()->getTypeLoc().getSourceRange();
2840b57cec5SDimitry Andric 
2850b57cec5SDimitry Andric   case SuperInstance:
2860b57cec5SDimitry Andric   case SuperClass:
2870b57cec5SDimitry Andric     return getSuperLoc();
2880b57cec5SDimitry Andric   }
2890b57cec5SDimitry Andric 
2900b57cec5SDimitry Andric   llvm_unreachable("Invalid ReceiverKind!");
2910b57cec5SDimitry Andric }
2920b57cec5SDimitry Andric 
getSelector() const2930b57cec5SDimitry Andric Selector ObjCMessageExpr::getSelector() const {
2940b57cec5SDimitry Andric   if (HasMethod)
2950b57cec5SDimitry Andric     return reinterpret_cast<const ObjCMethodDecl *>(SelectorOrMethod)
2960b57cec5SDimitry Andric         ->getSelector();
2970b57cec5SDimitry Andric   return Selector(SelectorOrMethod);
2980b57cec5SDimitry Andric }
2990b57cec5SDimitry Andric 
getReceiverType() const3000b57cec5SDimitry Andric QualType ObjCMessageExpr::getReceiverType() const {
3010b57cec5SDimitry Andric   switch (getReceiverKind()) {
3020b57cec5SDimitry Andric   case Instance:
3030b57cec5SDimitry Andric     return getInstanceReceiver()->getType();
3040b57cec5SDimitry Andric   case Class:
3050b57cec5SDimitry Andric     return getClassReceiver();
3060b57cec5SDimitry Andric   case SuperInstance:
3070b57cec5SDimitry Andric   case SuperClass:
3080b57cec5SDimitry Andric     return getSuperType();
3090b57cec5SDimitry Andric   }
3100b57cec5SDimitry Andric 
3110b57cec5SDimitry Andric   llvm_unreachable("unexpected receiver kind");
3120b57cec5SDimitry Andric }
3130b57cec5SDimitry Andric 
getReceiverInterface() const3140b57cec5SDimitry Andric ObjCInterfaceDecl *ObjCMessageExpr::getReceiverInterface() const {
3150b57cec5SDimitry Andric   QualType T = getReceiverType();
3160b57cec5SDimitry Andric 
3170b57cec5SDimitry Andric   if (const ObjCObjectPointerType *Ptr = T->getAs<ObjCObjectPointerType>())
3180b57cec5SDimitry Andric     return Ptr->getInterfaceDecl();
3190b57cec5SDimitry Andric 
3200b57cec5SDimitry Andric   if (const ObjCObjectType *Ty = T->getAs<ObjCObjectType>())
3210b57cec5SDimitry Andric     return Ty->getInterface();
3220b57cec5SDimitry Andric 
3230b57cec5SDimitry Andric   return nullptr;
3240b57cec5SDimitry Andric }
3250b57cec5SDimitry Andric 
children()3260b57cec5SDimitry Andric Stmt::child_range ObjCMessageExpr::children() {
3270b57cec5SDimitry Andric   Stmt **begin;
3280b57cec5SDimitry Andric   if (getReceiverKind() == Instance)
3290b57cec5SDimitry Andric     begin = reinterpret_cast<Stmt **>(getTrailingObjects<void *>());
3300b57cec5SDimitry Andric   else
3310b57cec5SDimitry Andric     begin = reinterpret_cast<Stmt **>(getArgs());
3320b57cec5SDimitry Andric   return child_range(begin,
3330b57cec5SDimitry Andric                      reinterpret_cast<Stmt **>(getArgs() + getNumArgs()));
3340b57cec5SDimitry Andric }
3350b57cec5SDimitry Andric 
children() const3360b57cec5SDimitry Andric Stmt::const_child_range ObjCMessageExpr::children() const {
3370b57cec5SDimitry Andric   auto Children = const_cast<ObjCMessageExpr *>(this)->children();
3380b57cec5SDimitry Andric   return const_child_range(Children.begin(), Children.end());
3390b57cec5SDimitry Andric }
3400b57cec5SDimitry Andric 
getBridgeKindName() const3410b57cec5SDimitry Andric StringRef ObjCBridgedCastExpr::getBridgeKindName() const {
3420b57cec5SDimitry Andric   switch (getBridgeKind()) {
3430b57cec5SDimitry Andric   case OBC_Bridge:
3440b57cec5SDimitry Andric     return "__bridge";
3450b57cec5SDimitry Andric   case OBC_BridgeTransfer:
3460b57cec5SDimitry Andric     return "__bridge_transfer";
3470b57cec5SDimitry Andric   case OBC_BridgeRetained:
3480b57cec5SDimitry Andric     return "__bridge_retained";
3490b57cec5SDimitry Andric   }
3500b57cec5SDimitry Andric 
3510b57cec5SDimitry Andric   llvm_unreachable("Invalid BridgeKind!");
3520b57cec5SDimitry Andric }
353