Path: blob/main/contrib/llvm-project/clang/lib/AST/ExprObjC.cpp
35259 views
//===- ExprObjC.cpp - (ObjC) Expression AST Node Implementation -----------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file implements the subclesses of Expr class declared in ExprObjC.h9//10//===----------------------------------------------------------------------===//1112#include "clang/AST/ExprObjC.h"13#include "clang/AST/ASTContext.h"14#include "clang/AST/ComputeDependence.h"15#include "clang/AST/DependenceFlags.h"16#include "clang/AST/SelectorLocationsKind.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>2425using namespace clang;2627ObjCArrayLiteral::ObjCArrayLiteral(ArrayRef<Expr *> Elements, QualType T,28ObjCMethodDecl *Method, SourceRange SR)29: Expr(ObjCArrayLiteralClass, T, VK_PRValue, OK_Ordinary),30NumElements(Elements.size()), Range(SR), ArrayWithObjectsMethod(Method) {31Expr **SaveElements = getElements();32for (unsigned I = 0, N = Elements.size(); I != N; ++I)33SaveElements[I] = Elements[I];3435setDependence(computeDependence(this));36}3738ObjCArrayLiteral *ObjCArrayLiteral::Create(const ASTContext &C,39ArrayRef<Expr *> Elements,40QualType T, ObjCMethodDecl *Method,41SourceRange SR) {42void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(Elements.size()));43return new (Mem) ObjCArrayLiteral(Elements, T, Method, SR);44}4546ObjCArrayLiteral *ObjCArrayLiteral::CreateEmpty(const ASTContext &C,47unsigned NumElements) {48void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(NumElements));49return new (Mem) ObjCArrayLiteral(EmptyShell(), NumElements);50}5152ObjCDictionaryLiteral::ObjCDictionaryLiteral(ArrayRef<ObjCDictionaryElement> VK,53bool HasPackExpansions, QualType T,54ObjCMethodDecl *method,55SourceRange SR)56: Expr(ObjCDictionaryLiteralClass, T, VK_PRValue, OK_Ordinary),57NumElements(VK.size()), HasPackExpansions(HasPackExpansions), Range(SR),58DictWithObjectsMethod(method) {59KeyValuePair *KeyValues = getTrailingObjects<KeyValuePair>();60ExpansionData *Expansions =61HasPackExpansions ? getTrailingObjects<ExpansionData>() : nullptr;62for (unsigned I = 0; I < NumElements; I++) {63KeyValues[I].Key = VK[I].Key;64KeyValues[I].Value = VK[I].Value;65if (Expansions) {66Expansions[I].EllipsisLoc = VK[I].EllipsisLoc;67if (VK[I].NumExpansions)68Expansions[I].NumExpansionsPlusOne = *VK[I].NumExpansions + 1;69else70Expansions[I].NumExpansionsPlusOne = 0;71}72}73setDependence(computeDependence(this));74}7576ObjCDictionaryLiteral *77ObjCDictionaryLiteral::Create(const ASTContext &C,78ArrayRef<ObjCDictionaryElement> VK,79bool HasPackExpansions, QualType T,80ObjCMethodDecl *method, SourceRange SR) {81void *Mem = C.Allocate(totalSizeToAlloc<KeyValuePair, ExpansionData>(82VK.size(), HasPackExpansions ? VK.size() : 0));83return new (Mem) ObjCDictionaryLiteral(VK, HasPackExpansions, T, method, SR);84}8586ObjCDictionaryLiteral *87ObjCDictionaryLiteral::CreateEmpty(const ASTContext &C, unsigned NumElements,88bool HasPackExpansions) {89void *Mem = C.Allocate(totalSizeToAlloc<KeyValuePair, ExpansionData>(90NumElements, HasPackExpansions ? NumElements : 0));91return new (Mem)92ObjCDictionaryLiteral(EmptyShell(), NumElements, HasPackExpansions);93}9495QualType ObjCPropertyRefExpr::getReceiverType(const ASTContext &ctx) const {96if (isClassReceiver())97return ctx.getObjCInterfaceType(getClassReceiver());9899if (isSuperReceiver())100return getSuperReceiverType();101102return getBase()->getType();103}104105ObjCMessageExpr::ObjCMessageExpr(QualType T, ExprValueKind VK,106SourceLocation LBracLoc,107SourceLocation SuperLoc, bool IsInstanceSuper,108QualType SuperType, Selector Sel,109ArrayRef<SourceLocation> SelLocs,110SelectorLocationsKind SelLocsK,111ObjCMethodDecl *Method, ArrayRef<Expr *> Args,112SourceLocation RBracLoc, bool isImplicit)113: Expr(ObjCMessageExprClass, T, VK, OK_Ordinary),114SelectorOrMethod(115reinterpret_cast<uintptr_t>(Method ? Method : Sel.getAsOpaquePtr())),116Kind(IsInstanceSuper ? SuperInstance : SuperClass),117HasMethod(Method != nullptr), IsDelegateInitCall(false),118IsImplicit(isImplicit), SuperLoc(SuperLoc), LBracLoc(LBracLoc),119RBracLoc(RBracLoc) {120initArgsAndSelLocs(Args, SelLocs, SelLocsK);121setReceiverPointer(SuperType.getAsOpaquePtr());122setDependence(computeDependence(this));123}124125ObjCMessageExpr::ObjCMessageExpr(QualType T, ExprValueKind VK,126SourceLocation LBracLoc,127TypeSourceInfo *Receiver, Selector Sel,128ArrayRef<SourceLocation> SelLocs,129SelectorLocationsKind SelLocsK,130ObjCMethodDecl *Method, ArrayRef<Expr *> Args,131SourceLocation RBracLoc, bool isImplicit)132: Expr(ObjCMessageExprClass, T, VK, OK_Ordinary),133SelectorOrMethod(134reinterpret_cast<uintptr_t>(Method ? Method : Sel.getAsOpaquePtr())),135Kind(Class), HasMethod(Method != nullptr), IsDelegateInitCall(false),136IsImplicit(isImplicit), LBracLoc(LBracLoc), RBracLoc(RBracLoc) {137initArgsAndSelLocs(Args, SelLocs, SelLocsK);138setReceiverPointer(Receiver);139setDependence(computeDependence(this));140}141142ObjCMessageExpr::ObjCMessageExpr(QualType T, ExprValueKind VK,143SourceLocation LBracLoc, Expr *Receiver,144Selector Sel, ArrayRef<SourceLocation> SelLocs,145SelectorLocationsKind SelLocsK,146ObjCMethodDecl *Method, ArrayRef<Expr *> Args,147SourceLocation RBracLoc, bool isImplicit)148: Expr(ObjCMessageExprClass, T, VK, OK_Ordinary),149SelectorOrMethod(150reinterpret_cast<uintptr_t>(Method ? Method : Sel.getAsOpaquePtr())),151Kind(Instance), HasMethod(Method != nullptr), IsDelegateInitCall(false),152IsImplicit(isImplicit), LBracLoc(LBracLoc), RBracLoc(RBracLoc) {153initArgsAndSelLocs(Args, SelLocs, SelLocsK);154setReceiverPointer(Receiver);155setDependence(computeDependence(this));156}157158void ObjCMessageExpr::initArgsAndSelLocs(ArrayRef<Expr *> Args,159ArrayRef<SourceLocation> SelLocs,160SelectorLocationsKind SelLocsK) {161setNumArgs(Args.size());162Expr **MyArgs = getArgs();163for (unsigned I = 0; I != Args.size(); ++I)164MyArgs[I] = Args[I];165166SelLocsKind = SelLocsK;167if (!isImplicit()) {168if (SelLocsK == SelLoc_NonStandard)169std::copy(SelLocs.begin(), SelLocs.end(), getStoredSelLocs());170}171}172173ObjCMessageExpr *174ObjCMessageExpr::Create(const ASTContext &Context, QualType T, ExprValueKind VK,175SourceLocation LBracLoc, SourceLocation SuperLoc,176bool IsInstanceSuper, QualType SuperType, Selector Sel,177ArrayRef<SourceLocation> SelLocs,178ObjCMethodDecl *Method, ArrayRef<Expr *> Args,179SourceLocation RBracLoc, bool isImplicit) {180assert((!SelLocs.empty() || isImplicit) &&181"No selector locs for non-implicit message");182ObjCMessageExpr *Mem;183SelectorLocationsKind SelLocsK = SelectorLocationsKind();184if (isImplicit)185Mem = alloc(Context, Args.size(), 0);186else187Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK);188return new (Mem) ObjCMessageExpr(T, VK, LBracLoc, SuperLoc, IsInstanceSuper,189SuperType, Sel, SelLocs, SelLocsK, Method,190Args, RBracLoc, isImplicit);191}192193ObjCMessageExpr *194ObjCMessageExpr::Create(const ASTContext &Context, QualType T, ExprValueKind VK,195SourceLocation LBracLoc, TypeSourceInfo *Receiver,196Selector Sel, ArrayRef<SourceLocation> SelLocs,197ObjCMethodDecl *Method, ArrayRef<Expr *> Args,198SourceLocation RBracLoc, bool isImplicit) {199assert((!SelLocs.empty() || isImplicit) &&200"No selector locs for non-implicit message");201ObjCMessageExpr *Mem;202SelectorLocationsKind SelLocsK = SelectorLocationsKind();203if (isImplicit)204Mem = alloc(Context, Args.size(), 0);205else206Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK);207return new (Mem)208ObjCMessageExpr(T, VK, LBracLoc, Receiver, Sel, SelLocs, SelLocsK, Method,209Args, RBracLoc, isImplicit);210}211212ObjCMessageExpr *213ObjCMessageExpr::Create(const ASTContext &Context, QualType T, ExprValueKind VK,214SourceLocation LBracLoc, Expr *Receiver, Selector Sel,215ArrayRef<SourceLocation> SelLocs,216ObjCMethodDecl *Method, ArrayRef<Expr *> Args,217SourceLocation RBracLoc, bool isImplicit) {218assert((!SelLocs.empty() || isImplicit) &&219"No selector locs for non-implicit message");220ObjCMessageExpr *Mem;221SelectorLocationsKind SelLocsK = SelectorLocationsKind();222if (isImplicit)223Mem = alloc(Context, Args.size(), 0);224else225Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK);226return new (Mem)227ObjCMessageExpr(T, VK, LBracLoc, Receiver, Sel, SelLocs, SelLocsK, Method,228Args, RBracLoc, isImplicit);229}230231ObjCMessageExpr *ObjCMessageExpr::CreateEmpty(const ASTContext &Context,232unsigned NumArgs,233unsigned NumStoredSelLocs) {234ObjCMessageExpr *Mem = alloc(Context, NumArgs, NumStoredSelLocs);235return new (Mem) ObjCMessageExpr(EmptyShell(), NumArgs);236}237238ObjCMessageExpr *ObjCMessageExpr::alloc(const ASTContext &C,239ArrayRef<Expr *> Args,240SourceLocation RBraceLoc,241ArrayRef<SourceLocation> SelLocs,242Selector Sel,243SelectorLocationsKind &SelLocsK) {244SelLocsK = hasStandardSelectorLocs(Sel, SelLocs, Args, RBraceLoc);245unsigned NumStoredSelLocs =246(SelLocsK == SelLoc_NonStandard) ? SelLocs.size() : 0;247return alloc(C, Args.size(), NumStoredSelLocs);248}249250ObjCMessageExpr *ObjCMessageExpr::alloc(const ASTContext &C, unsigned NumArgs,251unsigned NumStoredSelLocs) {252return (ObjCMessageExpr *)C.Allocate(253totalSizeToAlloc<void *, SourceLocation>(NumArgs + 1, NumStoredSelLocs),254alignof(ObjCMessageExpr));255}256257void ObjCMessageExpr::getSelectorLocs(258SmallVectorImpl<SourceLocation> &SelLocs) const {259for (unsigned i = 0, e = getNumSelectorLocs(); i != e; ++i)260SelLocs.push_back(getSelectorLoc(i));261}262263264QualType ObjCMessageExpr::getCallReturnType(ASTContext &Ctx) const {265if (const ObjCMethodDecl *MD = getMethodDecl()) {266QualType QT = MD->getReturnType();267if (QT == Ctx.getObjCInstanceType()) {268// instancetype corresponds to expression types.269return getType();270}271return QT;272}273return Ctx.getReferenceQualifiedType(this);274}275276SourceRange ObjCMessageExpr::getReceiverRange() const {277switch (getReceiverKind()) {278case Instance:279return getInstanceReceiver()->getSourceRange();280281case Class:282return getClassReceiverTypeInfo()->getTypeLoc().getSourceRange();283284case SuperInstance:285case SuperClass:286return getSuperLoc();287}288289llvm_unreachable("Invalid ReceiverKind!");290}291292Selector ObjCMessageExpr::getSelector() const {293if (HasMethod)294return reinterpret_cast<const ObjCMethodDecl *>(SelectorOrMethod)295->getSelector();296return Selector(SelectorOrMethod);297}298299QualType ObjCMessageExpr::getReceiverType() const {300switch (getReceiverKind()) {301case Instance:302return getInstanceReceiver()->getType();303case Class:304return getClassReceiver();305case SuperInstance:306case SuperClass:307return getSuperType();308}309310llvm_unreachable("unexpected receiver kind");311}312313ObjCInterfaceDecl *ObjCMessageExpr::getReceiverInterface() const {314QualType T = getReceiverType();315316if (const ObjCObjectPointerType *Ptr = T->getAs<ObjCObjectPointerType>())317return Ptr->getInterfaceDecl();318319if (const ObjCObjectType *Ty = T->getAs<ObjCObjectType>())320return Ty->getInterface();321322return nullptr;323}324325Stmt::child_range ObjCMessageExpr::children() {326Stmt **begin;327if (getReceiverKind() == Instance)328begin = reinterpret_cast<Stmt **>(getTrailingObjects<void *>());329else330begin = reinterpret_cast<Stmt **>(getArgs());331return child_range(begin,332reinterpret_cast<Stmt **>(getArgs() + getNumArgs()));333}334335Stmt::const_child_range ObjCMessageExpr::children() const {336auto Children = const_cast<ObjCMessageExpr *>(this)->children();337return const_child_range(Children.begin(), Children.end());338}339340StringRef ObjCBridgedCastExpr::getBridgeKindName() const {341switch (getBridgeKind()) {342case OBC_Bridge:343return "__bridge";344case OBC_BridgeTransfer:345return "__bridge_transfer";346case OBC_BridgeRetained:347return "__bridge_retained";348}349350llvm_unreachable("Invalid BridgeKind!");351}352353354