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