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