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