Clang Project

clang_source_code/lib/AST/ExprObjC.cpp
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"
15#include "clang/AST/SelectorLocationsKind.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
24using namespace clang;
25
26ObjCArrayLiteral::ObjCArrayLiteral(ArrayRef<Expr *> ElementsQualType T,
27                                   ObjCMethodDecl *MethodSourceRange SR)
28    : Expr(ObjCArrayLiteralClass, T, VK_RValue, OK_Ordinary, falsefalse,
29           falsefalse),
30      NumElements(Elements.size()), Range(SR), ArrayWithObjectsMethod(Method) {
31  Expr **SaveElements = getElements();
32  for (unsigned I = 0N = 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
44ObjCArrayLiteral *ObjCArrayLiteral::Create(const ASTContext &C,
45                                           ArrayRef<Expr *> Elements,
46                                           QualType TObjCMethodDecl *Method,
47                                           SourceRange SR) {
48  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(Elements.size()));
49  return new (Mem) ObjCArrayLiteral(Elements, T, Method, SR);
50}
51
52ObjCArrayLiteral *ObjCArrayLiteral::CreateEmpty(const ASTContext &C,
53                                                unsigned NumElements) {
54  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(NumElements));
55  return new (Mem) ObjCArrayLiteral(EmptyShell(), NumElements);
56}
57
58ObjCDictionaryLiteral::ObjCDictionaryLiteral(ArrayRef<ObjCDictionaryElementVK,
59                                             bool HasPackExpansionsQualType T,
60                                             ObjCMethodDecl *method,
61                                             SourceRange SR)
62    : Expr(ObjCDictionaryLiteralClass, T, VK_RValue, OK_Ordinary, falsefalse,
63           falsefalse),
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 = 0I < NumElementsI++) {
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
93ObjCDictionaryLiteral *
94ObjCDictionaryLiteral::Create(const ASTContext &C,
95                              ArrayRef<ObjCDictionaryElementVK,
96                              bool HasPackExpansionsQualType T,
97                              ObjCMethodDecl *methodSourceRange 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
103ObjCDictionaryLiteral *
104ObjCDictionaryLiteral::CreateEmpty(const ASTContext &Cunsigned NumElements,
105                                   bool HasPackExpansions) {
106  void *Mem = C.Allocate(totalSizeToAlloc<KeyValuePairExpansionData>(
107      NumElementsHasPackExpansions ? NumElements : 0));
108  return new (Mem)
109      ObjCDictionaryLiteral(EmptyShell(), NumElements, HasPackExpansions);
110}
111
112QualType ObjCPropertyRefExpr::getReceiverType(const ASTContext &ctxconst {
113  if (isClassReceiver())
114    return ctx.getObjCInterfaceType(getClassReceiver());
115
116  if (isSuperReceiver())
117    return getSuperReceiverType();
118
119  return getBase()->getType();
120}
121
122ObjCMessageExpr::ObjCMessageExpr(QualType TExprValueKind VK,
123                                 SourceLocation LBracLoc,
124                                 SourceLocation SuperLocbool IsInstanceSuper,
125                                 QualType SuperTypeSelector Sel,
126                                 ArrayRef<SourceLocationSelLocs,
127                                 SelectorLocationsKind SelLocsK,
128                                 ObjCMethodDecl *MethodArrayRef<Expr *> Args,
129                                 SourceLocation RBracLocbool 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
144ObjCMessageExpr::ObjCMessageExpr(QualType TExprValueKind VK,
145                                 SourceLocation LBracLoc,
146                                 TypeSourceInfo *ReceiverSelector Sel,
147                                 ArrayRef<SourceLocationSelLocs,
148                                 SelectorLocationsKind SelLocsK,
149                                 ObjCMethodDecl *MethodArrayRef<Expr *> Args,
150                                 SourceLocation RBracLocbool isImplicit)
151    : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary, T->isDependentType(),
152           T->isDependentType(), T->isInstantiationDependentType(),
153           T->containsUnexpandedParameterPack()),
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
162ObjCMessageExpr::ObjCMessageExpr(QualType TExprValueKind VK,
163                                 SourceLocation LBracLocExpr *Receiver,
164                                 Selector SelArrayRef<SourceLocationSelLocs,
165                                 SelectorLocationsKind SelLocsK,
166                                 ObjCMethodDecl *MethodArrayRef<Expr *> Args,
167                                 SourceLocation RBracLocbool 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
180void ObjCMessageExpr::initArgsAndSelLocs(ArrayRef<Expr *> Args,
181                                         ArrayRef<SourceLocationSelLocs,
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;
192    if (Args[I]->containsUnexpandedParameterPack())
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
205ObjCMessageExpr *
206ObjCMessageExpr::Create(const ASTContext &ContextQualType TExprValueKind VK,
207                        SourceLocation LBracLocSourceLocation SuperLoc,
208                        bool IsInstanceSuperQualType SuperTypeSelector Sel,
209                        ArrayRef<SourceLocationSelLocs,
210                        ObjCMethodDecl *MethodArrayRef<Expr *> Args,
211                        SourceLocation RBracLocbool isImplicit) {
212   (0) . __assert_fail ("(!SelLocs.empty() || isImplicit) && \"No selector locs for non-implicit message\"", "/home/seafit/code_projects/clang_source/clang/lib/AST/ExprObjC.cpp", 213, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert((!SelLocs.empty() || isImplicit) &&
213 (0) . __assert_fail ("(!SelLocs.empty() || isImplicit) && \"No selector locs for non-implicit message\"", "/home/seafit/code_projects/clang_source/clang/lib/AST/ExprObjC.cpp", 213, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">         "No selector locs for non-implicit message");
214  ObjCMessageExpr *Mem;
215  SelectorLocationsKind SelLocsK = SelectorLocationsKind();
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
225ObjCMessageExpr *
226ObjCMessageExpr::Create(const ASTContext &ContextQualType TExprValueKind VK,
227                        SourceLocation LBracLocTypeSourceInfo *Receiver,
228                        Selector SelArrayRef<SourceLocationSelLocs,
229                        ObjCMethodDecl *MethodArrayRef<Expr *> Args,
230                        SourceLocation RBracLocbool isImplicit) {
231   (0) . __assert_fail ("(!SelLocs.empty() || isImplicit) && \"No selector locs for non-implicit message\"", "/home/seafit/code_projects/clang_source/clang/lib/AST/ExprObjC.cpp", 232, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert((!SelLocs.empty() || isImplicit) &&
232 (0) . __assert_fail ("(!SelLocs.empty() || isImplicit) && \"No selector locs for non-implicit message\"", "/home/seafit/code_projects/clang_source/clang/lib/AST/ExprObjC.cpp", 232, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">         "No selector locs for non-implicit message");
233  ObjCMessageExpr *Mem;
234  SelectorLocationsKind SelLocsK = SelectorLocationsKind();
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
244ObjCMessageExpr *
245ObjCMessageExpr::Create(const ASTContext &ContextQualType TExprValueKind VK,
246                        SourceLocation LBracLocExpr *ReceiverSelector Sel,
247                        ArrayRef<SourceLocationSelLocs,
248                        ObjCMethodDecl *MethodArrayRef<Expr *> Args,
249                        SourceLocation RBracLocbool isImplicit) {
250   (0) . __assert_fail ("(!SelLocs.empty() || isImplicit) && \"No selector locs for non-implicit message\"", "/home/seafit/code_projects/clang_source/clang/lib/AST/ExprObjC.cpp", 251, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert((!SelLocs.empty() || isImplicit) &&
251 (0) . __assert_fail ("(!SelLocs.empty() || isImplicit) && \"No selector locs for non-implicit message\"", "/home/seafit/code_projects/clang_source/clang/lib/AST/ExprObjC.cpp", 251, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">         "No selector locs for non-implicit message");
252  ObjCMessageExpr *Mem;
253  SelectorLocationsKind SelLocsK = SelectorLocationsKind();
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
263ObjCMessageExpr *ObjCMessageExpr::CreateEmpty(const ASTContext &Context,
264                                              unsigned NumArgs,
265                                              unsigned NumStoredSelLocs) {
266  ObjCMessageExpr *Mem = alloc(ContextNumArgsNumStoredSelLocs);
267  return new (Mem) ObjCMessageExpr(EmptyShell(), NumArgs);
268}
269
270ObjCMessageExpr *ObjCMessageExpr::alloc(const ASTContext &C,
271                                        ArrayRef<Expr *> Args,
272                                        SourceLocation RBraceLoc,
273                                        ArrayRef<SourceLocationSelLocs,
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
282ObjCMessageExpr *ObjCMessageExpr::alloc(const ASTContext &Cunsigned NumArgs,
283                                        unsigned NumStoredSelLocs) {
284  return (ObjCMessageExpr *)C.Allocate(
285      totalSizeToAlloc<void *, SourceLocation>(NumArgs + 1NumStoredSelLocs),
286      alignof(ObjCMessageExpr));
287}
288
289void ObjCMessageExpr::getSelectorLocs(
290    SmallVectorImpl<SourceLocation> &SelLocsconst {
291  for (unsigned i = 0, e = getNumSelectorLocs(); i != e; ++i)
292    SelLocs.push_back(getSelectorLoc(i));
293}
294
295
296QualType ObjCMessageExpr::getCallReturnType(ASTContext &Ctxconst {
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
321SourceRange ObjCMessageExpr::getReceiverRange() const {
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
337Selector ObjCMessageExpr::getSelector() const {
338  if (HasMethod)
339    return reinterpret_cast<const ObjCMethodDecl *>(SelectorOrMethod)
340        ->getSelector();
341  return Selector(SelectorOrMethod);
342}
343
344QualType ObjCMessageExpr::getReceiverType() const {
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
358ObjCInterfaceDecl *ObjCMessageExpr::getReceiverInterface() const {
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
370Stmt::child_range ObjCMessageExpr::children() {
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
380StringRef ObjCBridgedCastExpr::getBridgeKindName() const {
381  switch (getBridgeKind()) {
382  case OBC_Bridge:
383    return "__bridge";
384  case OBC_BridgeTransfer:
385    return "__bridge_transfer";
386  case OBC_BridgeRetained:
387    return "__bridge_retained";
388  }
389
390  llvm_unreachable("Invalid BridgeKind!");
391}
392
clang::ObjCArrayLiteral::Create
clang::ObjCArrayLiteral::CreateEmpty
clang::ObjCDictionaryLiteral::Create
clang::ObjCDictionaryLiteral::CreateEmpty
clang::ObjCPropertyRefExpr::getReceiverType
clang::ObjCMessageExpr::initArgsAndSelLocs
clang::ObjCMessageExpr::Create
clang::ObjCMessageExpr::Create
clang::ObjCMessageExpr::Create
clang::ObjCMessageExpr::CreateEmpty
clang::ObjCMessageExpr::alloc
clang::ObjCMessageExpr::alloc
clang::ObjCMessageExpr::getSelectorLocs
clang::ObjCMessageExpr::getCallReturnType
clang::ObjCMessageExpr::getReceiverRange
clang::ObjCMessageExpr::getSelector
clang::ObjCMessageExpr::getReceiverType
clang::ObjCMessageExpr::getReceiverInterface
clang::ObjCMessageExpr::children
clang::ObjCBridgedCastExpr::getBridgeKindName