clang  6.0.0svn
ExprObjC.cpp
Go to the documentation of this file.
1 //===--- ExprObjC.cpp - (ObjC) Expression AST Node Implementation ---------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements the subclesses of Expr class declared in ExprObjC.h
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "clang/AST/ExprObjC.h"
15 
16 #include "clang/AST/ASTContext.h"
17 
18 using namespace clang;
19 
20 ObjCArrayLiteral::ObjCArrayLiteral(ArrayRef<Expr *> Elements, QualType T,
21  ObjCMethodDecl *Method, SourceRange SR)
22  : Expr(ObjCArrayLiteralClass, T, VK_RValue, OK_Ordinary, false, false,
23  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;
33 
34  SaveElements[I] = Elements[I];
35  }
36 }
37 
39  ArrayRef<Expr *> Elements,
40  QualType T, ObjCMethodDecl *Method,
41  SourceRange SR) {
42  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(Elements.size()));
43  return new (Mem) ObjCArrayLiteral(Elements, T, Method, SR);
44 }
45 
47  unsigned NumElements) {
48 
49  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(NumElements));
50  return new (Mem) ObjCArrayLiteral(EmptyShell(), NumElements);
51 }
52 
53 ObjCDictionaryLiteral::ObjCDictionaryLiteral(ArrayRef<ObjCDictionaryElement> VK,
54  bool HasPackExpansions, QualType T,
55  ObjCMethodDecl *method,
56  SourceRange SR)
57  : Expr(ObjCDictionaryLiteralClass, T, VK_RValue, OK_Ordinary, false, false,
58  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;
75 
76  KeyValues[I].Key = VK[I].Key;
77  KeyValues[I].Value = VK[I].Value;
78  if (Expansions) {
79  Expansions[I].EllipsisLoc = VK[I].EllipsisLoc;
80  if (VK[I].NumExpansions)
81  Expansions[I].NumExpansionsPlusOne = *VK[I].NumExpansions + 1;
82  else
83  Expansions[I].NumExpansionsPlusOne = 0;
84  }
85  }
86 }
87 
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);
96 }
97 
99 ObjCDictionaryLiteral::CreateEmpty(const ASTContext &C, unsigned NumElements,
100  bool HasPackExpansions) {
101  void *Mem = C.Allocate(totalSizeToAlloc<KeyValuePair, ExpansionData>(
102  NumElements, HasPackExpansions ? NumElements : 0));
103  return new (Mem)
104  ObjCDictionaryLiteral(EmptyShell(), NumElements, HasPackExpansions);
105 }
106 
108  if (isClassReceiver())
109  return ctx.getObjCInterfaceType(getClassReceiver());
110 
111  if (isSuperReceiver())
112  return getSuperReceiverType();
113 
114  return getBase()->getType();
115 }
116 
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),
129  SelectorOrMethod(
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),
134  RBracLoc(RBracLoc) {
135  initArgsAndSelLocs(Args, SelLocs, SelLocsK);
136  setReceiverPointer(SuperType.getAsOpaquePtr());
137 }
138 
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(),
149  SelectorOrMethod(
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);
155 }
156 
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()),
167  SelectorOrMethod(
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);
173 }
174 
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;
188  ExprBits.ContainsUnexpandedParameterPack = true;
189 
190  MyArgs[I] = Args[I];
191  }
192 
193  SelLocsKind = SelLocsK;
194  if (!isImplicit()) {
195  if (SelLocsK == SelLoc_NonStandard)
196  std::copy(SelLocs.begin(), SelLocs.end(), getStoredSelLocs());
197  }
198 }
199 
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;
211  if (isImplicit)
212  Mem = alloc(Context, Args.size(), 0);
213  else
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);
218 }
219 
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;
230  if (isImplicit)
231  Mem = alloc(Context, Args.size(), 0);
232  else
233  Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK);
234  return new (Mem)
235  ObjCMessageExpr(T, VK, LBracLoc, Receiver, Sel, SelLocs, SelLocsK, Method,
236  Args, RBracLoc, isImplicit);
237 }
238 
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;
249  if (isImplicit)
250  Mem = alloc(Context, Args.size(), 0);
251  else
252  Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK);
253  return new (Mem)
254  ObjCMessageExpr(T, VK, LBracLoc, Receiver, Sel, SelLocs, SelLocsK, Method,
255  Args, RBracLoc, isImplicit);
256 }
257 
259  unsigned NumArgs,
260  unsigned NumStoredSelLocs) {
261  ObjCMessageExpr *Mem = alloc(Context, NumArgs, NumStoredSelLocs);
262  return new (Mem) ObjCMessageExpr(EmptyShell(), NumArgs);
263 }
264 
265 ObjCMessageExpr *ObjCMessageExpr::alloc(const ASTContext &C,
266  ArrayRef<Expr *> Args,
267  SourceLocation RBraceLoc,
268  ArrayRef<SourceLocation> SelLocs,
269  Selector Sel,
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);
275 }
276 
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));
282 }
283 
285  SmallVectorImpl<SourceLocation> &SelLocs) const {
286  for (unsigned i = 0, e = getNumSelectorLocs(); i != e; ++i)
287  SelLocs.push_back(getSelectorLoc(i));
288 }
289 
291  switch (getReceiverKind()) {
292  case Instance:
293  return getInstanceReceiver()->getSourceRange();
294 
295  case Class:
296  return getClassReceiverTypeInfo()->getTypeLoc().getSourceRange();
297 
298  case SuperInstance:
299  case SuperClass:
300  return getSuperLoc();
301  }
302 
303  llvm_unreachable("Invalid ReceiverKind!");
304 }
305 
307  if (HasMethod)
308  return reinterpret_cast<const ObjCMethodDecl *>(SelectorOrMethod)
309  ->getSelector();
310  return Selector(SelectorOrMethod);
311 }
312 
314  switch (getReceiverKind()) {
315  case Instance:
316  return getInstanceReceiver()->getType();
317  case Class:
318  return getClassReceiver();
319  case SuperInstance:
320  case SuperClass:
321  return getSuperType();
322  }
323 
324  llvm_unreachable("unexpected receiver kind");
325 }
326 
328  QualType T = getReceiverType();
329 
330  if (const ObjCObjectPointerType *Ptr = T->getAs<ObjCObjectPointerType>())
331  return Ptr->getInterfaceDecl();
332 
333  if (const ObjCObjectType *Ty = T->getAs<ObjCObjectType>())
334  return Ty->getInterface();
335 
336  return nullptr;
337 }
338 
340  Stmt **begin;
341  if (getReceiverKind() == Instance)
342  begin = reinterpret_cast<Stmt **>(getTrailingObjects<void *>());
343  else
344  begin = reinterpret_cast<Stmt **>(getArgs());
345  return child_range(begin,
346  reinterpret_cast<Stmt **>(getArgs() + getNumArgs()));
347 }
348 
350  switch (getBridgeKind()) {
351  case OBC_Bridge:
352  return "__bridge";
353  case OBC_BridgeTransfer:
354  return "__bridge_transfer";
355  case OBC_BridgeRetained:
356  return "__bridge_retained";
357  }
358 
359  llvm_unreachable("Invalid BridgeKind!");
360 }
Defines the clang::ASTContext interface.
static ObjCArrayLiteral * Create(const ASTContext &C, ArrayRef< Expr *> Elements, QualType T, ObjCMethodDecl *Method, SourceRange SR)
Definition: ExprObjC.cpp:38
Smart pointer class that efficiently represents Objective-C method names.
if(T->getSizeExpr()) TRY_TO(TraverseStmt(T -> getSizeExpr()))
A (possibly-)qualified type.
Definition: Type.h:614
void * getAsOpaquePtr() const
Selector getSelector() const
Definition: ExprObjC.cpp:306
Expr(StmtClass SC, QualType T, ExprValueKind VK, ExprObjectKind OK, bool TD, bool VD, bool ID, bool ContainsUnexpandedParameterPack)
Definition: Expr.h:110
Stmt - This represents one statement.
Definition: Stmt.h:60
Bridging via __bridge, which does nothing but reinterpret the bits.
ObjCInterfaceDecl * getReceiverInterface() const
Retrieve the Objective-C interface to which this message is being directed, if known.
Definition: ExprObjC.cpp:327
A container of type source information.
Definition: Decl.h:62
static ObjCDictionaryLiteral * CreateEmpty(const ASTContext &C, unsigned NumElements, bool HasPackExpansions)
Definition: ExprObjC.cpp:99
const T * getAs() const
Member-template getAs<specific type>&#39;.
Definition: Type.h:6099
unsigned getNumArgs() const
Determine the number of arguments to this type trait.
Definition: ExprCXX.h:2301
ObjCMethodDecl - Represents an instance or class method declaration.
Definition: DeclObjC.h:113
Represents a class type in Objective C.
Definition: Type.h:5023
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:128
static ObjCMessageExpr * CreateEmpty(const ASTContext &Context, unsigned NumArgs, unsigned NumStoredSelLocs)
Create an empty Objective-C message expression, to be filled in by subsequent calls.
Definition: ExprObjC.cpp:258
static 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)
Create a message send to super.
Definition: ExprObjC.cpp:201
ObjCArrayLiteral - used for objective-c array containers; as in: @["Hello", NSApp, [NSNumber numberWithInt:42]];.
Definition: ExprObjC.h:144
An r-value expression (a pr-value in the C++11 taxonomy) produces a temporary value.
Definition: Specifiers.h:107
SelectorLocationsKind
Whether all locations of the selector identifiers are in a "standard" position.
bool containsUnexpandedParameterPack() const
Whether this type is or contains an unexpanded parameter pack, used to support C++0x variadic templat...
Definition: Type.h:1572
child_range children()
Definition: ExprObjC.cpp:339
bool isTypeDependent() const
isTypeDependent - Determines whether this expression is type-dependent (C++ [temp.dep.expr]), which means that its type could change from one template instantiation to the next.
Definition: Expr.h:167
void * getAsOpaquePtr() const
Definition: Type.h:662
An ordinary object is located at an address in memory.
Definition: Specifiers.h:123
Represents an ObjC class declaration.
Definition: DeclObjC.h:1108
Bridging via __bridge_transfer, which transfers ownership of an Objective-C pointer into ARC...
ArrayRef< TypeSourceInfo * > getArgs() const
Retrieve the argument types.
Definition: ExprCXX.h:2310
Expr - This represents one expression.
Definition: Expr.h:106
ExprValueKind
The categorization of expression values, currently following the C++11 scheme.
Definition: Specifiers.h:104
const FunctionProtoType * T
ObjCDictionaryLiteral - AST node to represent objective-c dictionary literals; as in:"name" : NSUserN...
Definition: ExprObjC.h:257
ExprBitfields ExprBits
Definition: Stmt.h:268
static ObjCDictionaryLiteral * Create(const ASTContext &C, ArrayRef< ObjCDictionaryElement > VK, bool HasPackExpansions, QualType T, ObjCMethodDecl *method, SourceRange SR)
Definition: ExprObjC.cpp:89
An expression that sends a message to the given Objective-C object or class.
Definition: ExprObjC.h:860
QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl, ObjCInterfaceDecl *PrevDecl=nullptr) const
getObjCInterfaceType - Return the unique reference to the type for the specified ObjC interface decl...
StringRef getBridgeKindName() const
Retrieve the kind of bridge being performed as a string.
Definition: ExprObjC.cpp:349
#define false
Definition: stdbool.h:33
Kind
bool isInstantiationDependent() const
Whether this expression is instantiation-dependent, meaning that it depends in some way on a template...
Definition: Expr.h:191
Encodes a location in the source.
llvm::iterator_range< child_iterator > child_range
Definition: Stmt.h:422
bool isValueDependent() const
isValueDependent - Determines whether this expression is value-dependent (C++ [temp.dep.constexpr]).
Definition: Expr.h:149
QualType getReceiverType() const
Retrieve the receiver type to which this message is being directed.
Definition: ExprObjC.cpp:313
bool isInstantiationDependentType() const
Determine whether this type is an instantiation-dependent type, meaning that the type involves a temp...
Definition: Type.h:1801
A placeholder type used to construct an empty shell of a type, that will be filled in later (e...
Definition: Stmt.h:308
void * Allocate(size_t Size, unsigned Align=8) const
Definition: ASTContext.h:625
Dataflow Directional Tag Classes.
Bridging via __bridge_retain, which makes an ARC object available as a +1 C pointer.
SourceRange getReceiverRange() const
Source range of the receiver.
Definition: ExprObjC.cpp:290
Represents a pointer to an Objective C object.
Definition: Type.h:5274
QualType getReceiverType(const ASTContext &ctx) const
Determine the type of the base, regardless of the kind of receiver.
Definition: ExprObjC.cpp:107
bool containsUnexpandedParameterPack() const
Whether this expression contains an unexpanded parameter pack (for C++11 variadic templates)...
Definition: Expr.h:214
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
Definition: Type.h:1795
static ObjCArrayLiteral * CreateEmpty(const ASTContext &C, unsigned NumElements)
Definition: ExprObjC.cpp:46
A trivial tuple used to represent a source range.
void getSelectorLocs(SmallVectorImpl< SourceLocation > &SelLocs) const
Definition: ExprObjC.cpp:284
SelectorLocationsKind hasStandardSelectorLocs(Selector Sel, ArrayRef< SourceLocation > SelLocs, ArrayRef< Expr *> Args, SourceLocation EndLoc)
Returns true if all SelLocs are in a "standard" location.