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