1 //===--- ExprObjC.cpp - (ObjC) Expression AST Node Implementation ---------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file implements the subclesses of Expr class declared in ExprObjC.h 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "clang/AST/ExprObjC.h" 15 16 #include "clang/AST/ASTContext.h" 17 18 using namespace clang; 19 20 ObjCArrayLiteral::ObjCArrayLiteral(ArrayRef<Expr *> Elements, QualType T, 21 ObjCMethodDecl *Method, SourceRange SR) 22 : Expr(ObjCArrayLiteralClass, T, VK_RValue, OK_Ordinary, false, false, 23 false, false), 24 NumElements(Elements.size()), Range(SR), ArrayWithObjectsMethod(Method) { 25 Expr **SaveElements = getElements(); 26 for (unsigned I = 0, N = Elements.size(); I != N; ++I) { 27 if (Elements[I]->isTypeDependent() || Elements[I]->isValueDependent()) 28 ExprBits.ValueDependent = true; 29 if (Elements[I]->isInstantiationDependent()) 30 ExprBits.InstantiationDependent = true; 31 if (Elements[I]->containsUnexpandedParameterPack()) 32 ExprBits.ContainsUnexpandedParameterPack = true; 33 34 SaveElements[I] = Elements[I]; 35 } 36 } 37 38 ObjCArrayLiteral *ObjCArrayLiteral::Create(const ASTContext &C, 39 ArrayRef<Expr *> Elements, 40 QualType T, ObjCMethodDecl *Method, 41 SourceRange SR) { 42 void *Mem = 43 C.Allocate(sizeof(ObjCArrayLiteral) + Elements.size() * sizeof(Expr *)); 44 return new (Mem) ObjCArrayLiteral(Elements, T, Method, SR); 45 } 46 47 ObjCArrayLiteral *ObjCArrayLiteral::CreateEmpty(const ASTContext &C, 48 unsigned NumElements) { 49 50 void *Mem = 51 C.Allocate(sizeof(ObjCArrayLiteral) + NumElements * sizeof(Expr *)); 52 return new (Mem) ObjCArrayLiteral(EmptyShell(), NumElements); 53 } 54 55 ObjCDictionaryLiteral::ObjCDictionaryLiteral(ArrayRef<ObjCDictionaryElement> VK, 56 bool HasPackExpansions, QualType T, 57 ObjCMethodDecl *method, 58 SourceRange SR) 59 : Expr(ObjCDictionaryLiteralClass, T, VK_RValue, OK_Ordinary, false, false, 60 false, false), 61 NumElements(VK.size()), HasPackExpansions(HasPackExpansions), Range(SR), 62 DictWithObjectsMethod(method) { 63 KeyValuePair *KeyValues = getKeyValues(); 64 ExpansionData *Expansions = getExpansionData(); 65 for (unsigned I = 0; I < NumElements; I++) { 66 if (VK[I].Key->isTypeDependent() || VK[I].Key->isValueDependent() || 67 VK[I].Value->isTypeDependent() || VK[I].Value->isValueDependent()) 68 ExprBits.ValueDependent = true; 69 if (VK[I].Key->isInstantiationDependent() || 70 VK[I].Value->isInstantiationDependent()) 71 ExprBits.InstantiationDependent = true; 72 if (VK[I].EllipsisLoc.isInvalid() && 73 (VK[I].Key->containsUnexpandedParameterPack() || 74 VK[I].Value->containsUnexpandedParameterPack())) 75 ExprBits.ContainsUnexpandedParameterPack = true; 76 77 KeyValues[I].Key = VK[I].Key; 78 KeyValues[I].Value = VK[I].Value; 79 if (Expansions) { 80 Expansions[I].EllipsisLoc = VK[I].EllipsisLoc; 81 if (VK[I].NumExpansions) 82 Expansions[I].NumExpansionsPlusOne = *VK[I].NumExpansions + 1; 83 else 84 Expansions[I].NumExpansionsPlusOne = 0; 85 } 86 } 87 } 88 89 ObjCDictionaryLiteral * 90 ObjCDictionaryLiteral::Create(const ASTContext &C, 91 ArrayRef<ObjCDictionaryElement> VK, 92 bool HasPackExpansions, QualType T, 93 ObjCMethodDecl *method, SourceRange SR) { 94 unsigned ExpansionsSize = 0; 95 if (HasPackExpansions) 96 ExpansionsSize = sizeof(ExpansionData) * VK.size(); 97 98 void *Mem = C.Allocate(sizeof(ObjCDictionaryLiteral) + 99 sizeof(KeyValuePair) * VK.size() + ExpansionsSize); 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 unsigned ExpansionsSize = 0; 107 if (HasPackExpansions) 108 ExpansionsSize = sizeof(ExpansionData) * NumElements; 109 void *Mem = C.Allocate(sizeof(ObjCDictionaryLiteral) + 110 sizeof(KeyValuePair) * NumElements + ExpansionsSize); 111 return new (Mem) 112 ObjCDictionaryLiteral(EmptyShell(), NumElements, HasPackExpansions); 113 } 114 115 QualType ObjCPropertyRefExpr::getReceiverType(const ASTContext &ctx) const { 116 if (isClassReceiver()) 117 return ctx.getObjCInterfaceType(getClassReceiver()); 118 119 if (isSuperReceiver()) 120 return getSuperReceiverType(); 121 122 return getBase()->getType(); 123 } 124 125 ObjCSubscriptRefExpr * 126 ObjCSubscriptRefExpr::Create(const ASTContext &C, Expr *base, Expr *key, 127 QualType T, ObjCMethodDecl *getMethod, 128 ObjCMethodDecl *setMethod, SourceLocation RB) { 129 void *Mem = C.Allocate(sizeof(ObjCSubscriptRefExpr)); 130 return new (Mem) ObjCSubscriptRefExpr( 131 base, key, T, VK_LValue, OK_ObjCSubscript, getMethod, setMethod, RB); 132 } 133 134 ObjCMessageExpr::ObjCMessageExpr(QualType T, ExprValueKind VK, 135 SourceLocation LBracLoc, 136 SourceLocation SuperLoc, bool IsInstanceSuper, 137 QualType SuperType, Selector Sel, 138 ArrayRef<SourceLocation> SelLocs, 139 SelectorLocationsKind SelLocsK, 140 ObjCMethodDecl *Method, ArrayRef<Expr *> Args, 141 SourceLocation RBracLoc, bool isImplicit) 142 : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary, 143 /*TypeDependent=*/false, /*ValueDependent=*/false, 144 /*InstantiationDependent=*/false, 145 /*ContainsUnexpandedParameterPack=*/false), 146 SelectorOrMethod( 147 reinterpret_cast<uintptr_t>(Method ? Method : Sel.getAsOpaquePtr())), 148 Kind(IsInstanceSuper ? SuperInstance : SuperClass), 149 HasMethod(Method != nullptr), IsDelegateInitCall(false), 150 IsImplicit(isImplicit), SuperLoc(SuperLoc), LBracLoc(LBracLoc), 151 RBracLoc(RBracLoc) { 152 initArgsAndSelLocs(Args, SelLocs, SelLocsK); 153 setReceiverPointer(SuperType.getAsOpaquePtr()); 154 } 155 156 ObjCMessageExpr::ObjCMessageExpr(QualType T, ExprValueKind VK, 157 SourceLocation LBracLoc, 158 TypeSourceInfo *Receiver, Selector Sel, 159 ArrayRef<SourceLocation> SelLocs, 160 SelectorLocationsKind SelLocsK, 161 ObjCMethodDecl *Method, ArrayRef<Expr *> Args, 162 SourceLocation RBracLoc, bool isImplicit) 163 : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary, T->isDependentType(), 164 T->isDependentType(), T->isInstantiationDependentType(), 165 T->containsUnexpandedParameterPack()), 166 SelectorOrMethod( 167 reinterpret_cast<uintptr_t>(Method ? Method : Sel.getAsOpaquePtr())), 168 Kind(Class), HasMethod(Method != nullptr), IsDelegateInitCall(false), 169 IsImplicit(isImplicit), LBracLoc(LBracLoc), RBracLoc(RBracLoc) { 170 initArgsAndSelLocs(Args, SelLocs, SelLocsK); 171 setReceiverPointer(Receiver); 172 } 173 174 ObjCMessageExpr::ObjCMessageExpr(QualType T, ExprValueKind VK, 175 SourceLocation LBracLoc, Expr *Receiver, 176 Selector Sel, ArrayRef<SourceLocation> SelLocs, 177 SelectorLocationsKind SelLocsK, 178 ObjCMethodDecl *Method, ArrayRef<Expr *> Args, 179 SourceLocation RBracLoc, bool isImplicit) 180 : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary, 181 Receiver->isTypeDependent(), Receiver->isTypeDependent(), 182 Receiver->isInstantiationDependent(), 183 Receiver->containsUnexpandedParameterPack()), 184 SelectorOrMethod( 185 reinterpret_cast<uintptr_t>(Method ? Method : Sel.getAsOpaquePtr())), 186 Kind(Instance), HasMethod(Method != nullptr), IsDelegateInitCall(false), 187 IsImplicit(isImplicit), LBracLoc(LBracLoc), RBracLoc(RBracLoc) { 188 initArgsAndSelLocs(Args, SelLocs, SelLocsK); 189 setReceiverPointer(Receiver); 190 } 191 192 void ObjCMessageExpr::initArgsAndSelLocs(ArrayRef<Expr *> Args, 193 ArrayRef<SourceLocation> SelLocs, 194 SelectorLocationsKind SelLocsK) { 195 setNumArgs(Args.size()); 196 Expr **MyArgs = getArgs(); 197 for (unsigned I = 0; I != Args.size(); ++I) { 198 if (Args[I]->isTypeDependent()) 199 ExprBits.TypeDependent = true; 200 if (Args[I]->isValueDependent()) 201 ExprBits.ValueDependent = true; 202 if (Args[I]->isInstantiationDependent()) 203 ExprBits.InstantiationDependent = true; 204 if (Args[I]->containsUnexpandedParameterPack()) 205 ExprBits.ContainsUnexpandedParameterPack = true; 206 207 MyArgs[I] = Args[I]; 208 } 209 210 SelLocsKind = SelLocsK; 211 if (!isImplicit()) { 212 if (SelLocsK == SelLoc_NonStandard) 213 std::copy(SelLocs.begin(), SelLocs.end(), getStoredSelLocs()); 214 } 215 } 216 217 ObjCMessageExpr * 218 ObjCMessageExpr::Create(const ASTContext &Context, QualType T, ExprValueKind VK, 219 SourceLocation LBracLoc, SourceLocation SuperLoc, 220 bool IsInstanceSuper, QualType SuperType, Selector Sel, 221 ArrayRef<SourceLocation> SelLocs, 222 ObjCMethodDecl *Method, ArrayRef<Expr *> Args, 223 SourceLocation RBracLoc, bool isImplicit) { 224 assert((!SelLocs.empty() || isImplicit) && 225 "No selector locs for non-implicit message"); 226 ObjCMessageExpr *Mem; 227 SelectorLocationsKind SelLocsK = SelectorLocationsKind(); 228 if (isImplicit) 229 Mem = alloc(Context, Args.size(), 0); 230 else 231 Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK); 232 return new (Mem) ObjCMessageExpr(T, VK, LBracLoc, SuperLoc, IsInstanceSuper, 233 SuperType, Sel, SelLocs, SelLocsK, Method, 234 Args, RBracLoc, isImplicit); 235 } 236 237 ObjCMessageExpr * 238 ObjCMessageExpr::Create(const ASTContext &Context, QualType T, ExprValueKind VK, 239 SourceLocation LBracLoc, TypeSourceInfo *Receiver, 240 Selector Sel, ArrayRef<SourceLocation> SelLocs, 241 ObjCMethodDecl *Method, ArrayRef<Expr *> Args, 242 SourceLocation RBracLoc, bool isImplicit) { 243 assert((!SelLocs.empty() || isImplicit) && 244 "No selector locs for non-implicit message"); 245 ObjCMessageExpr *Mem; 246 SelectorLocationsKind SelLocsK = SelectorLocationsKind(); 247 if (isImplicit) 248 Mem = alloc(Context, Args.size(), 0); 249 else 250 Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK); 251 return new (Mem) 252 ObjCMessageExpr(T, VK, LBracLoc, Receiver, Sel, SelLocs, SelLocsK, Method, 253 Args, RBracLoc, isImplicit); 254 } 255 256 ObjCMessageExpr * 257 ObjCMessageExpr::Create(const ASTContext &Context, QualType T, ExprValueKind VK, 258 SourceLocation LBracLoc, Expr *Receiver, Selector Sel, 259 ArrayRef<SourceLocation> SelLocs, 260 ObjCMethodDecl *Method, ArrayRef<Expr *> Args, 261 SourceLocation RBracLoc, bool isImplicit) { 262 assert((!SelLocs.empty() || isImplicit) && 263 "No selector locs for non-implicit message"); 264 ObjCMessageExpr *Mem; 265 SelectorLocationsKind SelLocsK = SelectorLocationsKind(); 266 if (isImplicit) 267 Mem = alloc(Context, Args.size(), 0); 268 else 269 Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK); 270 return new (Mem) 271 ObjCMessageExpr(T, VK, LBracLoc, Receiver, Sel, SelLocs, SelLocsK, Method, 272 Args, RBracLoc, isImplicit); 273 } 274 275 ObjCMessageExpr *ObjCMessageExpr::CreateEmpty(const ASTContext &Context, 276 unsigned NumArgs, 277 unsigned NumStoredSelLocs) { 278 ObjCMessageExpr *Mem = alloc(Context, NumArgs, NumStoredSelLocs); 279 return new (Mem) ObjCMessageExpr(EmptyShell(), NumArgs); 280 } 281 282 ObjCMessageExpr *ObjCMessageExpr::alloc(const ASTContext &C, 283 ArrayRef<Expr *> Args, 284 SourceLocation RBraceLoc, 285 ArrayRef<SourceLocation> SelLocs, 286 Selector Sel, 287 SelectorLocationsKind &SelLocsK) { 288 SelLocsK = hasStandardSelectorLocs(Sel, SelLocs, Args, RBraceLoc); 289 unsigned NumStoredSelLocs = 290 (SelLocsK == SelLoc_NonStandard) ? SelLocs.size() : 0; 291 return alloc(C, Args.size(), NumStoredSelLocs); 292 } 293 294 ObjCMessageExpr *ObjCMessageExpr::alloc(const ASTContext &C, unsigned NumArgs, 295 unsigned NumStoredSelLocs) { 296 unsigned Size = sizeof(ObjCMessageExpr) + sizeof(void *) + 297 NumArgs * sizeof(Expr *) + 298 NumStoredSelLocs * sizeof(SourceLocation); 299 return (ObjCMessageExpr *)C.Allocate( 300 Size, llvm::AlignOf<ObjCMessageExpr>::Alignment); 301 } 302 303 void ObjCMessageExpr::getSelectorLocs( 304 SmallVectorImpl<SourceLocation> &SelLocs) const { 305 for (unsigned i = 0, e = getNumSelectorLocs(); i != e; ++i) 306 SelLocs.push_back(getSelectorLoc(i)); 307 } 308 309 SourceRange ObjCMessageExpr::getReceiverRange() const { 310 switch (getReceiverKind()) { 311 case Instance: 312 return getInstanceReceiver()->getSourceRange(); 313 314 case Class: 315 return getClassReceiverTypeInfo()->getTypeLoc().getSourceRange(); 316 317 case SuperInstance: 318 case SuperClass: 319 return getSuperLoc(); 320 } 321 322 llvm_unreachable("Invalid ReceiverKind!"); 323 } 324 325 Selector ObjCMessageExpr::getSelector() const { 326 if (HasMethod) 327 return reinterpret_cast<const ObjCMethodDecl *>(SelectorOrMethod) 328 ->getSelector(); 329 return Selector(SelectorOrMethod); 330 } 331 332 QualType ObjCMessageExpr::getReceiverType() const { 333 switch (getReceiverKind()) { 334 case Instance: 335 return getInstanceReceiver()->getType(); 336 case Class: 337 return getClassReceiver(); 338 case SuperInstance: 339 case SuperClass: 340 return getSuperType(); 341 } 342 343 llvm_unreachable("unexpected receiver kind"); 344 } 345 346 ObjCInterfaceDecl *ObjCMessageExpr::getReceiverInterface() const { 347 QualType T = getReceiverType(); 348 349 if (const ObjCObjectPointerType *Ptr = T->getAs<ObjCObjectPointerType>()) 350 return Ptr->getInterfaceDecl(); 351 352 if (const ObjCObjectType *Ty = T->getAs<ObjCObjectType>()) 353 return Ty->getInterface(); 354 355 return nullptr; 356 } 357 358 Stmt::child_range ObjCMessageExpr::children() { 359 Stmt **begin; 360 if (getReceiverKind() == Instance) 361 begin = reinterpret_cast<Stmt **>(this + 1); 362 else 363 begin = reinterpret_cast<Stmt **>(getArgs()); 364 return child_range(begin, 365 reinterpret_cast<Stmt **>(getArgs() + getNumArgs())); 366 } 367 368 StringRef ObjCBridgedCastExpr::getBridgeKindName() const { 369 switch (getBridgeKind()) { 370 case OBC_Bridge: 371 return "__bridge"; 372 case OBC_BridgeTransfer: 373 return "__bridge_transfer"; 374 case OBC_BridgeRetained: 375 return "__bridge_retained"; 376 } 377 378 llvm_unreachable("Invalid BridgeKind!"); 379 } 380