348 lines · 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-exception6//7//===----------------------------------------------------------------------===//8//9// This file implements the subclesses of Expr class declared in ExprObjC.h10//11//===----------------------------------------------------------------------===//12 13#include "clang/AST/ExprObjC.h"14#include "clang/AST/ASTContext.h"15#include "clang/AST/Attr.h"16#include "clang/AST/ComputeDependence.h"17#include "clang/AST/SelectorLocationsKind.h"18#include "clang/AST/Type.h"19#include "clang/AST/TypeLoc.h"20#include "llvm/Support/ErrorHandling.h"21#include <cassert>22#include <cstdint>23 24using namespace clang;25 26ObjCArrayLiteral::ObjCArrayLiteral(ArrayRef<Expr *> Elements, QualType T,27 ObjCMethodDecl *Method, SourceRange SR)28 : Expr(ObjCArrayLiteralClass, T, VK_PRValue, OK_Ordinary),29 NumElements(Elements.size()), Range(SR), ArrayWithObjectsMethod(Method) {30 Expr **SaveElements = getElements();31 for (unsigned I = 0, N = Elements.size(); I != N; ++I)32 SaveElements[I] = Elements[I];33 34 setDependence(computeDependence(this));35}36 37ObjCArrayLiteral *ObjCArrayLiteral::Create(const ASTContext &C,38 ArrayRef<Expr *> Elements,39 QualType T, ObjCMethodDecl *Method,40 SourceRange SR) {41 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(Elements.size()));42 return new (Mem) ObjCArrayLiteral(Elements, T, Method, SR);43}44 45ObjCArrayLiteral *ObjCArrayLiteral::CreateEmpty(const ASTContext &C,46 unsigned NumElements) {47 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(NumElements));48 return new (Mem) ObjCArrayLiteral(EmptyShell(), NumElements);49}50 51ObjCDictionaryLiteral::ObjCDictionaryLiteral(ArrayRef<ObjCDictionaryElement> VK,52 bool HasPackExpansions, QualType T,53 ObjCMethodDecl *method,54 SourceRange SR)55 : Expr(ObjCDictionaryLiteralClass, T, VK_PRValue, OK_Ordinary),56 NumElements(VK.size()), HasPackExpansions(HasPackExpansions), Range(SR),57 DictWithObjectsMethod(method) {58 KeyValuePair *KeyValues = getTrailingObjects<KeyValuePair>();59 ExpansionData *Expansions =60 HasPackExpansions ? getTrailingObjects<ExpansionData>() : nullptr;61 for (unsigned I = 0; I < NumElements; I++) {62 KeyValues[I].Key = VK[I].Key;63 KeyValues[I].Value = VK[I].Value;64 if (Expansions) {65 Expansions[I].EllipsisLoc = VK[I].EllipsisLoc;66 if (VK[I].NumExpansions)67 Expansions[I].NumExpansionsPlusOne = *VK[I].NumExpansions + 1;68 else69 Expansions[I].NumExpansionsPlusOne = 0;70 }71 }72 setDependence(computeDependence(this));73}74 75ObjCDictionaryLiteral *76ObjCDictionaryLiteral::Create(const ASTContext &C,77 ArrayRef<ObjCDictionaryElement> VK,78 bool HasPackExpansions, QualType T,79 ObjCMethodDecl *method, SourceRange SR) {80 void *Mem = C.Allocate(totalSizeToAlloc<KeyValuePair, ExpansionData>(81 VK.size(), HasPackExpansions ? VK.size() : 0));82 return new (Mem) ObjCDictionaryLiteral(VK, HasPackExpansions, T, method, SR);83}84 85ObjCDictionaryLiteral *86ObjCDictionaryLiteral::CreateEmpty(const ASTContext &C, unsigned NumElements,87 bool HasPackExpansions) {88 void *Mem = C.Allocate(totalSizeToAlloc<KeyValuePair, ExpansionData>(89 NumElements, HasPackExpansions ? NumElements : 0));90 return new (Mem)91 ObjCDictionaryLiteral(EmptyShell(), NumElements, HasPackExpansions);92}93 94QualType ObjCPropertyRefExpr::getReceiverType(const ASTContext &ctx) const {95 if (isClassReceiver())96 return ctx.getObjCInterfaceType(getClassReceiver());97 98 if (isSuperReceiver())99 return getSuperReceiverType();100 101 return getBase()->getType();102}103 104ObjCMessageExpr::ObjCMessageExpr(QualType T, ExprValueKind VK,105 SourceLocation LBracLoc,106 SourceLocation SuperLoc, bool IsInstanceSuper,107 QualType SuperType, Selector Sel,108 ArrayRef<SourceLocation> SelLocs,109 SelectorLocationsKind SelLocsK,110 ObjCMethodDecl *Method, ArrayRef<Expr *> Args,111 SourceLocation RBracLoc, bool isImplicit)112 : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary),113 SelectorOrMethod(114 reinterpret_cast<uintptr_t>(Method ? Method : Sel.getAsOpaquePtr())),115 Kind(IsInstanceSuper ? SuperInstance : SuperClass),116 HasMethod(Method != nullptr), IsDelegateInitCall(false),117 IsImplicit(isImplicit), SuperLoc(SuperLoc), LBracLoc(LBracLoc),118 RBracLoc(RBracLoc) {119 initArgsAndSelLocs(Args, SelLocs, SelLocsK);120 setReceiverPointer(SuperType.getAsOpaquePtr());121 setDependence(computeDependence(this));122}123 124ObjCMessageExpr::ObjCMessageExpr(QualType T, ExprValueKind VK,125 SourceLocation LBracLoc,126 TypeSourceInfo *Receiver, 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 SelectorOrMethod(133 reinterpret_cast<uintptr_t>(Method ? Method : Sel.getAsOpaquePtr())),134 Kind(Class), HasMethod(Method != nullptr), IsDelegateInitCall(false),135 IsImplicit(isImplicit), LBracLoc(LBracLoc), RBracLoc(RBracLoc) {136 initArgsAndSelLocs(Args, SelLocs, SelLocsK);137 setReceiverPointer(Receiver);138 setDependence(computeDependence(this));139}140 141ObjCMessageExpr::ObjCMessageExpr(QualType T, ExprValueKind VK,142 SourceLocation LBracLoc, Expr *Receiver,143 Selector Sel, ArrayRef<SourceLocation> SelLocs,144 SelectorLocationsKind SelLocsK,145 ObjCMethodDecl *Method, ArrayRef<Expr *> Args,146 SourceLocation RBracLoc, bool isImplicit)147 : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary),148 SelectorOrMethod(149 reinterpret_cast<uintptr_t>(Method ? Method : Sel.getAsOpaquePtr())),150 Kind(Instance), HasMethod(Method != nullptr), IsDelegateInitCall(false),151 IsImplicit(isImplicit), LBracLoc(LBracLoc), RBracLoc(RBracLoc) {152 initArgsAndSelLocs(Args, SelLocs, SelLocsK);153 setReceiverPointer(Receiver);154 setDependence(computeDependence(this));155}156 157void ObjCMessageExpr::initArgsAndSelLocs(ArrayRef<Expr *> Args,158 ArrayRef<SourceLocation> SelLocs,159 SelectorLocationsKind SelLocsK) {160 setNumArgs(Args.size());161 Expr **MyArgs = getArgs();162 for (unsigned I = 0; I != Args.size(); ++I)163 MyArgs[I] = Args[I];164 165 SelLocsKind = SelLocsK;166 if (!isImplicit() && SelLocsK == SelLoc_NonStandard)167 llvm::copy(SelLocs, getStoredSelLocs());168}169 170ObjCMessageExpr *171ObjCMessageExpr::Create(const ASTContext &Context, QualType T, ExprValueKind VK,172 SourceLocation LBracLoc, SourceLocation SuperLoc,173 bool IsInstanceSuper, QualType SuperType, Selector Sel,174 ArrayRef<SourceLocation> SelLocs,175 ObjCMethodDecl *Method, ArrayRef<Expr *> Args,176 SourceLocation RBracLoc, bool isImplicit) {177 assert((!SelLocs.empty() || isImplicit) &&178 "No selector locs for non-implicit message");179 ObjCMessageExpr *Mem;180 SelectorLocationsKind SelLocsK = SelectorLocationsKind();181 if (isImplicit)182 Mem = alloc(Context, Args.size(), 0);183 else184 Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK);185 return new (Mem) ObjCMessageExpr(T, VK, LBracLoc, SuperLoc, IsInstanceSuper,186 SuperType, Sel, SelLocs, SelLocsK, Method,187 Args, RBracLoc, isImplicit);188}189 190ObjCMessageExpr *191ObjCMessageExpr::Create(const ASTContext &Context, QualType T, ExprValueKind VK,192 SourceLocation LBracLoc, TypeSourceInfo *Receiver,193 Selector Sel, ArrayRef<SourceLocation> SelLocs,194 ObjCMethodDecl *Method, ArrayRef<Expr *> Args,195 SourceLocation RBracLoc, bool isImplicit) {196 assert((!SelLocs.empty() || isImplicit) &&197 "No selector locs for non-implicit message");198 ObjCMessageExpr *Mem;199 SelectorLocationsKind SelLocsK = SelectorLocationsKind();200 if (isImplicit)201 Mem = alloc(Context, Args.size(), 0);202 else203 Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK);204 return new (Mem)205 ObjCMessageExpr(T, VK, LBracLoc, Receiver, Sel, SelLocs, SelLocsK, Method,206 Args, RBracLoc, isImplicit);207}208 209ObjCMessageExpr *210ObjCMessageExpr::Create(const ASTContext &Context, QualType T, ExprValueKind VK,211 SourceLocation LBracLoc, Expr *Receiver, Selector Sel,212 ArrayRef<SourceLocation> SelLocs,213 ObjCMethodDecl *Method, ArrayRef<Expr *> Args,214 SourceLocation RBracLoc, bool isImplicit) {215 assert((!SelLocs.empty() || isImplicit) &&216 "No selector locs for non-implicit message");217 ObjCMessageExpr *Mem;218 SelectorLocationsKind SelLocsK = SelectorLocationsKind();219 if (isImplicit)220 Mem = alloc(Context, Args.size(), 0);221 else222 Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK);223 return new (Mem)224 ObjCMessageExpr(T, VK, LBracLoc, Receiver, Sel, SelLocs, SelLocsK, Method,225 Args, RBracLoc, isImplicit);226}227 228ObjCMessageExpr *ObjCMessageExpr::CreateEmpty(const ASTContext &Context,229 unsigned NumArgs,230 unsigned NumStoredSelLocs) {231 ObjCMessageExpr *Mem = alloc(Context, NumArgs, NumStoredSelLocs);232 return new (Mem) ObjCMessageExpr(EmptyShell(), NumArgs);233}234 235ObjCMessageExpr *ObjCMessageExpr::alloc(const ASTContext &C,236 ArrayRef<Expr *> Args,237 SourceLocation RBraceLoc,238 ArrayRef<SourceLocation> SelLocs,239 Selector Sel,240 SelectorLocationsKind &SelLocsK) {241 SelLocsK = hasStandardSelectorLocs(Sel, SelLocs, Args, RBraceLoc);242 unsigned NumStoredSelLocs =243 (SelLocsK == SelLoc_NonStandard) ? SelLocs.size() : 0;244 return alloc(C, Args.size(), NumStoredSelLocs);245}246 247ObjCMessageExpr *ObjCMessageExpr::alloc(const ASTContext &C, unsigned NumArgs,248 unsigned NumStoredSelLocs) {249 return (ObjCMessageExpr *)C.Allocate(250 totalSizeToAlloc<void *, SourceLocation>(NumArgs + 1, NumStoredSelLocs),251 alignof(ObjCMessageExpr));252}253 254void ObjCMessageExpr::getSelectorLocs(255 SmallVectorImpl<SourceLocation> &SelLocs) const {256 for (unsigned i = 0, e = getNumSelectorLocs(); i != e; ++i)257 SelLocs.push_back(getSelectorLoc(i));258}259 260 261QualType ObjCMessageExpr::getCallReturnType(ASTContext &Ctx) const {262 if (const ObjCMethodDecl *MD = getMethodDecl()) {263 QualType QT = MD->getReturnType();264 if (QT == Ctx.getObjCInstanceType()) {265 // instancetype corresponds to expression types.266 return getType();267 }268 return QT;269 }270 return Ctx.getReferenceQualifiedType(this);271}272 273SourceRange ObjCMessageExpr::getReceiverRange() const {274 switch (getReceiverKind()) {275 case Instance:276 return getInstanceReceiver()->getSourceRange();277 278 case Class:279 return getClassReceiverTypeInfo()->getTypeLoc().getSourceRange();280 281 case SuperInstance:282 case SuperClass:283 return getSuperLoc();284 }285 286 llvm_unreachable("Invalid ReceiverKind!");287}288 289Selector ObjCMessageExpr::getSelector() const {290 if (HasMethod)291 return reinterpret_cast<const ObjCMethodDecl *>(SelectorOrMethod)292 ->getSelector();293 return Selector(SelectorOrMethod);294}295 296QualType ObjCMessageExpr::getReceiverType() const {297 switch (getReceiverKind()) {298 case Instance:299 return getInstanceReceiver()->getType();300 case Class:301 return getClassReceiver();302 case SuperInstance:303 case SuperClass:304 return getSuperType();305 }306 307 llvm_unreachable("unexpected receiver kind");308}309 310ObjCInterfaceDecl *ObjCMessageExpr::getReceiverInterface() const {311 QualType T = getReceiverType();312 313 if (const ObjCObjectPointerType *Ptr = T->getAs<ObjCObjectPointerType>())314 return Ptr->getInterfaceDecl();315 316 if (const ObjCObjectType *Ty = T->getAs<ObjCObjectType>())317 return Ty->getInterface();318 319 return nullptr;320}321 322Stmt::child_range ObjCMessageExpr::children() {323 Stmt **begin;324 if (getReceiverKind() == Instance)325 begin = reinterpret_cast<Stmt **>(getTrailingObjects<void *>());326 else327 begin = reinterpret_cast<Stmt **>(getArgs());328 return child_range(begin,329 reinterpret_cast<Stmt **>(getArgs() + getNumArgs()));330}331 332Stmt::const_child_range ObjCMessageExpr::children() const {333 return const_cast<ObjCMessageExpr *>(this)->children();334}335 336StringRef ObjCBridgedCastExpr::getBridgeKindName() const {337 switch (getBridgeKind()) {338 case OBC_Bridge:339 return "__bridge";340 case OBC_BridgeTransfer:341 return "__bridge_transfer";342 case OBC_BridgeRetained:343 return "__bridge_retained";344 }345 346 llvm_unreachable("Invalid BridgeKind!");347}348