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"
15 #include "clang/AST/ASTContext.h"
16 #include "clang/AST/SelectorLocationsKind.h"
17 #include "clang/AST/Type.h"
18 #include "clang/AST/TypeLoc.h"
19 #include "llvm/ADT/SmallVector.h"
20 #include "llvm/Support/ErrorHandling.h"
25 using namespace clang;
27 ObjCArrayLiteral::ObjCArrayLiteral(ArrayRef<Expr *> Elements, QualType T,
28 ObjCMethodDecl *Method, SourceRange SR)
29 : Expr(ObjCArrayLiteralClass, T, VK_RValue, OK_Ordinary, false, false,
31 NumElements(Elements.size()), Range(SR), ArrayWithObjectsMethod(Method) {
32 Expr **SaveElements = getElements();
33 for (unsigned I = 0, N = Elements.size(); I != N; ++I) {
34 if (Elements[I]->isTypeDependent() || Elements[I]->isValueDependent())
35 ExprBits.ValueDependent = true;
36 if (Elements[I]->isInstantiationDependent())
37 ExprBits.InstantiationDependent = true;
38 if (Elements[I]->containsUnexpandedParameterPack())
39 ExprBits.ContainsUnexpandedParameterPack = true;
41 SaveElements[I] = Elements[I];
45 ObjCArrayLiteral *ObjCArrayLiteral::Create(const ASTContext &C,
46 ArrayRef<Expr *> Elements,
47 QualType T, ObjCMethodDecl *Method,
49 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(Elements.size()));
50 return new (Mem) ObjCArrayLiteral(Elements, T, Method, SR);
53 ObjCArrayLiteral *ObjCArrayLiteral::CreateEmpty(const ASTContext &C,
54 unsigned NumElements) {
55 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(NumElements));
56 return new (Mem) ObjCArrayLiteral(EmptyShell(), NumElements);
59 ObjCDictionaryLiteral::ObjCDictionaryLiteral(ArrayRef<ObjCDictionaryElement> VK,
60 bool HasPackExpansions, QualType T,
61 ObjCMethodDecl *method,
63 : Expr(ObjCDictionaryLiteralClass, T, VK_RValue, OK_Ordinary, false, false,
65 NumElements(VK.size()), HasPackExpansions(HasPackExpansions), Range(SR),
66 DictWithObjectsMethod(method) {
67 KeyValuePair *KeyValues = getTrailingObjects<KeyValuePair>();
68 ExpansionData *Expansions =
69 HasPackExpansions ? getTrailingObjects<ExpansionData>() : nullptr;
70 for (unsigned I = 0; I < NumElements; I++) {
71 if (VK[I].Key->isTypeDependent() || VK[I].Key->isValueDependent() ||
72 VK[I].Value->isTypeDependent() || VK[I].Value->isValueDependent())
73 ExprBits.ValueDependent = true;
74 if (VK[I].Key->isInstantiationDependent() ||
75 VK[I].Value->isInstantiationDependent())
76 ExprBits.InstantiationDependent = true;
77 if (VK[I].EllipsisLoc.isInvalid() &&
78 (VK[I].Key->containsUnexpandedParameterPack() ||
79 VK[I].Value->containsUnexpandedParameterPack()))
80 ExprBits.ContainsUnexpandedParameterPack = true;
82 KeyValues[I].Key = VK[I].Key;
83 KeyValues[I].Value = VK[I].Value;
85 Expansions[I].EllipsisLoc = VK[I].EllipsisLoc;
86 if (VK[I].NumExpansions)
87 Expansions[I].NumExpansionsPlusOne = *VK[I].NumExpansions + 1;
89 Expansions[I].NumExpansionsPlusOne = 0;
94 ObjCDictionaryLiteral *
95 ObjCDictionaryLiteral::Create(const ASTContext &C,
96 ArrayRef<ObjCDictionaryElement> VK,
97 bool HasPackExpansions, QualType T,
98 ObjCMethodDecl *method, SourceRange SR) {
99 void *Mem = C.Allocate(totalSizeToAlloc<KeyValuePair, ExpansionData>(
100 VK.size(), HasPackExpansions ? VK.size() : 0));
101 return new (Mem) ObjCDictionaryLiteral(VK, HasPackExpansions, T, method, SR);
104 ObjCDictionaryLiteral *
105 ObjCDictionaryLiteral::CreateEmpty(const ASTContext &C, unsigned NumElements,
106 bool HasPackExpansions) {
107 void *Mem = C.Allocate(totalSizeToAlloc<KeyValuePair, ExpansionData>(
108 NumElements, HasPackExpansions ? NumElements : 0));
110 ObjCDictionaryLiteral(EmptyShell(), NumElements, HasPackExpansions);
113 QualType ObjCPropertyRefExpr::getReceiverType(const ASTContext &ctx) const {
114 if (isClassReceiver())
115 return ctx.getObjCInterfaceType(getClassReceiver());
117 if (isSuperReceiver())
118 return getSuperReceiverType();
120 return getBase()->getType();
123 ObjCMessageExpr::ObjCMessageExpr(QualType T, ExprValueKind VK,
124 SourceLocation LBracLoc,
125 SourceLocation SuperLoc, bool IsInstanceSuper,
126 QualType SuperType, Selector Sel,
127 ArrayRef<SourceLocation> SelLocs,
128 SelectorLocationsKind SelLocsK,
129 ObjCMethodDecl *Method, ArrayRef<Expr *> Args,
130 SourceLocation RBracLoc, bool isImplicit)
131 : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary,
132 /*TypeDependent=*/false, /*ValueDependent=*/false,
133 /*InstantiationDependent=*/false,
134 /*ContainsUnexpandedParameterPack=*/false),
136 reinterpret_cast<uintptr_t>(Method ? Method : Sel.getAsOpaquePtr())),
137 Kind(IsInstanceSuper ? SuperInstance : SuperClass),
138 HasMethod(Method != nullptr), IsDelegateInitCall(false),
139 IsImplicit(isImplicit), SuperLoc(SuperLoc), LBracLoc(LBracLoc),
141 initArgsAndSelLocs(Args, SelLocs, SelLocsK);
142 setReceiverPointer(SuperType.getAsOpaquePtr());
145 ObjCMessageExpr::ObjCMessageExpr(QualType T, ExprValueKind VK,
146 SourceLocation LBracLoc,
147 TypeSourceInfo *Receiver, Selector Sel,
148 ArrayRef<SourceLocation> SelLocs,
149 SelectorLocationsKind SelLocsK,
150 ObjCMethodDecl *Method, ArrayRef<Expr *> Args,
151 SourceLocation RBracLoc, bool isImplicit)
152 : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary, T->isDependentType(),
153 T->isDependentType(), T->isInstantiationDependentType(),
154 T->containsUnexpandedParameterPack()),
156 reinterpret_cast<uintptr_t>(Method ? Method : Sel.getAsOpaquePtr())),
157 Kind(Class), HasMethod(Method != nullptr), IsDelegateInitCall(false),
158 IsImplicit(isImplicit), LBracLoc(LBracLoc), RBracLoc(RBracLoc) {
159 initArgsAndSelLocs(Args, SelLocs, SelLocsK);
160 setReceiverPointer(Receiver);
163 ObjCMessageExpr::ObjCMessageExpr(QualType T, ExprValueKind VK,
164 SourceLocation LBracLoc, Expr *Receiver,
165 Selector Sel, ArrayRef<SourceLocation> SelLocs,
166 SelectorLocationsKind SelLocsK,
167 ObjCMethodDecl *Method, ArrayRef<Expr *> Args,
168 SourceLocation RBracLoc, bool isImplicit)
169 : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary,
170 Receiver->isTypeDependent(), Receiver->isTypeDependent(),
171 Receiver->isInstantiationDependent(),
172 Receiver->containsUnexpandedParameterPack()),
174 reinterpret_cast<uintptr_t>(Method ? Method : Sel.getAsOpaquePtr())),
175 Kind(Instance), HasMethod(Method != nullptr), IsDelegateInitCall(false),
176 IsImplicit(isImplicit), LBracLoc(LBracLoc), RBracLoc(RBracLoc) {
177 initArgsAndSelLocs(Args, SelLocs, SelLocsK);
178 setReceiverPointer(Receiver);
181 void ObjCMessageExpr::initArgsAndSelLocs(ArrayRef<Expr *> Args,
182 ArrayRef<SourceLocation> SelLocs,
183 SelectorLocationsKind SelLocsK) {
184 setNumArgs(Args.size());
185 Expr **MyArgs = getArgs();
186 for (unsigned I = 0; I != Args.size(); ++I) {
187 if (Args[I]->isTypeDependent())
188 ExprBits.TypeDependent = true;
189 if (Args[I]->isValueDependent())
190 ExprBits.ValueDependent = true;
191 if (Args[I]->isInstantiationDependent())
192 ExprBits.InstantiationDependent = true;
193 if (Args[I]->containsUnexpandedParameterPack())
194 ExprBits.ContainsUnexpandedParameterPack = true;
199 SelLocsKind = SelLocsK;
201 if (SelLocsK == SelLoc_NonStandard)
202 std::copy(SelLocs.begin(), SelLocs.end(), getStoredSelLocs());
207 ObjCMessageExpr::Create(const ASTContext &Context, QualType T, ExprValueKind VK,
208 SourceLocation LBracLoc, SourceLocation SuperLoc,
209 bool IsInstanceSuper, QualType SuperType, Selector Sel,
210 ArrayRef<SourceLocation> SelLocs,
211 ObjCMethodDecl *Method, ArrayRef<Expr *> Args,
212 SourceLocation RBracLoc, bool isImplicit) {
213 assert((!SelLocs.empty() || isImplicit) &&
214 "No selector locs for non-implicit message");
215 ObjCMessageExpr *Mem;
216 SelectorLocationsKind SelLocsK = SelectorLocationsKind();
218 Mem = alloc(Context, Args.size(), 0);
220 Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK);
221 return new (Mem) ObjCMessageExpr(T, VK, LBracLoc, SuperLoc, IsInstanceSuper,
222 SuperType, Sel, SelLocs, SelLocsK, Method,
223 Args, RBracLoc, isImplicit);
227 ObjCMessageExpr::Create(const ASTContext &Context, QualType T, ExprValueKind VK,
228 SourceLocation LBracLoc, TypeSourceInfo *Receiver,
229 Selector Sel, ArrayRef<SourceLocation> SelLocs,
230 ObjCMethodDecl *Method, ArrayRef<Expr *> Args,
231 SourceLocation RBracLoc, bool isImplicit) {
232 assert((!SelLocs.empty() || isImplicit) &&
233 "No selector locs for non-implicit message");
234 ObjCMessageExpr *Mem;
235 SelectorLocationsKind SelLocsK = SelectorLocationsKind();
237 Mem = alloc(Context, Args.size(), 0);
239 Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK);
241 ObjCMessageExpr(T, VK, LBracLoc, Receiver, Sel, SelLocs, SelLocsK, Method,
242 Args, RBracLoc, isImplicit);
246 ObjCMessageExpr::Create(const ASTContext &Context, QualType T, ExprValueKind VK,
247 SourceLocation LBracLoc, Expr *Receiver, Selector Sel,
248 ArrayRef<SourceLocation> SelLocs,
249 ObjCMethodDecl *Method, ArrayRef<Expr *> Args,
250 SourceLocation RBracLoc, bool isImplicit) {
251 assert((!SelLocs.empty() || isImplicit) &&
252 "No selector locs for non-implicit message");
253 ObjCMessageExpr *Mem;
254 SelectorLocationsKind SelLocsK = SelectorLocationsKind();
256 Mem = alloc(Context, Args.size(), 0);
258 Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK);
260 ObjCMessageExpr(T, VK, LBracLoc, Receiver, Sel, SelLocs, SelLocsK, Method,
261 Args, RBracLoc, isImplicit);
264 ObjCMessageExpr *ObjCMessageExpr::CreateEmpty(const ASTContext &Context,
266 unsigned NumStoredSelLocs) {
267 ObjCMessageExpr *Mem = alloc(Context, NumArgs, NumStoredSelLocs);
268 return new (Mem) ObjCMessageExpr(EmptyShell(), NumArgs);
271 ObjCMessageExpr *ObjCMessageExpr::alloc(const ASTContext &C,
272 ArrayRef<Expr *> Args,
273 SourceLocation RBraceLoc,
274 ArrayRef<SourceLocation> SelLocs,
276 SelectorLocationsKind &SelLocsK) {
277 SelLocsK = hasStandardSelectorLocs(Sel, SelLocs, Args, RBraceLoc);
278 unsigned NumStoredSelLocs =
279 (SelLocsK == SelLoc_NonStandard) ? SelLocs.size() : 0;
280 return alloc(C, Args.size(), NumStoredSelLocs);
283 ObjCMessageExpr *ObjCMessageExpr::alloc(const ASTContext &C, unsigned NumArgs,
284 unsigned NumStoredSelLocs) {
285 return (ObjCMessageExpr *)C.Allocate(
286 totalSizeToAlloc<void *, SourceLocation>(NumArgs + 1, NumStoredSelLocs),
287 alignof(ObjCMessageExpr));
290 void ObjCMessageExpr::getSelectorLocs(
291 SmallVectorImpl<SourceLocation> &SelLocs) const {
292 for (unsigned i = 0, e = getNumSelectorLocs(); i != e; ++i)
293 SelLocs.push_back(getSelectorLoc(i));
296 SourceRange ObjCMessageExpr::getReceiverRange() const {
297 switch (getReceiverKind()) {
299 return getInstanceReceiver()->getSourceRange();
302 return getClassReceiverTypeInfo()->getTypeLoc().getSourceRange();
306 return getSuperLoc();
309 llvm_unreachable("Invalid ReceiverKind!");
312 Selector ObjCMessageExpr::getSelector() const {
314 return reinterpret_cast<const ObjCMethodDecl *>(SelectorOrMethod)
316 return Selector(SelectorOrMethod);
319 QualType ObjCMessageExpr::getReceiverType() const {
320 switch (getReceiverKind()) {
322 return getInstanceReceiver()->getType();
324 return getClassReceiver();
327 return getSuperType();
330 llvm_unreachable("unexpected receiver kind");
333 ObjCInterfaceDecl *ObjCMessageExpr::getReceiverInterface() const {
334 QualType T = getReceiverType();
336 if (const ObjCObjectPointerType *Ptr = T->getAs<ObjCObjectPointerType>())
337 return Ptr->getInterfaceDecl();
339 if (const ObjCObjectType *Ty = T->getAs<ObjCObjectType>())
340 return Ty->getInterface();
345 Stmt::child_range ObjCMessageExpr::children() {
347 if (getReceiverKind() == Instance)
348 begin = reinterpret_cast<Stmt **>(getTrailingObjects<void *>());
350 begin = reinterpret_cast<Stmt **>(getArgs());
351 return child_range(begin,
352 reinterpret_cast<Stmt **>(getArgs() + getNumArgs()));
355 StringRef ObjCBridgedCastExpr::getBridgeKindName() const {
356 switch (getBridgeKind()) {
359 case OBC_BridgeTransfer:
360 return "__bridge_transfer";
361 case OBC_BridgeRetained:
362 return "__bridge_retained";
365 llvm_unreachable("Invalid BridgeKind!");