1e5dd7070Spatrick //===- ExprObjC.cpp - (ObjC) Expression AST Node Implementation -----------===//
2e5dd7070Spatrick //
3e5dd7070Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e5dd7070Spatrick // See https://llvm.org/LICENSE.txt for license information.
5e5dd7070Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e5dd7070Spatrick //
7e5dd7070Spatrick //===----------------------------------------------------------------------===//
8e5dd7070Spatrick //
9e5dd7070Spatrick // This file implements the subclesses of Expr class declared in ExprObjC.h
10e5dd7070Spatrick //
11e5dd7070Spatrick //===----------------------------------------------------------------------===//
12e5dd7070Spatrick
13e5dd7070Spatrick #include "clang/AST/ExprObjC.h"
14e5dd7070Spatrick #include "clang/AST/ASTContext.h"
15ec727ea7Spatrick #include "clang/AST/ComputeDependence.h"
16ec727ea7Spatrick #include "clang/AST/DependenceFlags.h"
17e5dd7070Spatrick #include "clang/AST/SelectorLocationsKind.h"
18e5dd7070Spatrick #include "clang/AST/Type.h"
19e5dd7070Spatrick #include "clang/AST/TypeLoc.h"
20e5dd7070Spatrick #include "llvm/ADT/SmallVector.h"
21e5dd7070Spatrick #include "llvm/Support/ErrorHandling.h"
22e5dd7070Spatrick #include <algorithm>
23e5dd7070Spatrick #include <cassert>
24e5dd7070Spatrick #include <cstdint>
25e5dd7070Spatrick
26e5dd7070Spatrick using namespace clang;
27e5dd7070Spatrick
ObjCArrayLiteral(ArrayRef<Expr * > Elements,QualType T,ObjCMethodDecl * Method,SourceRange SR)28e5dd7070Spatrick ObjCArrayLiteral::ObjCArrayLiteral(ArrayRef<Expr *> Elements, QualType T,
29e5dd7070Spatrick ObjCMethodDecl *Method, SourceRange SR)
30a9ac8606Spatrick : Expr(ObjCArrayLiteralClass, T, VK_PRValue, OK_Ordinary),
31e5dd7070Spatrick NumElements(Elements.size()), Range(SR), ArrayWithObjectsMethod(Method) {
32e5dd7070Spatrick Expr **SaveElements = getElements();
33ec727ea7Spatrick for (unsigned I = 0, N = Elements.size(); I != N; ++I)
34e5dd7070Spatrick SaveElements[I] = Elements[I];
35ec727ea7Spatrick
36ec727ea7Spatrick setDependence(computeDependence(this));
37e5dd7070Spatrick }
38e5dd7070Spatrick
Create(const ASTContext & C,ArrayRef<Expr * > Elements,QualType T,ObjCMethodDecl * Method,SourceRange SR)39e5dd7070Spatrick ObjCArrayLiteral *ObjCArrayLiteral::Create(const ASTContext &C,
40e5dd7070Spatrick ArrayRef<Expr *> Elements,
41e5dd7070Spatrick QualType T, ObjCMethodDecl *Method,
42e5dd7070Spatrick SourceRange SR) {
43e5dd7070Spatrick void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(Elements.size()));
44e5dd7070Spatrick return new (Mem) ObjCArrayLiteral(Elements, T, Method, SR);
45e5dd7070Spatrick }
46e5dd7070Spatrick
CreateEmpty(const ASTContext & C,unsigned NumElements)47e5dd7070Spatrick ObjCArrayLiteral *ObjCArrayLiteral::CreateEmpty(const ASTContext &C,
48e5dd7070Spatrick unsigned NumElements) {
49e5dd7070Spatrick void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(NumElements));
50e5dd7070Spatrick return new (Mem) ObjCArrayLiteral(EmptyShell(), NumElements);
51e5dd7070Spatrick }
52e5dd7070Spatrick
ObjCDictionaryLiteral(ArrayRef<ObjCDictionaryElement> VK,bool HasPackExpansions,QualType T,ObjCMethodDecl * method,SourceRange SR)53e5dd7070Spatrick ObjCDictionaryLiteral::ObjCDictionaryLiteral(ArrayRef<ObjCDictionaryElement> VK,
54e5dd7070Spatrick bool HasPackExpansions, QualType T,
55e5dd7070Spatrick ObjCMethodDecl *method,
56e5dd7070Spatrick SourceRange SR)
57a9ac8606Spatrick : Expr(ObjCDictionaryLiteralClass, T, VK_PRValue, OK_Ordinary),
58e5dd7070Spatrick NumElements(VK.size()), HasPackExpansions(HasPackExpansions), Range(SR),
59e5dd7070Spatrick DictWithObjectsMethod(method) {
60e5dd7070Spatrick KeyValuePair *KeyValues = getTrailingObjects<KeyValuePair>();
61e5dd7070Spatrick ExpansionData *Expansions =
62e5dd7070Spatrick HasPackExpansions ? getTrailingObjects<ExpansionData>() : nullptr;
63e5dd7070Spatrick for (unsigned I = 0; I < NumElements; I++) {
64e5dd7070Spatrick KeyValues[I].Key = VK[I].Key;
65e5dd7070Spatrick KeyValues[I].Value = VK[I].Value;
66e5dd7070Spatrick if (Expansions) {
67e5dd7070Spatrick Expansions[I].EllipsisLoc = VK[I].EllipsisLoc;
68e5dd7070Spatrick if (VK[I].NumExpansions)
69e5dd7070Spatrick Expansions[I].NumExpansionsPlusOne = *VK[I].NumExpansions + 1;
70e5dd7070Spatrick else
71e5dd7070Spatrick Expansions[I].NumExpansionsPlusOne = 0;
72e5dd7070Spatrick }
73e5dd7070Spatrick }
74ec727ea7Spatrick setDependence(computeDependence(this));
75e5dd7070Spatrick }
76e5dd7070Spatrick
77e5dd7070Spatrick ObjCDictionaryLiteral *
Create(const ASTContext & C,ArrayRef<ObjCDictionaryElement> VK,bool HasPackExpansions,QualType T,ObjCMethodDecl * method,SourceRange SR)78e5dd7070Spatrick ObjCDictionaryLiteral::Create(const ASTContext &C,
79e5dd7070Spatrick ArrayRef<ObjCDictionaryElement> VK,
80e5dd7070Spatrick bool HasPackExpansions, QualType T,
81e5dd7070Spatrick ObjCMethodDecl *method, SourceRange SR) {
82e5dd7070Spatrick void *Mem = C.Allocate(totalSizeToAlloc<KeyValuePair, ExpansionData>(
83e5dd7070Spatrick VK.size(), HasPackExpansions ? VK.size() : 0));
84e5dd7070Spatrick return new (Mem) ObjCDictionaryLiteral(VK, HasPackExpansions, T, method, SR);
85e5dd7070Spatrick }
86e5dd7070Spatrick
87e5dd7070Spatrick ObjCDictionaryLiteral *
CreateEmpty(const ASTContext & C,unsigned NumElements,bool HasPackExpansions)88e5dd7070Spatrick ObjCDictionaryLiteral::CreateEmpty(const ASTContext &C, unsigned NumElements,
89e5dd7070Spatrick bool HasPackExpansions) {
90e5dd7070Spatrick void *Mem = C.Allocate(totalSizeToAlloc<KeyValuePair, ExpansionData>(
91e5dd7070Spatrick NumElements, HasPackExpansions ? NumElements : 0));
92e5dd7070Spatrick return new (Mem)
93e5dd7070Spatrick ObjCDictionaryLiteral(EmptyShell(), NumElements, HasPackExpansions);
94e5dd7070Spatrick }
95e5dd7070Spatrick
getReceiverType(const ASTContext & ctx) const96e5dd7070Spatrick QualType ObjCPropertyRefExpr::getReceiverType(const ASTContext &ctx) const {
97e5dd7070Spatrick if (isClassReceiver())
98e5dd7070Spatrick return ctx.getObjCInterfaceType(getClassReceiver());
99e5dd7070Spatrick
100e5dd7070Spatrick if (isSuperReceiver())
101e5dd7070Spatrick return getSuperReceiverType();
102e5dd7070Spatrick
103e5dd7070Spatrick return getBase()->getType();
104e5dd7070Spatrick }
105e5dd7070Spatrick
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)106e5dd7070Spatrick ObjCMessageExpr::ObjCMessageExpr(QualType T, ExprValueKind VK,
107e5dd7070Spatrick SourceLocation LBracLoc,
108e5dd7070Spatrick SourceLocation SuperLoc, bool IsInstanceSuper,
109e5dd7070Spatrick QualType SuperType, Selector Sel,
110e5dd7070Spatrick ArrayRef<SourceLocation> SelLocs,
111e5dd7070Spatrick SelectorLocationsKind SelLocsK,
112e5dd7070Spatrick ObjCMethodDecl *Method, ArrayRef<Expr *> Args,
113e5dd7070Spatrick SourceLocation RBracLoc, bool isImplicit)
114ec727ea7Spatrick : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary),
115e5dd7070Spatrick SelectorOrMethod(
116e5dd7070Spatrick reinterpret_cast<uintptr_t>(Method ? Method : Sel.getAsOpaquePtr())),
117e5dd7070Spatrick Kind(IsInstanceSuper ? SuperInstance : SuperClass),
118e5dd7070Spatrick HasMethod(Method != nullptr), IsDelegateInitCall(false),
119e5dd7070Spatrick IsImplicit(isImplicit), SuperLoc(SuperLoc), LBracLoc(LBracLoc),
120e5dd7070Spatrick RBracLoc(RBracLoc) {
121e5dd7070Spatrick initArgsAndSelLocs(Args, SelLocs, SelLocsK);
122e5dd7070Spatrick setReceiverPointer(SuperType.getAsOpaquePtr());
123ec727ea7Spatrick setDependence(computeDependence(this));
124e5dd7070Spatrick }
125e5dd7070Spatrick
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)126e5dd7070Spatrick ObjCMessageExpr::ObjCMessageExpr(QualType T, ExprValueKind VK,
127e5dd7070Spatrick SourceLocation LBracLoc,
128e5dd7070Spatrick TypeSourceInfo *Receiver, Selector Sel,
129e5dd7070Spatrick ArrayRef<SourceLocation> SelLocs,
130e5dd7070Spatrick SelectorLocationsKind SelLocsK,
131e5dd7070Spatrick ObjCMethodDecl *Method, ArrayRef<Expr *> Args,
132e5dd7070Spatrick SourceLocation RBracLoc, bool isImplicit)
133ec727ea7Spatrick : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary),
134e5dd7070Spatrick SelectorOrMethod(
135e5dd7070Spatrick reinterpret_cast<uintptr_t>(Method ? Method : Sel.getAsOpaquePtr())),
136e5dd7070Spatrick Kind(Class), HasMethod(Method != nullptr), IsDelegateInitCall(false),
137e5dd7070Spatrick IsImplicit(isImplicit), LBracLoc(LBracLoc), RBracLoc(RBracLoc) {
138e5dd7070Spatrick initArgsAndSelLocs(Args, SelLocs, SelLocsK);
139e5dd7070Spatrick setReceiverPointer(Receiver);
140ec727ea7Spatrick setDependence(computeDependence(this));
141e5dd7070Spatrick }
142e5dd7070Spatrick
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)143e5dd7070Spatrick ObjCMessageExpr::ObjCMessageExpr(QualType T, ExprValueKind VK,
144e5dd7070Spatrick SourceLocation LBracLoc, Expr *Receiver,
145e5dd7070Spatrick Selector Sel, ArrayRef<SourceLocation> SelLocs,
146e5dd7070Spatrick SelectorLocationsKind SelLocsK,
147e5dd7070Spatrick ObjCMethodDecl *Method, ArrayRef<Expr *> Args,
148e5dd7070Spatrick SourceLocation RBracLoc, bool isImplicit)
149ec727ea7Spatrick : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary),
150e5dd7070Spatrick SelectorOrMethod(
151e5dd7070Spatrick reinterpret_cast<uintptr_t>(Method ? Method : Sel.getAsOpaquePtr())),
152e5dd7070Spatrick Kind(Instance), HasMethod(Method != nullptr), IsDelegateInitCall(false),
153e5dd7070Spatrick IsImplicit(isImplicit), LBracLoc(LBracLoc), RBracLoc(RBracLoc) {
154e5dd7070Spatrick initArgsAndSelLocs(Args, SelLocs, SelLocsK);
155e5dd7070Spatrick setReceiverPointer(Receiver);
156ec727ea7Spatrick setDependence(computeDependence(this));
157e5dd7070Spatrick }
158e5dd7070Spatrick
initArgsAndSelLocs(ArrayRef<Expr * > Args,ArrayRef<SourceLocation> SelLocs,SelectorLocationsKind SelLocsK)159e5dd7070Spatrick void ObjCMessageExpr::initArgsAndSelLocs(ArrayRef<Expr *> Args,
160e5dd7070Spatrick ArrayRef<SourceLocation> SelLocs,
161e5dd7070Spatrick SelectorLocationsKind SelLocsK) {
162e5dd7070Spatrick setNumArgs(Args.size());
163e5dd7070Spatrick Expr **MyArgs = getArgs();
164ec727ea7Spatrick for (unsigned I = 0; I != Args.size(); ++I)
165e5dd7070Spatrick MyArgs[I] = Args[I];
166e5dd7070Spatrick
167e5dd7070Spatrick SelLocsKind = SelLocsK;
168e5dd7070Spatrick if (!isImplicit()) {
169e5dd7070Spatrick if (SelLocsK == SelLoc_NonStandard)
170e5dd7070Spatrick std::copy(SelLocs.begin(), SelLocs.end(), getStoredSelLocs());
171e5dd7070Spatrick }
172e5dd7070Spatrick }
173e5dd7070Spatrick
174e5dd7070Spatrick 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)175e5dd7070Spatrick ObjCMessageExpr::Create(const ASTContext &Context, QualType T, ExprValueKind VK,
176e5dd7070Spatrick SourceLocation LBracLoc, SourceLocation SuperLoc,
177e5dd7070Spatrick bool IsInstanceSuper, QualType SuperType, Selector Sel,
178e5dd7070Spatrick ArrayRef<SourceLocation> SelLocs,
179e5dd7070Spatrick ObjCMethodDecl *Method, ArrayRef<Expr *> Args,
180e5dd7070Spatrick SourceLocation RBracLoc, bool isImplicit) {
181e5dd7070Spatrick assert((!SelLocs.empty() || isImplicit) &&
182e5dd7070Spatrick "No selector locs for non-implicit message");
183e5dd7070Spatrick ObjCMessageExpr *Mem;
184e5dd7070Spatrick SelectorLocationsKind SelLocsK = SelectorLocationsKind();
185e5dd7070Spatrick if (isImplicit)
186e5dd7070Spatrick Mem = alloc(Context, Args.size(), 0);
187e5dd7070Spatrick else
188e5dd7070Spatrick Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK);
189e5dd7070Spatrick return new (Mem) ObjCMessageExpr(T, VK, LBracLoc, SuperLoc, IsInstanceSuper,
190e5dd7070Spatrick SuperType, Sel, SelLocs, SelLocsK, Method,
191e5dd7070Spatrick Args, RBracLoc, isImplicit);
192e5dd7070Spatrick }
193e5dd7070Spatrick
194e5dd7070Spatrick 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)195e5dd7070Spatrick ObjCMessageExpr::Create(const ASTContext &Context, QualType T, ExprValueKind VK,
196e5dd7070Spatrick SourceLocation LBracLoc, TypeSourceInfo *Receiver,
197e5dd7070Spatrick Selector Sel, ArrayRef<SourceLocation> SelLocs,
198e5dd7070Spatrick ObjCMethodDecl *Method, ArrayRef<Expr *> Args,
199e5dd7070Spatrick SourceLocation RBracLoc, bool isImplicit) {
200e5dd7070Spatrick assert((!SelLocs.empty() || isImplicit) &&
201e5dd7070Spatrick "No selector locs for non-implicit message");
202e5dd7070Spatrick ObjCMessageExpr *Mem;
203e5dd7070Spatrick SelectorLocationsKind SelLocsK = SelectorLocationsKind();
204e5dd7070Spatrick if (isImplicit)
205e5dd7070Spatrick Mem = alloc(Context, Args.size(), 0);
206e5dd7070Spatrick else
207e5dd7070Spatrick Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK);
208e5dd7070Spatrick return new (Mem)
209e5dd7070Spatrick ObjCMessageExpr(T, VK, LBracLoc, Receiver, Sel, SelLocs, SelLocsK, Method,
210e5dd7070Spatrick Args, RBracLoc, isImplicit);
211e5dd7070Spatrick }
212e5dd7070Spatrick
213e5dd7070Spatrick 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)214e5dd7070Spatrick ObjCMessageExpr::Create(const ASTContext &Context, QualType T, ExprValueKind VK,
215e5dd7070Spatrick SourceLocation LBracLoc, Expr *Receiver, Selector Sel,
216e5dd7070Spatrick ArrayRef<SourceLocation> SelLocs,
217e5dd7070Spatrick ObjCMethodDecl *Method, ArrayRef<Expr *> Args,
218e5dd7070Spatrick SourceLocation RBracLoc, bool isImplicit) {
219e5dd7070Spatrick assert((!SelLocs.empty() || isImplicit) &&
220e5dd7070Spatrick "No selector locs for non-implicit message");
221e5dd7070Spatrick ObjCMessageExpr *Mem;
222e5dd7070Spatrick SelectorLocationsKind SelLocsK = SelectorLocationsKind();
223e5dd7070Spatrick if (isImplicit)
224e5dd7070Spatrick Mem = alloc(Context, Args.size(), 0);
225e5dd7070Spatrick else
226e5dd7070Spatrick Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK);
227e5dd7070Spatrick return new (Mem)
228e5dd7070Spatrick ObjCMessageExpr(T, VK, LBracLoc, Receiver, Sel, SelLocs, SelLocsK, Method,
229e5dd7070Spatrick Args, RBracLoc, isImplicit);
230e5dd7070Spatrick }
231e5dd7070Spatrick
CreateEmpty(const ASTContext & Context,unsigned NumArgs,unsigned NumStoredSelLocs)232e5dd7070Spatrick ObjCMessageExpr *ObjCMessageExpr::CreateEmpty(const ASTContext &Context,
233e5dd7070Spatrick unsigned NumArgs,
234e5dd7070Spatrick unsigned NumStoredSelLocs) {
235e5dd7070Spatrick ObjCMessageExpr *Mem = alloc(Context, NumArgs, NumStoredSelLocs);
236e5dd7070Spatrick return new (Mem) ObjCMessageExpr(EmptyShell(), NumArgs);
237e5dd7070Spatrick }
238e5dd7070Spatrick
alloc(const ASTContext & C,ArrayRef<Expr * > Args,SourceLocation RBraceLoc,ArrayRef<SourceLocation> SelLocs,Selector Sel,SelectorLocationsKind & SelLocsK)239e5dd7070Spatrick ObjCMessageExpr *ObjCMessageExpr::alloc(const ASTContext &C,
240e5dd7070Spatrick ArrayRef<Expr *> Args,
241e5dd7070Spatrick SourceLocation RBraceLoc,
242e5dd7070Spatrick ArrayRef<SourceLocation> SelLocs,
243e5dd7070Spatrick Selector Sel,
244e5dd7070Spatrick SelectorLocationsKind &SelLocsK) {
245e5dd7070Spatrick SelLocsK = hasStandardSelectorLocs(Sel, SelLocs, Args, RBraceLoc);
246e5dd7070Spatrick unsigned NumStoredSelLocs =
247e5dd7070Spatrick (SelLocsK == SelLoc_NonStandard) ? SelLocs.size() : 0;
248e5dd7070Spatrick return alloc(C, Args.size(), NumStoredSelLocs);
249e5dd7070Spatrick }
250e5dd7070Spatrick
alloc(const ASTContext & C,unsigned NumArgs,unsigned NumStoredSelLocs)251e5dd7070Spatrick ObjCMessageExpr *ObjCMessageExpr::alloc(const ASTContext &C, unsigned NumArgs,
252e5dd7070Spatrick unsigned NumStoredSelLocs) {
253e5dd7070Spatrick return (ObjCMessageExpr *)C.Allocate(
254e5dd7070Spatrick totalSizeToAlloc<void *, SourceLocation>(NumArgs + 1, NumStoredSelLocs),
255e5dd7070Spatrick alignof(ObjCMessageExpr));
256e5dd7070Spatrick }
257e5dd7070Spatrick
getSelectorLocs(SmallVectorImpl<SourceLocation> & SelLocs) const258e5dd7070Spatrick void ObjCMessageExpr::getSelectorLocs(
259e5dd7070Spatrick SmallVectorImpl<SourceLocation> &SelLocs) const {
260e5dd7070Spatrick for (unsigned i = 0, e = getNumSelectorLocs(); i != e; ++i)
261e5dd7070Spatrick SelLocs.push_back(getSelectorLoc(i));
262e5dd7070Spatrick }
263e5dd7070Spatrick
264e5dd7070Spatrick
getCallReturnType(ASTContext & Ctx) const265e5dd7070Spatrick QualType ObjCMessageExpr::getCallReturnType(ASTContext &Ctx) const {
266e5dd7070Spatrick if (const ObjCMethodDecl *MD = getMethodDecl()) {
267e5dd7070Spatrick QualType QT = MD->getReturnType();
268e5dd7070Spatrick if (QT == Ctx.getObjCInstanceType()) {
269e5dd7070Spatrick // instancetype corresponds to expression types.
270e5dd7070Spatrick return getType();
271e5dd7070Spatrick }
272e5dd7070Spatrick return QT;
273e5dd7070Spatrick }
274*12c85518Srobert return Ctx.getReferenceQualifiedType(this);
275e5dd7070Spatrick }
276e5dd7070Spatrick
getReceiverRange() const277e5dd7070Spatrick SourceRange ObjCMessageExpr::getReceiverRange() const {
278e5dd7070Spatrick switch (getReceiverKind()) {
279e5dd7070Spatrick case Instance:
280e5dd7070Spatrick return getInstanceReceiver()->getSourceRange();
281e5dd7070Spatrick
282e5dd7070Spatrick case Class:
283e5dd7070Spatrick return getClassReceiverTypeInfo()->getTypeLoc().getSourceRange();
284e5dd7070Spatrick
285e5dd7070Spatrick case SuperInstance:
286e5dd7070Spatrick case SuperClass:
287e5dd7070Spatrick return getSuperLoc();
288e5dd7070Spatrick }
289e5dd7070Spatrick
290e5dd7070Spatrick llvm_unreachable("Invalid ReceiverKind!");
291e5dd7070Spatrick }
292e5dd7070Spatrick
getSelector() const293e5dd7070Spatrick Selector ObjCMessageExpr::getSelector() const {
294e5dd7070Spatrick if (HasMethod)
295e5dd7070Spatrick return reinterpret_cast<const ObjCMethodDecl *>(SelectorOrMethod)
296e5dd7070Spatrick ->getSelector();
297e5dd7070Spatrick return Selector(SelectorOrMethod);
298e5dd7070Spatrick }
299e5dd7070Spatrick
getReceiverType() const300e5dd7070Spatrick QualType ObjCMessageExpr::getReceiverType() const {
301e5dd7070Spatrick switch (getReceiverKind()) {
302e5dd7070Spatrick case Instance:
303e5dd7070Spatrick return getInstanceReceiver()->getType();
304e5dd7070Spatrick case Class:
305e5dd7070Spatrick return getClassReceiver();
306e5dd7070Spatrick case SuperInstance:
307e5dd7070Spatrick case SuperClass:
308e5dd7070Spatrick return getSuperType();
309e5dd7070Spatrick }
310e5dd7070Spatrick
311e5dd7070Spatrick llvm_unreachable("unexpected receiver kind");
312e5dd7070Spatrick }
313e5dd7070Spatrick
getReceiverInterface() const314e5dd7070Spatrick ObjCInterfaceDecl *ObjCMessageExpr::getReceiverInterface() const {
315e5dd7070Spatrick QualType T = getReceiverType();
316e5dd7070Spatrick
317e5dd7070Spatrick if (const ObjCObjectPointerType *Ptr = T->getAs<ObjCObjectPointerType>())
318e5dd7070Spatrick return Ptr->getInterfaceDecl();
319e5dd7070Spatrick
320e5dd7070Spatrick if (const ObjCObjectType *Ty = T->getAs<ObjCObjectType>())
321e5dd7070Spatrick return Ty->getInterface();
322e5dd7070Spatrick
323e5dd7070Spatrick return nullptr;
324e5dd7070Spatrick }
325e5dd7070Spatrick
children()326e5dd7070Spatrick Stmt::child_range ObjCMessageExpr::children() {
327e5dd7070Spatrick Stmt **begin;
328e5dd7070Spatrick if (getReceiverKind() == Instance)
329e5dd7070Spatrick begin = reinterpret_cast<Stmt **>(getTrailingObjects<void *>());
330e5dd7070Spatrick else
331e5dd7070Spatrick begin = reinterpret_cast<Stmt **>(getArgs());
332e5dd7070Spatrick return child_range(begin,
333e5dd7070Spatrick reinterpret_cast<Stmt **>(getArgs() + getNumArgs()));
334e5dd7070Spatrick }
335e5dd7070Spatrick
children() const336e5dd7070Spatrick Stmt::const_child_range ObjCMessageExpr::children() const {
337e5dd7070Spatrick auto Children = const_cast<ObjCMessageExpr *>(this)->children();
338e5dd7070Spatrick return const_child_range(Children.begin(), Children.end());
339e5dd7070Spatrick }
340e5dd7070Spatrick
getBridgeKindName() const341e5dd7070Spatrick StringRef ObjCBridgedCastExpr::getBridgeKindName() const {
342e5dd7070Spatrick switch (getBridgeKind()) {
343e5dd7070Spatrick case OBC_Bridge:
344e5dd7070Spatrick return "__bridge";
345e5dd7070Spatrick case OBC_BridgeTransfer:
346e5dd7070Spatrick return "__bridge_transfer";
347e5dd7070Spatrick case OBC_BridgeRetained:
348e5dd7070Spatrick return "__bridge_retained";
349e5dd7070Spatrick }
350e5dd7070Spatrick
351e5dd7070Spatrick llvm_unreachable("Invalid BridgeKind!");
352e5dd7070Spatrick }
353