1 //===--- ExprObjC.cpp - (ObjC) Expression AST Node Implementation ---------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file implements the subclesses of Expr class declared in ExprObjC.h
12 //===----------------------------------------------------------------------===//
14 #include "clang/AST/ExprObjC.h"
16 #include "clang/AST/ASTContext.h"
18 using namespace clang;
20 ObjCArrayLiteral::ObjCArrayLiteral(ArrayRef<Expr *> Elements, QualType T,
21 ObjCMethodDecl *Method, SourceRange SR)
22 : Expr(ObjCArrayLiteralClass, T, VK_RValue, OK_Ordinary, false, false,
24 NumElements(Elements.size()), Range(SR), ArrayWithObjectsMethod(Method) {
25 Expr **SaveElements = getElements();
26 for (unsigned I = 0, N = Elements.size(); I != N; ++I) {
27 if (Elements[I]->isTypeDependent() || Elements[I]->isValueDependent())
28 ExprBits.ValueDependent = true;
29 if (Elements[I]->isInstantiationDependent())
30 ExprBits.InstantiationDependent = true;
31 if (Elements[I]->containsUnexpandedParameterPack())
32 ExprBits.ContainsUnexpandedParameterPack = true;
34 SaveElements[I] = Elements[I];
38 ObjCArrayLiteral *ObjCArrayLiteral::Create(const ASTContext &C,
39 ArrayRef<Expr *> Elements,
40 QualType T, ObjCMethodDecl *Method,
43 C.Allocate(sizeof(ObjCArrayLiteral) + Elements.size() * sizeof(Expr *));
44 return new (Mem) ObjCArrayLiteral(Elements, T, Method, SR);
47 ObjCArrayLiteral *ObjCArrayLiteral::CreateEmpty(const ASTContext &C,
48 unsigned NumElements) {
51 C.Allocate(sizeof(ObjCArrayLiteral) + NumElements * sizeof(Expr *));
52 return new (Mem) ObjCArrayLiteral(EmptyShell(), NumElements);
55 ObjCDictionaryLiteral::ObjCDictionaryLiteral(ArrayRef<ObjCDictionaryElement> VK,
56 bool HasPackExpansions, QualType T,
57 ObjCMethodDecl *method,
59 : Expr(ObjCDictionaryLiteralClass, T, VK_RValue, OK_Ordinary, false, false,
61 NumElements(VK.size()), HasPackExpansions(HasPackExpansions), Range(SR),
62 DictWithObjectsMethod(method) {
63 KeyValuePair *KeyValues = getKeyValues();
64 ExpansionData *Expansions = getExpansionData();
65 for (unsigned I = 0; I < NumElements; I++) {
66 if (VK[I].Key->isTypeDependent() || VK[I].Key->isValueDependent() ||
67 VK[I].Value->isTypeDependent() || VK[I].Value->isValueDependent())
68 ExprBits.ValueDependent = true;
69 if (VK[I].Key->isInstantiationDependent() ||
70 VK[I].Value->isInstantiationDependent())
71 ExprBits.InstantiationDependent = true;
72 if (VK[I].EllipsisLoc.isInvalid() &&
73 (VK[I].Key->containsUnexpandedParameterPack() ||
74 VK[I].Value->containsUnexpandedParameterPack()))
75 ExprBits.ContainsUnexpandedParameterPack = true;
77 KeyValues[I].Key = VK[I].Key;
78 KeyValues[I].Value = VK[I].Value;
80 Expansions[I].EllipsisLoc = VK[I].EllipsisLoc;
81 if (VK[I].NumExpansions)
82 Expansions[I].NumExpansionsPlusOne = *VK[I].NumExpansions + 1;
84 Expansions[I].NumExpansionsPlusOne = 0;
89 ObjCDictionaryLiteral *
90 ObjCDictionaryLiteral::Create(const ASTContext &C,
91 ArrayRef<ObjCDictionaryElement> VK,
92 bool HasPackExpansions, QualType T,
93 ObjCMethodDecl *method, SourceRange SR) {
94 unsigned ExpansionsSize = 0;
95 if (HasPackExpansions)
96 ExpansionsSize = sizeof(ExpansionData) * VK.size();
98 void *Mem = C.Allocate(sizeof(ObjCDictionaryLiteral) +
99 sizeof(KeyValuePair) * VK.size() + ExpansionsSize);
100 return new (Mem) ObjCDictionaryLiteral(VK, HasPackExpansions, T, method, SR);
103 ObjCDictionaryLiteral *
104 ObjCDictionaryLiteral::CreateEmpty(const ASTContext &C, unsigned NumElements,
105 bool HasPackExpansions) {
106 unsigned ExpansionsSize = 0;
107 if (HasPackExpansions)
108 ExpansionsSize = sizeof(ExpansionData) * NumElements;
109 void *Mem = C.Allocate(sizeof(ObjCDictionaryLiteral) +
110 sizeof(KeyValuePair) * NumElements + ExpansionsSize);
112 ObjCDictionaryLiteral(EmptyShell(), NumElements, HasPackExpansions);
115 QualType ObjCPropertyRefExpr::getReceiverType(const ASTContext &ctx) const {
116 if (isClassReceiver())
117 return ctx.getObjCInterfaceType(getClassReceiver());
119 if (isSuperReceiver())
120 return getSuperReceiverType();
122 return getBase()->getType();
125 ObjCSubscriptRefExpr *
126 ObjCSubscriptRefExpr::Create(const ASTContext &C, Expr *base, Expr *key,
127 QualType T, ObjCMethodDecl *getMethod,
128 ObjCMethodDecl *setMethod, SourceLocation RB) {
129 void *Mem = C.Allocate(sizeof(ObjCSubscriptRefExpr));
130 return new (Mem) ObjCSubscriptRefExpr(
131 base, key, T, VK_LValue, OK_ObjCSubscript, getMethod, setMethod, RB);
134 ObjCMessageExpr::ObjCMessageExpr(QualType T, ExprValueKind VK,
135 SourceLocation LBracLoc,
136 SourceLocation SuperLoc, bool IsInstanceSuper,
137 QualType SuperType, Selector Sel,
138 ArrayRef<SourceLocation> SelLocs,
139 SelectorLocationsKind SelLocsK,
140 ObjCMethodDecl *Method, ArrayRef<Expr *> Args,
141 SourceLocation RBracLoc, bool isImplicit)
142 : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary,
143 /*TypeDependent=*/false, /*ValueDependent=*/false,
144 /*InstantiationDependent=*/false,
145 /*ContainsUnexpandedParameterPack=*/false),
147 reinterpret_cast<uintptr_t>(Method ? Method : Sel.getAsOpaquePtr())),
148 Kind(IsInstanceSuper ? SuperInstance : SuperClass),
149 HasMethod(Method != nullptr), IsDelegateInitCall(false),
150 IsImplicit(isImplicit), SuperLoc(SuperLoc), LBracLoc(LBracLoc),
152 initArgsAndSelLocs(Args, SelLocs, SelLocsK);
153 setReceiverPointer(SuperType.getAsOpaquePtr());
156 ObjCMessageExpr::ObjCMessageExpr(QualType T, ExprValueKind VK,
157 SourceLocation LBracLoc,
158 TypeSourceInfo *Receiver, Selector Sel,
159 ArrayRef<SourceLocation> SelLocs,
160 SelectorLocationsKind SelLocsK,
161 ObjCMethodDecl *Method, ArrayRef<Expr *> Args,
162 SourceLocation RBracLoc, bool isImplicit)
163 : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary, T->isDependentType(),
164 T->isDependentType(), T->isInstantiationDependentType(),
165 T->containsUnexpandedParameterPack()),
167 reinterpret_cast<uintptr_t>(Method ? Method : Sel.getAsOpaquePtr())),
168 Kind(Class), HasMethod(Method != nullptr), IsDelegateInitCall(false),
169 IsImplicit(isImplicit), LBracLoc(LBracLoc), RBracLoc(RBracLoc) {
170 initArgsAndSelLocs(Args, SelLocs, SelLocsK);
171 setReceiverPointer(Receiver);
174 ObjCMessageExpr::ObjCMessageExpr(QualType T, ExprValueKind VK,
175 SourceLocation LBracLoc, Expr *Receiver,
176 Selector Sel, ArrayRef<SourceLocation> SelLocs,
177 SelectorLocationsKind SelLocsK,
178 ObjCMethodDecl *Method, ArrayRef<Expr *> Args,
179 SourceLocation RBracLoc, bool isImplicit)
180 : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary,
181 Receiver->isTypeDependent(), Receiver->isTypeDependent(),
182 Receiver->isInstantiationDependent(),
183 Receiver->containsUnexpandedParameterPack()),
185 reinterpret_cast<uintptr_t>(Method ? Method : Sel.getAsOpaquePtr())),
186 Kind(Instance), HasMethod(Method != nullptr), IsDelegateInitCall(false),
187 IsImplicit(isImplicit), LBracLoc(LBracLoc), RBracLoc(RBracLoc) {
188 initArgsAndSelLocs(Args, SelLocs, SelLocsK);
189 setReceiverPointer(Receiver);
192 void ObjCMessageExpr::initArgsAndSelLocs(ArrayRef<Expr *> Args,
193 ArrayRef<SourceLocation> SelLocs,
194 SelectorLocationsKind SelLocsK) {
195 setNumArgs(Args.size());
196 Expr **MyArgs = getArgs();
197 for (unsigned I = 0; I != Args.size(); ++I) {
198 if (Args[I]->isTypeDependent())
199 ExprBits.TypeDependent = true;
200 if (Args[I]->isValueDependent())
201 ExprBits.ValueDependent = true;
202 if (Args[I]->isInstantiationDependent())
203 ExprBits.InstantiationDependent = true;
204 if (Args[I]->containsUnexpandedParameterPack())
205 ExprBits.ContainsUnexpandedParameterPack = true;
210 SelLocsKind = SelLocsK;
212 if (SelLocsK == SelLoc_NonStandard)
213 std::copy(SelLocs.begin(), SelLocs.end(), getStoredSelLocs());
218 ObjCMessageExpr::Create(const ASTContext &Context, QualType T, ExprValueKind VK,
219 SourceLocation LBracLoc, SourceLocation SuperLoc,
220 bool IsInstanceSuper, QualType SuperType, Selector Sel,
221 ArrayRef<SourceLocation> SelLocs,
222 ObjCMethodDecl *Method, ArrayRef<Expr *> Args,
223 SourceLocation RBracLoc, bool isImplicit) {
224 assert((!SelLocs.empty() || isImplicit) &&
225 "No selector locs for non-implicit message");
226 ObjCMessageExpr *Mem;
227 SelectorLocationsKind SelLocsK = SelectorLocationsKind();
229 Mem = alloc(Context, Args.size(), 0);
231 Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK);
232 return new (Mem) ObjCMessageExpr(T, VK, LBracLoc, SuperLoc, IsInstanceSuper,
233 SuperType, Sel, SelLocs, SelLocsK, Method,
234 Args, RBracLoc, isImplicit);
238 ObjCMessageExpr::Create(const ASTContext &Context, QualType T, ExprValueKind VK,
239 SourceLocation LBracLoc, TypeSourceInfo *Receiver,
240 Selector Sel, ArrayRef<SourceLocation> SelLocs,
241 ObjCMethodDecl *Method, ArrayRef<Expr *> Args,
242 SourceLocation RBracLoc, bool isImplicit) {
243 assert((!SelLocs.empty() || isImplicit) &&
244 "No selector locs for non-implicit message");
245 ObjCMessageExpr *Mem;
246 SelectorLocationsKind SelLocsK = SelectorLocationsKind();
248 Mem = alloc(Context, Args.size(), 0);
250 Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK);
252 ObjCMessageExpr(T, VK, LBracLoc, Receiver, Sel, SelLocs, SelLocsK, Method,
253 Args, RBracLoc, isImplicit);
257 ObjCMessageExpr::Create(const ASTContext &Context, QualType T, ExprValueKind VK,
258 SourceLocation LBracLoc, Expr *Receiver, Selector Sel,
259 ArrayRef<SourceLocation> SelLocs,
260 ObjCMethodDecl *Method, ArrayRef<Expr *> Args,
261 SourceLocation RBracLoc, bool isImplicit) {
262 assert((!SelLocs.empty() || isImplicit) &&
263 "No selector locs for non-implicit message");
264 ObjCMessageExpr *Mem;
265 SelectorLocationsKind SelLocsK = SelectorLocationsKind();
267 Mem = alloc(Context, Args.size(), 0);
269 Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK);
271 ObjCMessageExpr(T, VK, LBracLoc, Receiver, Sel, SelLocs, SelLocsK, Method,
272 Args, RBracLoc, isImplicit);
275 ObjCMessageExpr *ObjCMessageExpr::CreateEmpty(const ASTContext &Context,
277 unsigned NumStoredSelLocs) {
278 ObjCMessageExpr *Mem = alloc(Context, NumArgs, NumStoredSelLocs);
279 return new (Mem) ObjCMessageExpr(EmptyShell(), NumArgs);
282 ObjCMessageExpr *ObjCMessageExpr::alloc(const ASTContext &C,
283 ArrayRef<Expr *> Args,
284 SourceLocation RBraceLoc,
285 ArrayRef<SourceLocation> SelLocs,
287 SelectorLocationsKind &SelLocsK) {
288 SelLocsK = hasStandardSelectorLocs(Sel, SelLocs, Args, RBraceLoc);
289 unsigned NumStoredSelLocs =
290 (SelLocsK == SelLoc_NonStandard) ? SelLocs.size() : 0;
291 return alloc(C, Args.size(), NumStoredSelLocs);
294 ObjCMessageExpr *ObjCMessageExpr::alloc(const ASTContext &C, unsigned NumArgs,
295 unsigned NumStoredSelLocs) {
296 unsigned Size = sizeof(ObjCMessageExpr) + sizeof(void *) +
297 NumArgs * sizeof(Expr *) +
298 NumStoredSelLocs * sizeof(SourceLocation);
299 return (ObjCMessageExpr *)C.Allocate(
300 Size, llvm::AlignOf<ObjCMessageExpr>::Alignment);
303 void ObjCMessageExpr::getSelectorLocs(
304 SmallVectorImpl<SourceLocation> &SelLocs) const {
305 for (unsigned i = 0, e = getNumSelectorLocs(); i != e; ++i)
306 SelLocs.push_back(getSelectorLoc(i));
309 SourceRange ObjCMessageExpr::getReceiverRange() const {
310 switch (getReceiverKind()) {
312 return getInstanceReceiver()->getSourceRange();
315 return getClassReceiverTypeInfo()->getTypeLoc().getSourceRange();
319 return getSuperLoc();
322 llvm_unreachable("Invalid ReceiverKind!");
325 Selector ObjCMessageExpr::getSelector() const {
327 return reinterpret_cast<const ObjCMethodDecl *>(SelectorOrMethod)
329 return Selector(SelectorOrMethod);
332 QualType ObjCMessageExpr::getReceiverType() const {
333 switch (getReceiverKind()) {
335 return getInstanceReceiver()->getType();
337 return getClassReceiver();
340 return getSuperType();
343 llvm_unreachable("unexpected receiver kind");
346 ObjCInterfaceDecl *ObjCMessageExpr::getReceiverInterface() const {
347 QualType T = getReceiverType();
349 if (const ObjCObjectPointerType *Ptr = T->getAs<ObjCObjectPointerType>())
350 return Ptr->getInterfaceDecl();
352 if (const ObjCObjectType *Ty = T->getAs<ObjCObjectType>())
353 return Ty->getInterface();
358 Stmt::child_range ObjCMessageExpr::children() {
360 if (getReceiverKind() == Instance)
361 begin = reinterpret_cast<Stmt **>(this + 1);
363 begin = reinterpret_cast<Stmt **>(getArgs());
364 return child_range(begin,
365 reinterpret_cast<Stmt **>(getArgs() + getNumArgs()));
368 StringRef ObjCBridgedCastExpr::getBridgeKindName() const {
369 switch (getBridgeKind()) {
372 case OBC_BridgeTransfer:
373 return "__bridge_transfer";
374 case OBC_BridgeRetained:
375 return "__bridge_retained";
378 llvm_unreachable("Invalid BridgeKind!");