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 #include "clang/AST/ASTContext.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"
21 #include <algorithm>
22 #include <cassert>
23 #include <cstdint>
24 
25 using namespace clang;
26 
27 ObjCArrayLiteral::ObjCArrayLiteral(ArrayRef<Expr *> Elements, QualType T,
28  ObjCMethodDecl *Method, SourceRange SR)
29  : Expr(ObjCArrayLiteralClass, T, VK_RValue, OK_Ordinary, false, false,
30  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;
40 
41  SaveElements[I] = Elements[I];
42  }
43 }
44 
46  ArrayRef<Expr *> Elements,
47  QualType T, ObjCMethodDecl *Method,
48  SourceRange SR) {
49  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(Elements.size()));
50  return new (Mem) ObjCArrayLiteral(Elements, T, Method, SR);
51 }
52 
54  unsigned NumElements) {
55  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(NumElements));
56  return new (Mem) ObjCArrayLiteral(EmptyShell(), NumElements);
57 }
58 
59 ObjCDictionaryLiteral::ObjCDictionaryLiteral(ArrayRef<ObjCDictionaryElement> VK,
60  bool HasPackExpansions, QualType T,
61  ObjCMethodDecl *method,
62  SourceRange SR)
63  : Expr(ObjCDictionaryLiteralClass, T, VK_RValue, OK_Ordinary, false, false,
64  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;
81 
82  KeyValues[I].Key = VK[I].Key;
83  KeyValues[I].Value = VK[I].Value;
84  if (Expansions) {
85  Expansions[I].EllipsisLoc = VK[I].EllipsisLoc;
86  if (VK[I].NumExpansions)
87  Expansions[I].NumExpansionsPlusOne = *VK[I].NumExpansions + 1;
88  else
89  Expansions[I].NumExpansionsPlusOne = 0;
90  }
91  }
92 }
93 
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);
102 }
103 
105 ObjCDictionaryLiteral::CreateEmpty(const ASTContext &C, unsigned NumElements,
106  bool HasPackExpansions) {
107  void *Mem = C.Allocate(totalSizeToAlloc<KeyValuePair, ExpansionData>(
108  NumElements, HasPackExpansions ? NumElements : 0));
109  return new (Mem)
110  ObjCDictionaryLiteral(EmptyShell(), NumElements, HasPackExpansions);
111 }
112 
114  if (isClassReceiver())
115  return ctx.getObjCInterfaceType(getClassReceiver());
116 
117  if (isSuperReceiver())
118  return getSuperReceiverType();
119 
120  return getBase()->getType();
121 }
122 
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),
135  SelectorOrMethod(
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),
140  RBracLoc(RBracLoc) {
141  initArgsAndSelLocs(Args, SelLocs, SelLocsK);
142  setReceiverPointer(SuperType.getAsOpaquePtr());
143 }
144 
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(),
155  SelectorOrMethod(
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);
161 }
162 
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()),
173  SelectorOrMethod(
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);
179 }
180 
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;
194  ExprBits.ContainsUnexpandedParameterPack = true;
195 
196  MyArgs[I] = Args[I];
197  }
198 
199  SelLocsKind = SelLocsK;
200  if (!isImplicit()) {
201  if (SelLocsK == SelLoc_NonStandard)
202  std::copy(SelLocs.begin(), SelLocs.end(), getStoredSelLocs());
203  }
204 }
205 
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;
217  if (isImplicit)
218  Mem = alloc(Context, Args.size(), 0);
219  else
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);
224 }
225 
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;
236  if (isImplicit)
237  Mem = alloc(Context, Args.size(), 0);
238  else
239  Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK);
240  return new (Mem)
241  ObjCMessageExpr(T, VK, LBracLoc, Receiver, Sel, SelLocs, SelLocsK, Method,
242  Args, RBracLoc, isImplicit);
243 }
244 
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;
255  if (isImplicit)
256  Mem = alloc(Context, Args.size(), 0);
257  else
258  Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK);
259  return new (Mem)
260  ObjCMessageExpr(T, VK, LBracLoc, Receiver, Sel, SelLocs, SelLocsK, Method,
261  Args, RBracLoc, isImplicit);
262 }
263 
265  unsigned NumArgs,
266  unsigned NumStoredSelLocs) {
267  ObjCMessageExpr *Mem = alloc(Context, NumArgs, NumStoredSelLocs);
268  return new (Mem) ObjCMessageExpr(EmptyShell(), NumArgs);
269 }
270 
271 ObjCMessageExpr *ObjCMessageExpr::alloc(const ASTContext &C,
272  ArrayRef<Expr *> Args,
273  SourceLocation RBraceLoc,
274  ArrayRef<SourceLocation> SelLocs,
275  Selector Sel,
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);
281 }
282 
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));
288 }
289 
291  SmallVectorImpl<SourceLocation> &SelLocs) const {
292  for (unsigned i = 0, e = getNumSelectorLocs(); i != e; ++i)
293  SelLocs.push_back(getSelectorLoc(i));
294 }
295 
297  switch (getReceiverKind()) {
298  case Instance:
299  return getInstanceReceiver()->getSourceRange();
300 
301  case Class:
302  return getClassReceiverTypeInfo()->getTypeLoc().getSourceRange();
303 
304  case SuperInstance:
305  case SuperClass:
306  return getSuperLoc();
307  }
308 
309  llvm_unreachable("Invalid ReceiverKind!");
310 }
311 
313  if (HasMethod)
314  return reinterpret_cast<const ObjCMethodDecl *>(SelectorOrMethod)
315  ->getSelector();
316  return Selector(SelectorOrMethod);
317 }
318 
320  switch (getReceiverKind()) {
321  case Instance:
322  return getInstanceReceiver()->getType();
323  case Class:
324  return getClassReceiver();
325  case SuperInstance:
326  case SuperClass:
327  return getSuperType();
328  }
329 
330  llvm_unreachable("unexpected receiver kind");
331 }
332 
334  QualType T = getReceiverType();
335 
336  if (const ObjCObjectPointerType *Ptr = T->getAs<ObjCObjectPointerType>())
337  return Ptr->getInterfaceDecl();
338 
339  if (const ObjCObjectType *Ty = T->getAs<ObjCObjectType>())
340  return Ty->getInterface();
341 
342  return nullptr;
343 }
344 
346  Stmt **begin;
347  if (getReceiverKind() == Instance)
348  begin = reinterpret_cast<Stmt **>(getTrailingObjects<void *>());
349  else
350  begin = reinterpret_cast<Stmt **>(getArgs());
351  return child_range(begin,
352  reinterpret_cast<Stmt **>(getArgs() + getNumArgs()));
353 }
354 
356  switch (getBridgeKind()) {
357  case OBC_Bridge:
358  return "__bridge";
359  case OBC_BridgeTransfer:
360  return "__bridge_transfer";
361  case OBC_BridgeRetained:
362  return "__bridge_retained";
363  }
364 
365  llvm_unreachable("Invalid BridgeKind!");
366 }
Defines the clang::ASTContext interface.
static ObjCArrayLiteral * Create(const ASTContext &C, ArrayRef< Expr *> Elements, QualType T, ObjCMethodDecl *Method, SourceRange SR)
Definition: ExprObjC.cpp:45
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:653
void * getAsOpaquePtr() const
Selector getSelector() const
Definition: ExprObjC.cpp:312
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:66
Bridging via __bridge, which does nothing but reinterpret the bits.
C Language Family Type Representation.
ObjCInterfaceDecl * getReceiverInterface() const
Retrieve the Objective-C interface to which this message is being directed, if known.
Definition: ExprObjC.cpp:333
llvm::iterator_range< child_iterator > child_range
Definition: Stmt.h:443
A container of type source information.
Definition: Decl.h:86
static ObjCDictionaryLiteral * CreateEmpty(const ASTContext &C, unsigned NumElements, bool HasPackExpansions)
Definition: ExprObjC.cpp:105
const T * getAs() const
Member-template getAs<specific type>&#39;.
Definition: Type.h:6307
unsigned getNumArgs() const
Determine the number of arguments to this type trait.
Definition: ExprCXX.h:2388
ObjCMethodDecl - Represents an instance or class method declaration.
Definition: DeclObjC.h:139
Represents a class type in Objective C.
Definition: Type.h:5186
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:149
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:264
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:207
ObjCArrayLiteral - used for objective-c array containers; as in: @["Hello", NSApp, [NSNumber numberWithInt:42]];.
Definition: ExprObjC.h:171
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:1635
child_range children()
Definition: ExprObjC.cpp:345
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:699
An ordinary object is located at an address in memory.
Definition: Specifiers.h:123
Represents an ObjC class declaration.
Definition: DeclObjC.h:1191
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:2397
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:288
ExprBitfields ExprBits
Definition: Stmt.h:288
static ObjCDictionaryLiteral * Create(const ASTContext &C, ArrayRef< ObjCDictionaryElement > VK, bool HasPackExpansions, QualType T, ObjCMethodDecl *method, SourceRange SR)
Definition: ExprObjC.cpp:95
Defines the clang::TypeLoc interface and its subclasses.
An expression that sends a message to the given Objective-C object or class.
Definition: ExprObjC.h:903
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:355
#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.
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:319
bool isInstantiationDependentType() const
Determine whether this type is an instantiation-dependent type, meaning that the type involves a temp...
Definition: Type.h:1866
A placeholder type used to construct an empty shell of a type, that will be filled in later (e...
Definition: Stmt.h:325
void * Allocate(size_t Size, unsigned Align=8) const
Definition: ASTContext.h:650
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:296
Represents a pointer to an Objective C object.
Definition: Type.h:5442
QualType getReceiverType(const ASTContext &ctx) const
Determine the type of the base, regardless of the kind of receiver.
Definition: ExprObjC.cpp:113
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:1860
static ObjCArrayLiteral * CreateEmpty(const ASTContext &C, unsigned NumElements)
Definition: ExprObjC.cpp:53
A trivial tuple used to represent a source range.
void getSelectorLocs(SmallVectorImpl< SourceLocation > &SelLocs) const
Definition: ExprObjC.cpp:290
SelectorLocationsKind hasStandardSelectorLocs(Selector Sel, ArrayRef< SourceLocation > SelLocs, ArrayRef< Expr *> Args, SourceLocation EndLoc)
Returns true if all SelLocs are in a "standard" location.