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,
42 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(Elements.size()));
43 return new (Mem) ObjCArrayLiteral(Elements, T, Method, SR);
46 ObjCArrayLiteral *ObjCArrayLiteral::CreateEmpty(const ASTContext &C,
47 unsigned NumElements) {
49 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(NumElements));
50 return new (Mem) ObjCArrayLiteral(EmptyShell(), NumElements);
53 ObjCDictionaryLiteral::ObjCDictionaryLiteral(ArrayRef<ObjCDictionaryElement> VK,
54 bool HasPackExpansions, QualType T,
55 ObjCMethodDecl *method,
57 : Expr(ObjCDictionaryLiteralClass, T, VK_RValue, OK_Ordinary, false, false,
59 NumElements(VK.size()), HasPackExpansions(HasPackExpansions), Range(SR),
60 DictWithObjectsMethod(method) {
61 KeyValuePair *KeyValues = getTrailingObjects<KeyValuePair>();
62 ExpansionData *Expansions =
63 HasPackExpansions ? getTrailingObjects<ExpansionData>() : nullptr;
64 for (unsigned I = 0; I < NumElements; I++) {
65 if (VK[I].Key->isTypeDependent() || VK[I].Key->isValueDependent() ||
66 VK[I].Value->isTypeDependent() || VK[I].Value->isValueDependent())
67 ExprBits.ValueDependent = true;
68 if (VK[I].Key->isInstantiationDependent() ||
69 VK[I].Value->isInstantiationDependent())
70 ExprBits.InstantiationDependent = true;
71 if (VK[I].EllipsisLoc.isInvalid() &&
72 (VK[I].Key->containsUnexpandedParameterPack() ||
73 VK[I].Value->containsUnexpandedParameterPack()))
74 ExprBits.ContainsUnexpandedParameterPack = true;
76 KeyValues[I].Key = VK[I].Key;
77 KeyValues[I].Value = VK[I].Value;
79 Expansions[I].EllipsisLoc = VK[I].EllipsisLoc;
80 if (VK[I].NumExpansions)
81 Expansions[I].NumExpansionsPlusOne = *VK[I].NumExpansions + 1;
83 Expansions[I].NumExpansionsPlusOne = 0;
88 ObjCDictionaryLiteral *
89 ObjCDictionaryLiteral::Create(const ASTContext &C,
90 ArrayRef<ObjCDictionaryElement> VK,
91 bool HasPackExpansions, QualType T,
92 ObjCMethodDecl *method, SourceRange SR) {
93 void *Mem = C.Allocate(totalSizeToAlloc<KeyValuePair, ExpansionData>(
94 VK.size(), HasPackExpansions ? VK.size() : 0));
95 return new (Mem) ObjCDictionaryLiteral(VK, HasPackExpansions, T, method, SR);
98 ObjCDictionaryLiteral *
99 ObjCDictionaryLiteral::CreateEmpty(const ASTContext &C, unsigned NumElements,
100 bool HasPackExpansions) {
101 void *Mem = C.Allocate(totalSizeToAlloc<KeyValuePair, ExpansionData>(
102 NumElements, HasPackExpansions ? NumElements : 0));
104 ObjCDictionaryLiteral(EmptyShell(), NumElements, HasPackExpansions);
107 QualType ObjCPropertyRefExpr::getReceiverType(const ASTContext &ctx) const {
108 if (isClassReceiver())
109 return ctx.getObjCInterfaceType(getClassReceiver());
111 if (isSuperReceiver())
112 return getSuperReceiverType();
114 return getBase()->getType();
117 ObjCMessageExpr::ObjCMessageExpr(QualType T, ExprValueKind VK,
118 SourceLocation LBracLoc,
119 SourceLocation SuperLoc, bool IsInstanceSuper,
120 QualType SuperType, Selector Sel,
121 ArrayRef<SourceLocation> SelLocs,
122 SelectorLocationsKind SelLocsK,
123 ObjCMethodDecl *Method, ArrayRef<Expr *> Args,
124 SourceLocation RBracLoc, bool isImplicit)
125 : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary,
126 /*TypeDependent=*/false, /*ValueDependent=*/false,
127 /*InstantiationDependent=*/false,
128 /*ContainsUnexpandedParameterPack=*/false),
130 reinterpret_cast<uintptr_t>(Method ? Method : Sel.getAsOpaquePtr())),
131 Kind(IsInstanceSuper ? SuperInstance : SuperClass),
132 HasMethod(Method != nullptr), IsDelegateInitCall(false),
133 IsImplicit(isImplicit), SuperLoc(SuperLoc), LBracLoc(LBracLoc),
135 initArgsAndSelLocs(Args, SelLocs, SelLocsK);
136 setReceiverPointer(SuperType.getAsOpaquePtr());
139 ObjCMessageExpr::ObjCMessageExpr(QualType T, ExprValueKind VK,
140 SourceLocation LBracLoc,
141 TypeSourceInfo *Receiver, Selector Sel,
142 ArrayRef<SourceLocation> SelLocs,
143 SelectorLocationsKind SelLocsK,
144 ObjCMethodDecl *Method, ArrayRef<Expr *> Args,
145 SourceLocation RBracLoc, bool isImplicit)
146 : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary, T->isDependentType(),
147 T->isDependentType(), T->isInstantiationDependentType(),
148 T->containsUnexpandedParameterPack()),
150 reinterpret_cast<uintptr_t>(Method ? Method : Sel.getAsOpaquePtr())),
151 Kind(Class), HasMethod(Method != nullptr), IsDelegateInitCall(false),
152 IsImplicit(isImplicit), LBracLoc(LBracLoc), RBracLoc(RBracLoc) {
153 initArgsAndSelLocs(Args, SelLocs, SelLocsK);
154 setReceiverPointer(Receiver);
157 ObjCMessageExpr::ObjCMessageExpr(QualType T, ExprValueKind VK,
158 SourceLocation LBracLoc, Expr *Receiver,
159 Selector Sel, ArrayRef<SourceLocation> SelLocs,
160 SelectorLocationsKind SelLocsK,
161 ObjCMethodDecl *Method, ArrayRef<Expr *> Args,
162 SourceLocation RBracLoc, bool isImplicit)
163 : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary,
164 Receiver->isTypeDependent(), Receiver->isTypeDependent(),
165 Receiver->isInstantiationDependent(),
166 Receiver->containsUnexpandedParameterPack()),
168 reinterpret_cast<uintptr_t>(Method ? Method : Sel.getAsOpaquePtr())),
169 Kind(Instance), HasMethod(Method != nullptr), IsDelegateInitCall(false),
170 IsImplicit(isImplicit), LBracLoc(LBracLoc), RBracLoc(RBracLoc) {
171 initArgsAndSelLocs(Args, SelLocs, SelLocsK);
172 setReceiverPointer(Receiver);
175 void ObjCMessageExpr::initArgsAndSelLocs(ArrayRef<Expr *> Args,
176 ArrayRef<SourceLocation> SelLocs,
177 SelectorLocationsKind SelLocsK) {
178 setNumArgs(Args.size());
179 Expr **MyArgs = getArgs();
180 for (unsigned I = 0; I != Args.size(); ++I) {
181 if (Args[I]->isTypeDependent())
182 ExprBits.TypeDependent = true;
183 if (Args[I]->isValueDependent())
184 ExprBits.ValueDependent = true;
185 if (Args[I]->isInstantiationDependent())
186 ExprBits.InstantiationDependent = true;
187 if (Args[I]->containsUnexpandedParameterPack())
188 ExprBits.ContainsUnexpandedParameterPack = true;
193 SelLocsKind = SelLocsK;
195 if (SelLocsK == SelLoc_NonStandard)
196 std::copy(SelLocs.begin(), SelLocs.end(), getStoredSelLocs());
201 ObjCMessageExpr::Create(const ASTContext &Context, QualType T, ExprValueKind VK,
202 SourceLocation LBracLoc, SourceLocation SuperLoc,
203 bool IsInstanceSuper, QualType SuperType, Selector Sel,
204 ArrayRef<SourceLocation> SelLocs,
205 ObjCMethodDecl *Method, ArrayRef<Expr *> Args,
206 SourceLocation RBracLoc, bool isImplicit) {
207 assert((!SelLocs.empty() || isImplicit) &&
208 "No selector locs for non-implicit message");
209 ObjCMessageExpr *Mem;
210 SelectorLocationsKind SelLocsK = SelectorLocationsKind();
212 Mem = alloc(Context, Args.size(), 0);
214 Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK);
215 return new (Mem) ObjCMessageExpr(T, VK, LBracLoc, SuperLoc, IsInstanceSuper,
216 SuperType, Sel, SelLocs, SelLocsK, Method,
217 Args, RBracLoc, isImplicit);
221 ObjCMessageExpr::Create(const ASTContext &Context, QualType T, ExprValueKind VK,
222 SourceLocation LBracLoc, TypeSourceInfo *Receiver,
223 Selector Sel, ArrayRef<SourceLocation> SelLocs,
224 ObjCMethodDecl *Method, ArrayRef<Expr *> Args,
225 SourceLocation RBracLoc, bool isImplicit) {
226 assert((!SelLocs.empty() || isImplicit) &&
227 "No selector locs for non-implicit message");
228 ObjCMessageExpr *Mem;
229 SelectorLocationsKind SelLocsK = SelectorLocationsKind();
231 Mem = alloc(Context, Args.size(), 0);
233 Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK);
235 ObjCMessageExpr(T, VK, LBracLoc, Receiver, Sel, SelLocs, SelLocsK, Method,
236 Args, RBracLoc, isImplicit);
240 ObjCMessageExpr::Create(const ASTContext &Context, QualType T, ExprValueKind VK,
241 SourceLocation LBracLoc, Expr *Receiver, Selector Sel,
242 ArrayRef<SourceLocation> SelLocs,
243 ObjCMethodDecl *Method, ArrayRef<Expr *> Args,
244 SourceLocation RBracLoc, bool isImplicit) {
245 assert((!SelLocs.empty() || isImplicit) &&
246 "No selector locs for non-implicit message");
247 ObjCMessageExpr *Mem;
248 SelectorLocationsKind SelLocsK = SelectorLocationsKind();
250 Mem = alloc(Context, Args.size(), 0);
252 Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK);
254 ObjCMessageExpr(T, VK, LBracLoc, Receiver, Sel, SelLocs, SelLocsK, Method,
255 Args, RBracLoc, isImplicit);
258 ObjCMessageExpr *ObjCMessageExpr::CreateEmpty(const ASTContext &Context,
260 unsigned NumStoredSelLocs) {
261 ObjCMessageExpr *Mem = alloc(Context, NumArgs, NumStoredSelLocs);
262 return new (Mem) ObjCMessageExpr(EmptyShell(), NumArgs);
265 ObjCMessageExpr *ObjCMessageExpr::alloc(const ASTContext &C,
266 ArrayRef<Expr *> Args,
267 SourceLocation RBraceLoc,
268 ArrayRef<SourceLocation> SelLocs,
270 SelectorLocationsKind &SelLocsK) {
271 SelLocsK = hasStandardSelectorLocs(Sel, SelLocs, Args, RBraceLoc);
272 unsigned NumStoredSelLocs =
273 (SelLocsK == SelLoc_NonStandard) ? SelLocs.size() : 0;
274 return alloc(C, Args.size(), NumStoredSelLocs);
277 ObjCMessageExpr *ObjCMessageExpr::alloc(const ASTContext &C, unsigned NumArgs,
278 unsigned NumStoredSelLocs) {
279 return (ObjCMessageExpr *)C.Allocate(
280 totalSizeToAlloc<void *, SourceLocation>(NumArgs + 1, NumStoredSelLocs),
281 alignof(ObjCMessageExpr));
284 void ObjCMessageExpr::getSelectorLocs(
285 SmallVectorImpl<SourceLocation> &SelLocs) const {
286 for (unsigned i = 0, e = getNumSelectorLocs(); i != e; ++i)
287 SelLocs.push_back(getSelectorLoc(i));
290 SourceRange ObjCMessageExpr::getReceiverRange() const {
291 switch (getReceiverKind()) {
293 return getInstanceReceiver()->getSourceRange();
296 return getClassReceiverTypeInfo()->getTypeLoc().getSourceRange();
300 return getSuperLoc();
303 llvm_unreachable("Invalid ReceiverKind!");
306 Selector ObjCMessageExpr::getSelector() const {
308 return reinterpret_cast<const ObjCMethodDecl *>(SelectorOrMethod)
310 return Selector(SelectorOrMethod);
313 QualType ObjCMessageExpr::getReceiverType() const {
314 switch (getReceiverKind()) {
316 return getInstanceReceiver()->getType();
318 return getClassReceiver();
321 return getSuperType();
324 llvm_unreachable("unexpected receiver kind");
327 ObjCInterfaceDecl *ObjCMessageExpr::getReceiverInterface() const {
328 QualType T = getReceiverType();
330 if (const ObjCObjectPointerType *Ptr = T->getAs<ObjCObjectPointerType>())
331 return Ptr->getInterfaceDecl();
333 if (const ObjCObjectType *Ty = T->getAs<ObjCObjectType>())
334 return Ty->getInterface();
339 Stmt::child_range ObjCMessageExpr::children() {
341 if (getReceiverKind() == Instance)
342 begin = reinterpret_cast<Stmt **>(getTrailingObjects<void *>());
344 begin = reinterpret_cast<Stmt **>(getArgs());
345 return child_range(begin,
346 reinterpret_cast<Stmt **>(getArgs() + getNumArgs()));
349 StringRef ObjCBridgedCastExpr::getBridgeKindName() const {
350 switch (getBridgeKind()) {
353 case OBC_BridgeTransfer:
354 return "__bridge_transfer";
355 case OBC_BridgeRetained:
356 return "__bridge_retained";
359 llvm_unreachable("Invalid BridgeKind!");