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 #include "clang/AST/ASTContext.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 if (Elements[I]->isTypeDependent() || Elements[I]->isValueDependent()) 35 ExprBits.ValueDependent = true; 36 if (Elements[I]->isInstantiationDependent()) 37 ExprBits.InstantiationDependent = true; 38 if (Elements[I]->containsUnexpandedParameterPack()) 39 ExprBits.ContainsUnexpandedParameterPack = true; 40 41 SaveElements[I] = Elements[I]; 42 } 43 } 44 45 ObjCArrayLiteral *ObjCArrayLiteral::Create(const ASTContext &C, 46 ArrayRef<Expr *> Elements, 47 QualType T, ObjCMethodDecl *Method, 48 SourceRange SR) { 49 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(Elements.size())); 50 return new (Mem) ObjCArrayLiteral(Elements, T, Method, SR); 51 } 52 53 ObjCArrayLiteral *ObjCArrayLiteral::CreateEmpty(const ASTContext &C, 54 unsigned NumElements) { 55 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(NumElements)); 56 return new (Mem) ObjCArrayLiteral(EmptyShell(), NumElements); 57 } 58 59 ObjCDictionaryLiteral::ObjCDictionaryLiteral(ArrayRef<ObjCDictionaryElement> VK, 60 bool HasPackExpansions, QualType T, 61 ObjCMethodDecl *method, 62 SourceRange SR) 63 : Expr(ObjCDictionaryLiteralClass, T, VK_RValue, OK_Ordinary, false, false, 64 false, false), 65 NumElements(VK.size()), HasPackExpansions(HasPackExpansions), Range(SR), 66 DictWithObjectsMethod(method) { 67 KeyValuePair *KeyValues = getTrailingObjects<KeyValuePair>(); 68 ExpansionData *Expansions = 69 HasPackExpansions ? getTrailingObjects<ExpansionData>() : nullptr; 70 for (unsigned I = 0; I < NumElements; I++) { 71 if (VK[I].Key->isTypeDependent() || VK[I].Key->isValueDependent() || 72 VK[I].Value->isTypeDependent() || VK[I].Value->isValueDependent()) 73 ExprBits.ValueDependent = true; 74 if (VK[I].Key->isInstantiationDependent() || 75 VK[I].Value->isInstantiationDependent()) 76 ExprBits.InstantiationDependent = true; 77 if (VK[I].EllipsisLoc.isInvalid() && 78 (VK[I].Key->containsUnexpandedParameterPack() || 79 VK[I].Value->containsUnexpandedParameterPack())) 80 ExprBits.ContainsUnexpandedParameterPack = true; 81 82 KeyValues[I].Key = VK[I].Key; 83 KeyValues[I].Value = VK[I].Value; 84 if (Expansions) { 85 Expansions[I].EllipsisLoc = VK[I].EllipsisLoc; 86 if (VK[I].NumExpansions) 87 Expansions[I].NumExpansionsPlusOne = *VK[I].NumExpansions + 1; 88 else 89 Expansions[I].NumExpansionsPlusOne = 0; 90 } 91 } 92 } 93 94 ObjCDictionaryLiteral * 95 ObjCDictionaryLiteral::Create(const ASTContext &C, 96 ArrayRef<ObjCDictionaryElement> VK, 97 bool HasPackExpansions, QualType T, 98 ObjCMethodDecl *method, SourceRange SR) { 99 void *Mem = C.Allocate(totalSizeToAlloc<KeyValuePair, ExpansionData>( 100 VK.size(), HasPackExpansions ? VK.size() : 0)); 101 return new (Mem) ObjCDictionaryLiteral(VK, HasPackExpansions, T, method, SR); 102 } 103 104 ObjCDictionaryLiteral * 105 ObjCDictionaryLiteral::CreateEmpty(const ASTContext &C, unsigned NumElements, 106 bool HasPackExpansions) { 107 void *Mem = C.Allocate(totalSizeToAlloc<KeyValuePair, ExpansionData>( 108 NumElements, HasPackExpansions ? NumElements : 0)); 109 return new (Mem) 110 ObjCDictionaryLiteral(EmptyShell(), NumElements, HasPackExpansions); 111 } 112 113 QualType ObjCPropertyRefExpr::getReceiverType(const ASTContext &ctx) const { 114 if (isClassReceiver()) 115 return ctx.getObjCInterfaceType(getClassReceiver()); 116 117 if (isSuperReceiver()) 118 return getSuperReceiverType(); 119 120 return getBase()->getType(); 121 } 122 123 ObjCMessageExpr::ObjCMessageExpr(QualType T, ExprValueKind VK, 124 SourceLocation LBracLoc, 125 SourceLocation SuperLoc, bool IsInstanceSuper, 126 QualType SuperType, Selector Sel, 127 ArrayRef<SourceLocation> SelLocs, 128 SelectorLocationsKind SelLocsK, 129 ObjCMethodDecl *Method, ArrayRef<Expr *> Args, 130 SourceLocation RBracLoc, bool isImplicit) 131 : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary, 132 /*TypeDependent=*/false, /*ValueDependent=*/false, 133 /*InstantiationDependent=*/false, 134 /*ContainsUnexpandedParameterPack=*/false), 135 SelectorOrMethod( 136 reinterpret_cast<uintptr_t>(Method ? Method : Sel.getAsOpaquePtr())), 137 Kind(IsInstanceSuper ? SuperInstance : SuperClass), 138 HasMethod(Method != nullptr), IsDelegateInitCall(false), 139 IsImplicit(isImplicit), SuperLoc(SuperLoc), LBracLoc(LBracLoc), 140 RBracLoc(RBracLoc) { 141 initArgsAndSelLocs(Args, SelLocs, SelLocsK); 142 setReceiverPointer(SuperType.getAsOpaquePtr()); 143 } 144 145 ObjCMessageExpr::ObjCMessageExpr(QualType T, ExprValueKind VK, 146 SourceLocation LBracLoc, 147 TypeSourceInfo *Receiver, Selector Sel, 148 ArrayRef<SourceLocation> SelLocs, 149 SelectorLocationsKind SelLocsK, 150 ObjCMethodDecl *Method, ArrayRef<Expr *> Args, 151 SourceLocation RBracLoc, bool isImplicit) 152 : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary, T->isDependentType(), 153 T->isDependentType(), T->isInstantiationDependentType(), 154 T->containsUnexpandedParameterPack()), 155 SelectorOrMethod( 156 reinterpret_cast<uintptr_t>(Method ? Method : Sel.getAsOpaquePtr())), 157 Kind(Class), HasMethod(Method != nullptr), IsDelegateInitCall(false), 158 IsImplicit(isImplicit), LBracLoc(LBracLoc), RBracLoc(RBracLoc) { 159 initArgsAndSelLocs(Args, SelLocs, SelLocsK); 160 setReceiverPointer(Receiver); 161 } 162 163 ObjCMessageExpr::ObjCMessageExpr(QualType T, ExprValueKind VK, 164 SourceLocation LBracLoc, Expr *Receiver, 165 Selector Sel, ArrayRef<SourceLocation> SelLocs, 166 SelectorLocationsKind SelLocsK, 167 ObjCMethodDecl *Method, ArrayRef<Expr *> Args, 168 SourceLocation RBracLoc, bool isImplicit) 169 : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary, 170 Receiver->isTypeDependent(), Receiver->isTypeDependent(), 171 Receiver->isInstantiationDependent(), 172 Receiver->containsUnexpandedParameterPack()), 173 SelectorOrMethod( 174 reinterpret_cast<uintptr_t>(Method ? Method : Sel.getAsOpaquePtr())), 175 Kind(Instance), HasMethod(Method != nullptr), IsDelegateInitCall(false), 176 IsImplicit(isImplicit), LBracLoc(LBracLoc), RBracLoc(RBracLoc) { 177 initArgsAndSelLocs(Args, SelLocs, SelLocsK); 178 setReceiverPointer(Receiver); 179 } 180 181 void ObjCMessageExpr::initArgsAndSelLocs(ArrayRef<Expr *> Args, 182 ArrayRef<SourceLocation> SelLocs, 183 SelectorLocationsKind SelLocsK) { 184 setNumArgs(Args.size()); 185 Expr **MyArgs = getArgs(); 186 for (unsigned I = 0; I != Args.size(); ++I) { 187 if (Args[I]->isTypeDependent()) 188 ExprBits.TypeDependent = true; 189 if (Args[I]->isValueDependent()) 190 ExprBits.ValueDependent = true; 191 if (Args[I]->isInstantiationDependent()) 192 ExprBits.InstantiationDependent = true; 193 if (Args[I]->containsUnexpandedParameterPack()) 194 ExprBits.ContainsUnexpandedParameterPack = true; 195 196 MyArgs[I] = Args[I]; 197 } 198 199 SelLocsKind = SelLocsK; 200 if (!isImplicit()) { 201 if (SelLocsK == SelLoc_NonStandard) 202 std::copy(SelLocs.begin(), SelLocs.end(), getStoredSelLocs()); 203 } 204 } 205 206 ObjCMessageExpr * 207 ObjCMessageExpr::Create(const ASTContext &Context, QualType T, ExprValueKind VK, 208 SourceLocation LBracLoc, SourceLocation SuperLoc, 209 bool IsInstanceSuper, QualType SuperType, Selector Sel, 210 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) ObjCMessageExpr(T, VK, LBracLoc, SuperLoc, IsInstanceSuper, 222 SuperType, 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, TypeSourceInfo *Receiver, 229 Selector Sel, 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 * 246 ObjCMessageExpr::Create(const ASTContext &Context, QualType T, ExprValueKind VK, 247 SourceLocation LBracLoc, Expr *Receiver, Selector Sel, 248 ArrayRef<SourceLocation> SelLocs, 249 ObjCMethodDecl *Method, ArrayRef<Expr *> Args, 250 SourceLocation RBracLoc, bool isImplicit) { 251 assert((!SelLocs.empty() || isImplicit) && 252 "No selector locs for non-implicit message"); 253 ObjCMessageExpr *Mem; 254 SelectorLocationsKind SelLocsK = SelectorLocationsKind(); 255 if (isImplicit) 256 Mem = alloc(Context, Args.size(), 0); 257 else 258 Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK); 259 return new (Mem) 260 ObjCMessageExpr(T, VK, LBracLoc, Receiver, Sel, SelLocs, SelLocsK, Method, 261 Args, RBracLoc, isImplicit); 262 } 263 264 ObjCMessageExpr *ObjCMessageExpr::CreateEmpty(const ASTContext &Context, 265 unsigned NumArgs, 266 unsigned NumStoredSelLocs) { 267 ObjCMessageExpr *Mem = alloc(Context, NumArgs, NumStoredSelLocs); 268 return new (Mem) ObjCMessageExpr(EmptyShell(), NumArgs); 269 } 270 271 ObjCMessageExpr *ObjCMessageExpr::alloc(const ASTContext &C, 272 ArrayRef<Expr *> Args, 273 SourceLocation RBraceLoc, 274 ArrayRef<SourceLocation> SelLocs, 275 Selector Sel, 276 SelectorLocationsKind &SelLocsK) { 277 SelLocsK = hasStandardSelectorLocs(Sel, SelLocs, Args, RBraceLoc); 278 unsigned NumStoredSelLocs = 279 (SelLocsK == SelLoc_NonStandard) ? SelLocs.size() : 0; 280 return alloc(C, Args.size(), NumStoredSelLocs); 281 } 282 283 ObjCMessageExpr *ObjCMessageExpr::alloc(const ASTContext &C, unsigned NumArgs, 284 unsigned NumStoredSelLocs) { 285 return (ObjCMessageExpr *)C.Allocate( 286 totalSizeToAlloc<void *, SourceLocation>(NumArgs + 1, NumStoredSelLocs), 287 alignof(ObjCMessageExpr)); 288 } 289 290 void ObjCMessageExpr::getSelectorLocs( 291 SmallVectorImpl<SourceLocation> &SelLocs) const { 292 for (unsigned i = 0, e = getNumSelectorLocs(); i != e; ++i) 293 SelLocs.push_back(getSelectorLoc(i)); 294 } 295 296 SourceRange ObjCMessageExpr::getReceiverRange() const { 297 switch (getReceiverKind()) { 298 case Instance: 299 return getInstanceReceiver()->getSourceRange(); 300 301 case Class: 302 return getClassReceiverTypeInfo()->getTypeLoc().getSourceRange(); 303 304 case SuperInstance: 305 case SuperClass: 306 return getSuperLoc(); 307 } 308 309 llvm_unreachable("Invalid ReceiverKind!"); 310 } 311 312 Selector ObjCMessageExpr::getSelector() const { 313 if (HasMethod) 314 return reinterpret_cast<const ObjCMethodDecl *>(SelectorOrMethod) 315 ->getSelector(); 316 return Selector(SelectorOrMethod); 317 } 318 319 QualType ObjCMessageExpr::getReceiverType() const { 320 switch (getReceiverKind()) { 321 case Instance: 322 return getInstanceReceiver()->getType(); 323 case Class: 324 return getClassReceiver(); 325 case SuperInstance: 326 case SuperClass: 327 return getSuperType(); 328 } 329 330 llvm_unreachable("unexpected receiver kind"); 331 } 332 333 ObjCInterfaceDecl *ObjCMessageExpr::getReceiverInterface() const { 334 QualType T = getReceiverType(); 335 336 if (const ObjCObjectPointerType *Ptr = T->getAs<ObjCObjectPointerType>()) 337 return Ptr->getInterfaceDecl(); 338 339 if (const ObjCObjectType *Ty = T->getAs<ObjCObjectType>()) 340 return Ty->getInterface(); 341 342 return nullptr; 343 } 344 345 Stmt::child_range ObjCMessageExpr::children() { 346 Stmt **begin; 347 if (getReceiverKind() == Instance) 348 begin = reinterpret_cast<Stmt **>(getTrailingObjects<void *>()); 349 else 350 begin = reinterpret_cast<Stmt **>(getArgs()); 351 return child_range(begin, 352 reinterpret_cast<Stmt **>(getArgs() + getNumArgs())); 353 } 354 355 StringRef ObjCBridgedCastExpr::getBridgeKindName() const { 356 switch (getBridgeKind()) { 357 case OBC_Bridge: 358 return "__bridge"; 359 case OBC_BridgeTransfer: 360 return "__bridge_transfer"; 361 case OBC_BridgeRetained: 362 return "__bridge_retained"; 363 } 364 365 llvm_unreachable("Invalid BridgeKind!"); 366 } 367