clang  10.0.0svn
ExprObjC.cpp
Go to the documentation of this file.
1 //===- ExprObjC.cpp - (ObjC) Expression AST Node Implementation -----------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implements the subclesses of Expr class declared in ExprObjC.h
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "clang/AST/ExprObjC.h"
14 #include "clang/AST/ASTContext.h"
16 #include "clang/AST/Type.h"
17 #include "clang/AST/TypeLoc.h"
18 #include "llvm/ADT/SmallVector.h"
19 #include "llvm/Support/ErrorHandling.h"
20 #include <algorithm>
21 #include <cassert>
22 #include <cstdint>
23 
24 using namespace clang;
25 
26 ObjCArrayLiteral::ObjCArrayLiteral(ArrayRef<Expr *> Elements, QualType T,
27  ObjCMethodDecl *Method, SourceRange SR)
28  : Expr(ObjCArrayLiteralClass, T, VK_RValue, OK_Ordinary, false, false,
29  false, false),
30  NumElements(Elements.size()), Range(SR), ArrayWithObjectsMethod(Method) {
31  Expr **SaveElements = getElements();
32  for (unsigned I = 0, N = Elements.size(); I != N; ++I) {
33  if (Elements[I]->isTypeDependent() || Elements[I]->isValueDependent())
34  ExprBits.ValueDependent = true;
35  if (Elements[I]->isInstantiationDependent())
36  ExprBits.InstantiationDependent = true;
37  if (Elements[I]->containsUnexpandedParameterPack())
38  ExprBits.ContainsUnexpandedParameterPack = true;
39 
40  SaveElements[I] = Elements[I];
41  }
42 }
43 
45  ArrayRef<Expr *> Elements,
46  QualType T, ObjCMethodDecl *Method,
47  SourceRange SR) {
48  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(Elements.size()));
49  return new (Mem) ObjCArrayLiteral(Elements, T, Method, SR);
50 }
51 
53  unsigned NumElements) {
54  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(NumElements));
55  return new (Mem) ObjCArrayLiteral(EmptyShell(), NumElements);
56 }
57 
58 ObjCDictionaryLiteral::ObjCDictionaryLiteral(ArrayRef<ObjCDictionaryElement> VK,
59  bool HasPackExpansions, QualType T,
60  ObjCMethodDecl *method,
61  SourceRange SR)
62  : Expr(ObjCDictionaryLiteralClass, T, VK_RValue, OK_Ordinary, false, false,
63  false, false),
64  NumElements(VK.size()), HasPackExpansions(HasPackExpansions), Range(SR),
65  DictWithObjectsMethod(method) {
66  KeyValuePair *KeyValues = getTrailingObjects<KeyValuePair>();
67  ExpansionData *Expansions =
68  HasPackExpansions ? getTrailingObjects<ExpansionData>() : nullptr;
69  for (unsigned I = 0; I < NumElements; I++) {
70  if (VK[I].Key->isTypeDependent() || VK[I].Key->isValueDependent() ||
71  VK[I].Value->isTypeDependent() || VK[I].Value->isValueDependent())
72  ExprBits.ValueDependent = true;
73  if (VK[I].Key->isInstantiationDependent() ||
74  VK[I].Value->isInstantiationDependent())
75  ExprBits.InstantiationDependent = true;
76  if (VK[I].EllipsisLoc.isInvalid() &&
77  (VK[I].Key->containsUnexpandedParameterPack() ||
78  VK[I].Value->containsUnexpandedParameterPack()))
79  ExprBits.ContainsUnexpandedParameterPack = true;
80 
81  KeyValues[I].Key = VK[I].Key;
82  KeyValues[I].Value = VK[I].Value;
83  if (Expansions) {
84  Expansions[I].EllipsisLoc = VK[I].EllipsisLoc;
85  if (VK[I].NumExpansions)
86  Expansions[I].NumExpansionsPlusOne = *VK[I].NumExpansions + 1;
87  else
88  Expansions[I].NumExpansionsPlusOne = 0;
89  }
90  }
91 }
92 
96  bool HasPackExpansions, QualType T,
97  ObjCMethodDecl *method, SourceRange SR) {
98  void *Mem = C.Allocate(totalSizeToAlloc<KeyValuePair, ExpansionData>(
99  VK.size(), HasPackExpansions ? VK.size() : 0));
100  return new (Mem) ObjCDictionaryLiteral(VK, HasPackExpansions, T, method, SR);
101 }
102 
104 ObjCDictionaryLiteral::CreateEmpty(const ASTContext &C, unsigned NumElements,
105  bool HasPackExpansions) {
106  void *Mem = C.Allocate(totalSizeToAlloc<KeyValuePair, ExpansionData>(
107  NumElements, HasPackExpansions ? NumElements : 0));
108  return new (Mem)
109  ObjCDictionaryLiteral(EmptyShell(), NumElements, HasPackExpansions);
110 }
111 
113  if (isClassReceiver())
114  return ctx.getObjCInterfaceType(getClassReceiver());
115 
116  if (isSuperReceiver())
117  return getSuperReceiverType();
118 
119  return getBase()->getType();
120 }
121 
122 ObjCMessageExpr::ObjCMessageExpr(QualType T, ExprValueKind VK,
123  SourceLocation LBracLoc,
124  SourceLocation SuperLoc, bool IsInstanceSuper,
125  QualType SuperType, Selector Sel,
126  ArrayRef<SourceLocation> SelLocs,
127  SelectorLocationsKind SelLocsK,
128  ObjCMethodDecl *Method, ArrayRef<Expr *> Args,
129  SourceLocation RBracLoc, bool isImplicit)
130  : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary,
131  /*TypeDependent=*/false, /*ValueDependent=*/false,
132  /*InstantiationDependent=*/false,
133  /*ContainsUnexpandedParameterPack=*/false),
134  SelectorOrMethod(
135  reinterpret_cast<uintptr_t>(Method ? Method : Sel.getAsOpaquePtr())),
136  Kind(IsInstanceSuper ? SuperInstance : SuperClass),
137  HasMethod(Method != nullptr), IsDelegateInitCall(false),
138  IsImplicit(isImplicit), SuperLoc(SuperLoc), LBracLoc(LBracLoc),
139  RBracLoc(RBracLoc) {
140  initArgsAndSelLocs(Args, SelLocs, SelLocsK);
141  setReceiverPointer(SuperType.getAsOpaquePtr());
142 }
143 
144 ObjCMessageExpr::ObjCMessageExpr(QualType T, ExprValueKind VK,
145  SourceLocation LBracLoc,
146  TypeSourceInfo *Receiver, Selector Sel,
147  ArrayRef<SourceLocation> SelLocs,
148  SelectorLocationsKind SelLocsK,
149  ObjCMethodDecl *Method, ArrayRef<Expr *> Args,
150  SourceLocation RBracLoc, bool isImplicit)
151  : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary, T->isDependentType(),
154  SelectorOrMethod(
155  reinterpret_cast<uintptr_t>(Method ? Method : Sel.getAsOpaquePtr())),
156  Kind(Class), HasMethod(Method != nullptr), IsDelegateInitCall(false),
157  IsImplicit(isImplicit), LBracLoc(LBracLoc), RBracLoc(RBracLoc) {
158  initArgsAndSelLocs(Args, SelLocs, SelLocsK);
159  setReceiverPointer(Receiver);
160 }
161 
162 ObjCMessageExpr::ObjCMessageExpr(QualType T, ExprValueKind VK,
163  SourceLocation LBracLoc, Expr *Receiver,
164  Selector Sel, ArrayRef<SourceLocation> SelLocs,
165  SelectorLocationsKind SelLocsK,
166  ObjCMethodDecl *Method, ArrayRef<Expr *> Args,
167  SourceLocation RBracLoc, bool isImplicit)
168  : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary,
169  Receiver->isTypeDependent(), Receiver->isTypeDependent(),
170  Receiver->isInstantiationDependent(),
171  Receiver->containsUnexpandedParameterPack()),
172  SelectorOrMethod(
173  reinterpret_cast<uintptr_t>(Method ? Method : Sel.getAsOpaquePtr())),
174  Kind(Instance), HasMethod(Method != nullptr), IsDelegateInitCall(false),
175  IsImplicit(isImplicit), LBracLoc(LBracLoc), RBracLoc(RBracLoc) {
176  initArgsAndSelLocs(Args, SelLocs, SelLocsK);
177  setReceiverPointer(Receiver);
178 }
179 
180 void ObjCMessageExpr::initArgsAndSelLocs(ArrayRef<Expr *> Args,
181  ArrayRef<SourceLocation> SelLocs,
182  SelectorLocationsKind SelLocsK) {
183  setNumArgs(Args.size());
184  Expr **MyArgs = getArgs();
185  for (unsigned I = 0; I != Args.size(); ++I) {
186  if (Args[I]->isTypeDependent())
187  ExprBits.TypeDependent = true;
188  if (Args[I]->isValueDependent())
189  ExprBits.ValueDependent = true;
190  if (Args[I]->isInstantiationDependent())
191  ExprBits.InstantiationDependent = true;
193  ExprBits.ContainsUnexpandedParameterPack = true;
194 
195  MyArgs[I] = Args[I];
196  }
197 
198  SelLocsKind = SelLocsK;
199  if (!isImplicit()) {
200  if (SelLocsK == SelLoc_NonStandard)
201  std::copy(SelLocs.begin(), SelLocs.end(), getStoredSelLocs());
202  }
203 }
204 
207  SourceLocation LBracLoc, SourceLocation SuperLoc,
208  bool IsInstanceSuper, QualType SuperType, Selector Sel,
209  ArrayRef<SourceLocation> SelLocs,
210  ObjCMethodDecl *Method, ArrayRef<Expr *> Args,
211  SourceLocation RBracLoc, bool isImplicit) {
212  assert((!SelLocs.empty() || isImplicit) &&
213  "No selector locs for non-implicit message");
214  ObjCMessageExpr *Mem;
216  if (isImplicit)
217  Mem = alloc(Context, Args.size(), 0);
218  else
219  Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK);
220  return new (Mem) ObjCMessageExpr(T, VK, LBracLoc, SuperLoc, IsInstanceSuper,
221  SuperType, Sel, SelLocs, SelLocsK, Method,
222  Args, RBracLoc, isImplicit);
223 }
224 
227  SourceLocation LBracLoc, TypeSourceInfo *Receiver,
228  Selector Sel, ArrayRef<SourceLocation> SelLocs,
229  ObjCMethodDecl *Method, ArrayRef<Expr *> Args,
230  SourceLocation RBracLoc, bool isImplicit) {
231  assert((!SelLocs.empty() || isImplicit) &&
232  "No selector locs for non-implicit message");
233  ObjCMessageExpr *Mem;
235  if (isImplicit)
236  Mem = alloc(Context, Args.size(), 0);
237  else
238  Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK);
239  return new (Mem)
240  ObjCMessageExpr(T, VK, LBracLoc, Receiver, Sel, SelLocs, SelLocsK, Method,
241  Args, RBracLoc, isImplicit);
242 }
243 
246  SourceLocation LBracLoc, Expr *Receiver, Selector Sel,
247  ArrayRef<SourceLocation> SelLocs,
248  ObjCMethodDecl *Method, ArrayRef<Expr *> Args,
249  SourceLocation RBracLoc, bool isImplicit) {
250  assert((!SelLocs.empty() || isImplicit) &&
251  "No selector locs for non-implicit message");
252  ObjCMessageExpr *Mem;
254  if (isImplicit)
255  Mem = alloc(Context, Args.size(), 0);
256  else
257  Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK);
258  return new (Mem)
259  ObjCMessageExpr(T, VK, LBracLoc, Receiver, Sel, SelLocs, SelLocsK, Method,
260  Args, RBracLoc, isImplicit);
261 }
262 
264  unsigned NumArgs,
265  unsigned NumStoredSelLocs) {
266  ObjCMessageExpr *Mem = alloc(Context, NumArgs, NumStoredSelLocs);
267  return new (Mem) ObjCMessageExpr(EmptyShell(), NumArgs);
268 }
269 
270 ObjCMessageExpr *ObjCMessageExpr::alloc(const ASTContext &C,
271  ArrayRef<Expr *> Args,
272  SourceLocation RBraceLoc,
273  ArrayRef<SourceLocation> SelLocs,
274  Selector Sel,
275  SelectorLocationsKind &SelLocsK) {
276  SelLocsK = hasStandardSelectorLocs(Sel, SelLocs, Args, RBraceLoc);
277  unsigned NumStoredSelLocs =
278  (SelLocsK == SelLoc_NonStandard) ? SelLocs.size() : 0;
279  return alloc(C, Args.size(), NumStoredSelLocs);
280 }
281 
282 ObjCMessageExpr *ObjCMessageExpr::alloc(const ASTContext &C, unsigned NumArgs,
283  unsigned NumStoredSelLocs) {
284  return (ObjCMessageExpr *)C.Allocate(
285  totalSizeToAlloc<void *, SourceLocation>(NumArgs + 1, NumStoredSelLocs),
286  alignof(ObjCMessageExpr));
287 }
288 
290  SmallVectorImpl<SourceLocation> &SelLocs) const {
291  for (unsigned i = 0, e = getNumSelectorLocs(); i != e; ++i)
292  SelLocs.push_back(getSelectorLoc(i));
293 }
294 
295 
297  if (const ObjCMethodDecl *MD = getMethodDecl()) {
298  QualType QT = MD->getReturnType();
299  if (QT == Ctx.getObjCInstanceType()) {
300  // instancetype corresponds to expression types.
301  return getType();
302  }
303  return QT;
304  }
305 
306  // Expression type might be different from an expected call return type,
307  // as expression type would never be a reference even if call returns a
308  // reference. Reconstruct the original expression type.
309  QualType QT = getType();
310  switch (getValueKind()) {
311  case VK_LValue:
312  return Ctx.getLValueReferenceType(QT);
313  case VK_XValue:
314  return Ctx.getRValueReferenceType(QT);
315  case VK_RValue:
316  return QT;
317  }
318  llvm_unreachable("Unsupported ExprValueKind");
319 }
320 
322  switch (getReceiverKind()) {
323  case Instance:
324  return getInstanceReceiver()->getSourceRange();
325 
326  case Class:
327  return getClassReceiverTypeInfo()->getTypeLoc().getSourceRange();
328 
329  case SuperInstance:
330  case SuperClass:
331  return getSuperLoc();
332  }
333 
334  llvm_unreachable("Invalid ReceiverKind!");
335 }
336 
338  if (HasMethod)
339  return reinterpret_cast<const ObjCMethodDecl *>(SelectorOrMethod)
340  ->getSelector();
341  return Selector(SelectorOrMethod);
342 }
343 
345  switch (getReceiverKind()) {
346  case Instance:
347  return getInstanceReceiver()->getType();
348  case Class:
349  return getClassReceiver();
350  case SuperInstance:
351  case SuperClass:
352  return getSuperType();
353  }
354 
355  llvm_unreachable("unexpected receiver kind");
356 }
357 
359  QualType T = getReceiverType();
360 
361  if (const ObjCObjectPointerType *Ptr = T->getAs<ObjCObjectPointerType>())
362  return Ptr->getInterfaceDecl();
363 
364  if (const ObjCObjectType *Ty = T->getAs<ObjCObjectType>())
365  return Ty->getInterface();
366 
367  return nullptr;
368 }
369 
371  Stmt **begin;
372  if (getReceiverKind() == Instance)
373  begin = reinterpret_cast<Stmt **>(getTrailingObjects<void *>());
374  else
375  begin = reinterpret_cast<Stmt **>(getArgs());
376  return child_range(begin,
377  reinterpret_cast<Stmt **>(getArgs() + getNumArgs()));
378 }
379 
381  auto Children = const_cast<ObjCMessageExpr *>(this)->children();
382  return const_child_range(Children.begin(), Children.end());
383 }
384 
386  switch (getBridgeKind()) {
387  case OBC_Bridge:
388  return "__bridge";
389  case OBC_BridgeTransfer:
390  return "__bridge_transfer";
391  case OBC_BridgeRetained:
392  return "__bridge_retained";
393  }
394 
395  llvm_unreachable("Invalid BridgeKind!");
396 }
Defines the clang::ASTContext interface.
Expr ** getArgs()
Retrieve the call arguments.
Definition: Expr.h:2667
static ObjCArrayLiteral * Create(const ASTContext &C, ArrayRef< Expr *> Elements, QualType T, ObjCMethodDecl *Method, SourceRange SR)
Definition: ExprObjC.cpp:44
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:643
void * getAsOpaquePtr() const
Selector getSelector() const
Definition: ExprObjC.cpp:337
Stmt - This represents one statement.
Definition: Stmt.h:66
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this call.
Definition: Expr.h:2664
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:358
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const
Return the uniqued reference to the type for an lvalue reference to the specified type...
llvm::iterator_range< child_iterator > child_range
Definition: Stmt.h:1158
A container of type source information.
Definition: Decl.h:86
static ObjCDictionaryLiteral * CreateEmpty(const ASTContext &C, unsigned NumElements, bool HasPackExpansions)
Definition: ExprObjC.cpp:104
const T * getAs() const
Member-template getAs<specific type>&#39;.
Definition: Type.h:6858
ObjCMethodDecl - Represents an instance or class method declaration.
Definition: DeclObjC.h:138
Represents a class type in Objective C.
Definition: Type.h:5614
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:160
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:263
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:206
ObjCArrayLiteral - used for objective-c array containers; as in: @["Hello", NSApp, [NSNumber numberWithInt:42]];.
Definition: ExprObjC.h:188
An r-value expression (a pr-value in the C++11 taxonomy) produces a temporary value.
Definition: Specifiers.h:125
SelectorLocationsKind
Whether all locations of the selector identifiers are in a "standard" position.
An x-value expression is a reference to an object with independent storage but which can be "moved"...
Definition: Specifiers.h:134
ExprValueKind getValueKind() const
getValueKind - The value kind that this expression produces.
Definition: Expr.h:414
child_range children()
Definition: Expr.h:2786
bool containsUnexpandedParameterPack() const
Whether this type is or contains an unexpanded parameter pack, used to support C++0x variadic templat...
Definition: Type.h:1871
child_range children()
Definition: ExprObjC.cpp:370
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:176
void * getAsOpaquePtr() const
Definition: Type.h:688
An ordinary object is located at an address in memory.
Definition: Specifiers.h:141
Represents an ObjC class declaration.
Definition: DeclObjC.h:1171
Bridging via __bridge_transfer, which transfers ownership of an Objective-C pointer into ARC...
Expr()=delete
llvm::iterator_range< const_child_iterator > const_child_range
Definition: Stmt.h:1159
This represents one expression.
Definition: Expr.h:108
ExprValueKind
The categorization of expression values, currently following the C++11 scheme.
Definition: Specifiers.h:122
ObjCDictionaryLiteral - AST node to represent objective-c dictionary literals; as in:"name" : NSUserN...
Definition: ExprObjC.h:304
ExprBitfields ExprBits
Definition: Stmt.h:959
static ObjCDictionaryLiteral * Create(const ASTContext &C, ArrayRef< ObjCDictionaryElement > VK, bool HasPackExpansions, QualType T, ObjCMethodDecl *method, SourceRange SR)
Definition: ExprObjC.cpp:94
Defines the clang::TypeLoc interface and its subclasses.
QualType getType() const
Definition: Expr.h:137
An expression that sends a message to the given Objective-C object or class.
Definition: ExprObjC.h:950
QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl, ObjCInterfaceDecl *PrevDecl=nullptr) const
getObjCInterfaceType - Return the unique reference to the type for the specified ObjC interface decl...
QualType getCallReturnType(ASTContext &Ctx) const
Definition: ExprObjC.cpp:296
StringRef getBridgeKindName() const
Retrieve the kind of bridge being performed as a string.
Definition: ExprObjC.cpp:385
#define false
Definition: stdbool.h:17
Kind
bool isInstantiationDependent() const
Whether this expression is instantiation-dependent, meaning that it depends in some way on a template...
Definition: Expr.h:200
Encodes a location in the source.
bool isValueDependent() const
isValueDependent - Determines whether this expression is value-dependent (C++ [temp.dep.constexpr]).
Definition: Expr.h:158
QualType getReceiverType() const
Retrieve the receiver type to which this message is being directed.
Definition: ExprObjC.cpp:344
bool isInstantiationDependentType() const
Determine whether this type is an instantiation-dependent type, meaning that the type involves a temp...
Definition: Type.h:2127
A placeholder type used to construct an empty shell of a type, that will be filled in later (e...
Definition: Stmt.h:1034
QualType getObjCInstanceType()
Retrieve the Objective-C "instancetype" type, if already known; otherwise, returns a NULL type;...
Definition: ASTContext.h:1739
void * Allocate(size_t Size, unsigned Align=8) const
Definition: ASTContext.h:685
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:321
Represents a pointer to an Objective C object.
Definition: Type.h:5870
QualType getRValueReferenceType(QualType T) const
Return the uniqued reference to the type for an rvalue reference to the specified type...
QualType getReceiverType(const ASTContext &ctx) const
Determine the type of the base, regardless of the kind of receiver.
Definition: ExprObjC.cpp:112
bool containsUnexpandedParameterPack() const
Whether this expression contains an unexpanded parameter pack (for C++11 variadic templates)...
Definition: Expr.h:223
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
Definition: Type.h:2121
static ObjCArrayLiteral * CreateEmpty(const ASTContext &C, unsigned NumElements)
Definition: ExprObjC.cpp:52
An l-value expression is a reference to an object with independent storage.
Definition: Specifiers.h:129
A trivial tuple used to represent a source range.
void getSelectorLocs(SmallVectorImpl< SourceLocation > &SelLocs) const
Definition: ExprObjC.cpp:289
SelectorLocationsKind hasStandardSelectorLocs(Selector Sel, ArrayRef< SourceLocation > SelLocs, ArrayRef< Expr *> Args, SourceLocation EndLoc)
Returns true if all SelLocs are in a "standard" location.