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/ComputeDependence.h" 16 #include "clang/AST/SelectorLocationsKind.h" 17 #include "clang/AST/Type.h" 18 #include "clang/AST/TypeLoc.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_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 37 ObjCArrayLiteral *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 45 ObjCArrayLiteral *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 51 ObjCDictionaryLiteral::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 else 69 Expansions[I].NumExpansionsPlusOne = 0; 70 } 71 } 72 setDependence(computeDependence(this)); 73 } 74 75 ObjCDictionaryLiteral * 76 ObjCDictionaryLiteral::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 85 ObjCDictionaryLiteral * 86 ObjCDictionaryLiteral::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 94 QualType 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 104 ObjCMessageExpr::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 124 ObjCMessageExpr::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 141 ObjCMessageExpr::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 157 void 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()) { 167 if (SelLocsK == SelLoc_NonStandard) 168 std::copy(SelLocs.begin(), SelLocs.end(), getStoredSelLocs()); 169 } 170 } 171 172 ObjCMessageExpr * 173 ObjCMessageExpr::Create(const ASTContext &Context, QualType T, ExprValueKind VK, 174 SourceLocation LBracLoc, SourceLocation SuperLoc, 175 bool IsInstanceSuper, QualType SuperType, Selector Sel, 176 ArrayRef<SourceLocation> SelLocs, 177 ObjCMethodDecl *Method, ArrayRef<Expr *> Args, 178 SourceLocation RBracLoc, bool isImplicit) { 179 assert((!SelLocs.empty() || isImplicit) && 180 "No selector locs for non-implicit message"); 181 ObjCMessageExpr *Mem; 182 SelectorLocationsKind SelLocsK = SelectorLocationsKind(); 183 if (isImplicit) 184 Mem = alloc(Context, Args.size(), 0); 185 else 186 Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK); 187 return new (Mem) ObjCMessageExpr(T, VK, LBracLoc, SuperLoc, IsInstanceSuper, 188 SuperType, Sel, SelLocs, SelLocsK, Method, 189 Args, RBracLoc, isImplicit); 190 } 191 192 ObjCMessageExpr * 193 ObjCMessageExpr::Create(const ASTContext &Context, QualType T, ExprValueKind VK, 194 SourceLocation LBracLoc, TypeSourceInfo *Receiver, 195 Selector Sel, ArrayRef<SourceLocation> SelLocs, 196 ObjCMethodDecl *Method, ArrayRef<Expr *> Args, 197 SourceLocation RBracLoc, bool isImplicit) { 198 assert((!SelLocs.empty() || isImplicit) && 199 "No selector locs for non-implicit message"); 200 ObjCMessageExpr *Mem; 201 SelectorLocationsKind SelLocsK = SelectorLocationsKind(); 202 if (isImplicit) 203 Mem = alloc(Context, Args.size(), 0); 204 else 205 Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK); 206 return new (Mem) 207 ObjCMessageExpr(T, VK, LBracLoc, Receiver, Sel, SelLocs, SelLocsK, Method, 208 Args, RBracLoc, isImplicit); 209 } 210 211 ObjCMessageExpr * 212 ObjCMessageExpr::Create(const ASTContext &Context, QualType T, ExprValueKind VK, 213 SourceLocation LBracLoc, Expr *Receiver, Selector Sel, 214 ArrayRef<SourceLocation> SelLocs, 215 ObjCMethodDecl *Method, ArrayRef<Expr *> Args, 216 SourceLocation RBracLoc, bool isImplicit) { 217 assert((!SelLocs.empty() || isImplicit) && 218 "No selector locs for non-implicit message"); 219 ObjCMessageExpr *Mem; 220 SelectorLocationsKind SelLocsK = SelectorLocationsKind(); 221 if (isImplicit) 222 Mem = alloc(Context, Args.size(), 0); 223 else 224 Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK); 225 return new (Mem) 226 ObjCMessageExpr(T, VK, LBracLoc, Receiver, Sel, SelLocs, SelLocsK, Method, 227 Args, RBracLoc, isImplicit); 228 } 229 230 ObjCMessageExpr *ObjCMessageExpr::CreateEmpty(const ASTContext &Context, 231 unsigned NumArgs, 232 unsigned NumStoredSelLocs) { 233 ObjCMessageExpr *Mem = alloc(Context, NumArgs, NumStoredSelLocs); 234 return new (Mem) ObjCMessageExpr(EmptyShell(), NumArgs); 235 } 236 237 ObjCMessageExpr *ObjCMessageExpr::alloc(const ASTContext &C, 238 ArrayRef<Expr *> Args, 239 SourceLocation RBraceLoc, 240 ArrayRef<SourceLocation> SelLocs, 241 Selector Sel, 242 SelectorLocationsKind &SelLocsK) { 243 SelLocsK = hasStandardSelectorLocs(Sel, SelLocs, Args, RBraceLoc); 244 unsigned NumStoredSelLocs = 245 (SelLocsK == SelLoc_NonStandard) ? SelLocs.size() : 0; 246 return alloc(C, Args.size(), NumStoredSelLocs); 247 } 248 249 ObjCMessageExpr *ObjCMessageExpr::alloc(const ASTContext &C, unsigned NumArgs, 250 unsigned NumStoredSelLocs) { 251 return (ObjCMessageExpr *)C.Allocate( 252 totalSizeToAlloc<void *, SourceLocation>(NumArgs + 1, NumStoredSelLocs), 253 alignof(ObjCMessageExpr)); 254 } 255 256 void ObjCMessageExpr::getSelectorLocs( 257 SmallVectorImpl<SourceLocation> &SelLocs) const { 258 for (unsigned i = 0, e = getNumSelectorLocs(); i != e; ++i) 259 SelLocs.push_back(getSelectorLoc(i)); 260 } 261 262 263 QualType ObjCMessageExpr::getCallReturnType(ASTContext &Ctx) const { 264 if (const ObjCMethodDecl *MD = getMethodDecl()) { 265 QualType QT = MD->getReturnType(); 266 if (QT == Ctx.getObjCInstanceType()) { 267 // instancetype corresponds to expression types. 268 return getType(); 269 } 270 return QT; 271 } 272 return Ctx.getReferenceQualifiedType(this); 273 } 274 275 SourceRange ObjCMessageExpr::getReceiverRange() const { 276 switch (getReceiverKind()) { 277 case Instance: 278 return getInstanceReceiver()->getSourceRange(); 279 280 case Class: 281 return getClassReceiverTypeInfo()->getTypeLoc().getSourceRange(); 282 283 case SuperInstance: 284 case SuperClass: 285 return getSuperLoc(); 286 } 287 288 llvm_unreachable("Invalid ReceiverKind!"); 289 } 290 291 Selector ObjCMessageExpr::getSelector() const { 292 if (HasMethod) 293 return reinterpret_cast<const ObjCMethodDecl *>(SelectorOrMethod) 294 ->getSelector(); 295 return Selector(SelectorOrMethod); 296 } 297 298 QualType ObjCMessageExpr::getReceiverType() const { 299 switch (getReceiverKind()) { 300 case Instance: 301 return getInstanceReceiver()->getType(); 302 case Class: 303 return getClassReceiver(); 304 case SuperInstance: 305 case SuperClass: 306 return getSuperType(); 307 } 308 309 llvm_unreachable("unexpected receiver kind"); 310 } 311 312 ObjCInterfaceDecl *ObjCMessageExpr::getReceiverInterface() const { 313 QualType T = getReceiverType(); 314 315 if (const ObjCObjectPointerType *Ptr = T->getAs<ObjCObjectPointerType>()) 316 return Ptr->getInterfaceDecl(); 317 318 if (const ObjCObjectType *Ty = T->getAs<ObjCObjectType>()) 319 return Ty->getInterface(); 320 321 return nullptr; 322 } 323 324 Stmt::child_range ObjCMessageExpr::children() { 325 Stmt **begin; 326 if (getReceiverKind() == Instance) 327 begin = reinterpret_cast<Stmt **>(getTrailingObjects<void *>()); 328 else 329 begin = reinterpret_cast<Stmt **>(getArgs()); 330 return child_range(begin, 331 reinterpret_cast<Stmt **>(getArgs() + getNumArgs())); 332 } 333 334 Stmt::const_child_range ObjCMessageExpr::children() const { 335 auto Children = const_cast<ObjCMessageExpr *>(this)->children(); 336 return const_child_range(Children.begin(), Children.end()); 337 } 338 339 StringRef ObjCBridgedCastExpr::getBridgeKindName() const { 340 switch (getBridgeKind()) { 341 case OBC_Bridge: 342 return "__bridge"; 343 case OBC_BridgeTransfer: 344 return "__bridge_transfer"; 345 case OBC_BridgeRetained: 346 return "__bridge_retained"; 347 } 348 349 llvm_unreachable("Invalid BridgeKind!"); 350 } 351