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