ExprCXX.cpp revision 208600
1//===--- ExprCXX.cpp - (C++) 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 ExprCXX.h 11// 12//===----------------------------------------------------------------------===// 13 14#include "clang/Basic/IdentifierTable.h" 15#include "clang/AST/DeclCXX.h" 16#include "clang/AST/DeclTemplate.h" 17#include "clang/AST/ExprCXX.h" 18#include "clang/AST/TypeLoc.h" 19using namespace clang; 20 21 22//===----------------------------------------------------------------------===// 23// Child Iterators for iterating over subexpressions/substatements 24//===----------------------------------------------------------------------===// 25 26QualType CXXTypeidExpr::getTypeOperand() const { 27 assert(isTypeOperand() && "Cannot call getTypeOperand for typeid(expr)"); 28 return Operand.get<TypeSourceInfo *>()->getType().getNonReferenceType() 29 .getUnqualifiedType(); 30} 31 32// CXXTypeidExpr - has child iterators if the operand is an expression 33Stmt::child_iterator CXXTypeidExpr::child_begin() { 34 return isTypeOperand() ? child_iterator() 35 : reinterpret_cast<Stmt **>(&Operand); 36} 37Stmt::child_iterator CXXTypeidExpr::child_end() { 38 return isTypeOperand() ? child_iterator() 39 : reinterpret_cast<Stmt **>(&Operand) + 1; 40} 41 42// CXXBoolLiteralExpr 43Stmt::child_iterator CXXBoolLiteralExpr::child_begin() { 44 return child_iterator(); 45} 46Stmt::child_iterator CXXBoolLiteralExpr::child_end() { 47 return child_iterator(); 48} 49 50// CXXNullPtrLiteralExpr 51Stmt::child_iterator CXXNullPtrLiteralExpr::child_begin() { 52 return child_iterator(); 53} 54Stmt::child_iterator CXXNullPtrLiteralExpr::child_end() { 55 return child_iterator(); 56} 57 58// CXXThisExpr 59Stmt::child_iterator CXXThisExpr::child_begin() { return child_iterator(); } 60Stmt::child_iterator CXXThisExpr::child_end() { return child_iterator(); } 61 62// CXXThrowExpr 63Stmt::child_iterator CXXThrowExpr::child_begin() { return &Op; } 64Stmt::child_iterator CXXThrowExpr::child_end() { 65 // If Op is 0, we are processing throw; which has no children. 66 return Op ? &Op+1 : &Op; 67} 68 69// CXXDefaultArgExpr 70Stmt::child_iterator CXXDefaultArgExpr::child_begin() { 71 return child_iterator(); 72} 73Stmt::child_iterator CXXDefaultArgExpr::child_end() { 74 return child_iterator(); 75} 76 77// CXXZeroInitValueExpr 78Stmt::child_iterator CXXZeroInitValueExpr::child_begin() { 79 return child_iterator(); 80} 81Stmt::child_iterator CXXZeroInitValueExpr::child_end() { 82 return child_iterator(); 83} 84 85// CXXNewExpr 86CXXNewExpr::CXXNewExpr(ASTContext &C, bool globalNew, FunctionDecl *operatorNew, 87 Expr **placementArgs, unsigned numPlaceArgs, 88 bool parenTypeId, Expr *arraySize, 89 CXXConstructorDecl *constructor, bool initializer, 90 Expr **constructorArgs, unsigned numConsArgs, 91 FunctionDecl *operatorDelete, QualType ty, 92 SourceLocation startLoc, SourceLocation endLoc) 93 : Expr(CXXNewExprClass, ty, ty->isDependentType(), ty->isDependentType()), 94 GlobalNew(globalNew), ParenTypeId(parenTypeId), 95 Initializer(initializer), SubExprs(0), OperatorNew(operatorNew), 96 OperatorDelete(operatorDelete), Constructor(constructor), 97 StartLoc(startLoc), EndLoc(endLoc) { 98 99 AllocateArgsArray(C, arraySize != 0, numPlaceArgs, numConsArgs); 100 unsigned i = 0; 101 if (Array) 102 SubExprs[i++] = arraySize; 103 for (unsigned j = 0; j < NumPlacementArgs; ++j) 104 SubExprs[i++] = placementArgs[j]; 105 for (unsigned j = 0; j < NumConstructorArgs; ++j) 106 SubExprs[i++] = constructorArgs[j]; 107} 108 109void CXXNewExpr::AllocateArgsArray(ASTContext &C, bool isArray, 110 unsigned numPlaceArgs, unsigned numConsArgs){ 111 assert(SubExprs == 0 && "SubExprs already allocated"); 112 Array = isArray; 113 NumPlacementArgs = numPlaceArgs; 114 NumConstructorArgs = numConsArgs; 115 116 unsigned TotalSize = Array + NumPlacementArgs + NumConstructorArgs; 117 SubExprs = new (C) Stmt*[TotalSize]; 118} 119 120 121void CXXNewExpr::DoDestroy(ASTContext &C) { 122 DestroyChildren(C); 123 if (SubExprs) 124 C.Deallocate(SubExprs); 125 this->~CXXNewExpr(); 126 C.Deallocate((void*)this); 127} 128 129Stmt::child_iterator CXXNewExpr::child_begin() { return &SubExprs[0]; } 130Stmt::child_iterator CXXNewExpr::child_end() { 131 return &SubExprs[0] + Array + getNumPlacementArgs() + getNumConstructorArgs(); 132} 133 134// CXXDeleteExpr 135Stmt::child_iterator CXXDeleteExpr::child_begin() { return &Argument; } 136Stmt::child_iterator CXXDeleteExpr::child_end() { return &Argument+1; } 137 138// CXXPseudoDestructorExpr 139Stmt::child_iterator CXXPseudoDestructorExpr::child_begin() { return &Base; } 140Stmt::child_iterator CXXPseudoDestructorExpr::child_end() { 141 return &Base + 1; 142} 143 144PseudoDestructorTypeStorage::PseudoDestructorTypeStorage(TypeSourceInfo *Info) 145 : Type(Info) 146{ 147 Location = Info->getTypeLoc().getLocalSourceRange().getBegin(); 148} 149 150QualType CXXPseudoDestructorExpr::getDestroyedType() const { 151 if (TypeSourceInfo *TInfo = DestroyedType.getTypeSourceInfo()) 152 return TInfo->getType(); 153 154 return QualType(); 155} 156 157SourceRange CXXPseudoDestructorExpr::getSourceRange() const { 158 SourceLocation End = DestroyedType.getLocation(); 159 if (TypeSourceInfo *TInfo = DestroyedType.getTypeSourceInfo()) 160 End = TInfo->getTypeLoc().getLocalSourceRange().getEnd(); 161 return SourceRange(Base->getLocStart(), End); 162} 163 164 165// UnresolvedLookupExpr 166UnresolvedLookupExpr * 167UnresolvedLookupExpr::Create(ASTContext &C, bool Dependent, 168 CXXRecordDecl *NamingClass, 169 NestedNameSpecifier *Qualifier, 170 SourceRange QualifierRange, DeclarationName Name, 171 SourceLocation NameLoc, bool ADL, 172 const TemplateArgumentListInfo &Args, 173 UnresolvedSetIterator Begin, 174 UnresolvedSetIterator End) 175{ 176 void *Mem = C.Allocate(sizeof(UnresolvedLookupExpr) + 177 ExplicitTemplateArgumentList::sizeFor(Args)); 178 UnresolvedLookupExpr *ULE 179 = new (Mem) UnresolvedLookupExpr(C, 180 Dependent ? C.DependentTy : C.OverloadTy, 181 Dependent, NamingClass, 182 Qualifier, QualifierRange, 183 Name, NameLoc, ADL, 184 /*Overload*/ true, 185 /*ExplicitTemplateArgs*/ true, 186 Begin, End); 187 188 reinterpret_cast<ExplicitTemplateArgumentList*>(ULE+1)->initializeFrom(Args); 189 190 return ULE; 191} 192 193OverloadExpr::OverloadExpr(StmtClass K, ASTContext &C, QualType T, 194 bool Dependent, NestedNameSpecifier *Qualifier, 195 SourceRange QRange, DeclarationName Name, 196 SourceLocation NameLoc, bool HasTemplateArgs, 197 UnresolvedSetIterator Begin, 198 UnresolvedSetIterator End) 199 : Expr(K, T, Dependent, Dependent), 200 Results(0), NumResults(End - Begin), Name(Name), Qualifier(Qualifier), 201 QualifierRange(QRange), NameLoc(NameLoc), 202 HasExplicitTemplateArgs(HasTemplateArgs) 203{ 204 if (NumResults) { 205 Results = static_cast<DeclAccessPair *>( 206 C.Allocate(sizeof(DeclAccessPair) * NumResults, 207 llvm::alignof<DeclAccessPair>())); 208 memcpy(Results, &*Begin.getIterator(), 209 (End - Begin) * sizeof(DeclAccessPair)); 210 } 211} 212 213bool OverloadExpr::ComputeDependence(UnresolvedSetIterator Begin, 214 UnresolvedSetIterator End, 215 const TemplateArgumentListInfo *Args) { 216 for (UnresolvedSetImpl::const_iterator I = Begin; I != End; ++I) 217 if ((*I)->getDeclContext()->isDependentContext()) 218 return true; 219 220 if (Args && TemplateSpecializationType::anyDependentTemplateArguments(*Args)) 221 return true; 222 223 return false; 224} 225 226CXXRecordDecl *OverloadExpr::getNamingClass() const { 227 if (isa<UnresolvedLookupExpr>(this)) 228 return cast<UnresolvedLookupExpr>(this)->getNamingClass(); 229 else 230 return cast<UnresolvedMemberExpr>(this)->getNamingClass(); 231} 232 233Stmt::child_iterator UnresolvedLookupExpr::child_begin() { 234 return child_iterator(); 235} 236Stmt::child_iterator UnresolvedLookupExpr::child_end() { 237 return child_iterator(); 238} 239// UnaryTypeTraitExpr 240Stmt::child_iterator UnaryTypeTraitExpr::child_begin() { 241 return child_iterator(); 242} 243Stmt::child_iterator UnaryTypeTraitExpr::child_end() { 244 return child_iterator(); 245} 246 247// DependentScopeDeclRefExpr 248DependentScopeDeclRefExpr * 249DependentScopeDeclRefExpr::Create(ASTContext &C, 250 NestedNameSpecifier *Qualifier, 251 SourceRange QualifierRange, 252 DeclarationName Name, 253 SourceLocation NameLoc, 254 const TemplateArgumentListInfo *Args) { 255 std::size_t size = sizeof(DependentScopeDeclRefExpr); 256 if (Args) size += ExplicitTemplateArgumentList::sizeFor(*Args); 257 void *Mem = C.Allocate(size); 258 259 DependentScopeDeclRefExpr *DRE 260 = new (Mem) DependentScopeDeclRefExpr(C.DependentTy, 261 Qualifier, QualifierRange, 262 Name, NameLoc, 263 Args != 0); 264 265 if (Args) 266 reinterpret_cast<ExplicitTemplateArgumentList*>(DRE+1) 267 ->initializeFrom(*Args); 268 269 return DRE; 270} 271 272StmtIterator DependentScopeDeclRefExpr::child_begin() { 273 return child_iterator(); 274} 275 276StmtIterator DependentScopeDeclRefExpr::child_end() { 277 return child_iterator(); 278} 279 280bool UnaryTypeTraitExpr::EvaluateTrait(ASTContext& C) const { 281 switch(UTT) { 282 default: assert(false && "Unknown type trait or not implemented"); 283 case UTT_IsPOD: return QueriedType->isPODType(); 284 case UTT_IsLiteral: return QueriedType->isLiteralType(); 285 case UTT_IsClass: // Fallthrough 286 case UTT_IsUnion: 287 if (const RecordType *Record = QueriedType->getAs<RecordType>()) { 288 bool Union = Record->getDecl()->isUnion(); 289 return UTT == UTT_IsUnion ? Union : !Union; 290 } 291 return false; 292 case UTT_IsEnum: return QueriedType->isEnumeralType(); 293 case UTT_IsPolymorphic: 294 if (const RecordType *Record = QueriedType->getAs<RecordType>()) { 295 // Type traits are only parsed in C++, so we've got CXXRecords. 296 return cast<CXXRecordDecl>(Record->getDecl())->isPolymorphic(); 297 } 298 return false; 299 case UTT_IsAbstract: 300 if (const RecordType *RT = QueriedType->getAs<RecordType>()) 301 return cast<CXXRecordDecl>(RT->getDecl())->isAbstract(); 302 return false; 303 case UTT_IsEmpty: 304 if (const RecordType *Record = QueriedType->getAs<RecordType>()) { 305 return !Record->getDecl()->isUnion() 306 && cast<CXXRecordDecl>(Record->getDecl())->isEmpty(); 307 } 308 return false; 309 case UTT_HasTrivialConstructor: 310 // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html: 311 // If __is_pod (type) is true then the trait is true, else if type is 312 // a cv class or union type (or array thereof) with a trivial default 313 // constructor ([class.ctor]) then the trait is true, else it is false. 314 if (QueriedType->isPODType()) 315 return true; 316 if (const RecordType *RT = 317 C.getBaseElementType(QueriedType)->getAs<RecordType>()) 318 return cast<CXXRecordDecl>(RT->getDecl())->hasTrivialConstructor(); 319 return false; 320 case UTT_HasTrivialCopy: 321 // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html: 322 // If __is_pod (type) is true or type is a reference type then 323 // the trait is true, else if type is a cv class or union type 324 // with a trivial copy constructor ([class.copy]) then the trait 325 // is true, else it is false. 326 if (QueriedType->isPODType() || QueriedType->isReferenceType()) 327 return true; 328 if (const RecordType *RT = QueriedType->getAs<RecordType>()) 329 return cast<CXXRecordDecl>(RT->getDecl())->hasTrivialCopyConstructor(); 330 return false; 331 case UTT_HasTrivialAssign: 332 // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html: 333 // If type is const qualified or is a reference type then the 334 // trait is false. Otherwise if __is_pod (type) is true then the 335 // trait is true, else if type is a cv class or union type with 336 // a trivial copy assignment ([class.copy]) then the trait is 337 // true, else it is false. 338 // Note: the const and reference restrictions are interesting, 339 // given that const and reference members don't prevent a class 340 // from having a trivial copy assignment operator (but do cause 341 // errors if the copy assignment operator is actually used, q.v. 342 // [class.copy]p12). 343 344 if (C.getBaseElementType(QueriedType).isConstQualified()) 345 return false; 346 if (QueriedType->isPODType()) 347 return true; 348 if (const RecordType *RT = QueriedType->getAs<RecordType>()) 349 return cast<CXXRecordDecl>(RT->getDecl())->hasTrivialCopyAssignment(); 350 return false; 351 case UTT_HasTrivialDestructor: 352 // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html: 353 // If __is_pod (type) is true or type is a reference type 354 // then the trait is true, else if type is a cv class or union 355 // type (or array thereof) with a trivial destructor 356 // ([class.dtor]) then the trait is true, else it is 357 // false. 358 if (QueriedType->isPODType() || QueriedType->isReferenceType()) 359 return true; 360 if (const RecordType *RT = 361 C.getBaseElementType(QueriedType)->getAs<RecordType>()) 362 return cast<CXXRecordDecl>(RT->getDecl())->hasTrivialDestructor(); 363 return false; 364 } 365} 366 367SourceRange CXXConstructExpr::getSourceRange() const { 368 // FIXME: Should we know where the parentheses are, if there are any? 369 for (std::reverse_iterator<Stmt**> I(&Args[NumArgs]), E(&Args[0]); I!=E;++I) { 370 // Ignore CXXDefaultExprs when computing the range, as they don't 371 // have a range. 372 if (!isa<CXXDefaultArgExpr>(*I)) 373 return SourceRange(Loc, (*I)->getLocEnd()); 374 } 375 376 return SourceRange(Loc); 377} 378 379SourceRange CXXOperatorCallExpr::getSourceRange() const { 380 OverloadedOperatorKind Kind = getOperator(); 381 if (Kind == OO_PlusPlus || Kind == OO_MinusMinus) { 382 if (getNumArgs() == 1) 383 // Prefix operator 384 return SourceRange(getOperatorLoc(), 385 getArg(0)->getSourceRange().getEnd()); 386 else 387 // Postfix operator 388 return SourceRange(getArg(0)->getSourceRange().getEnd(), 389 getOperatorLoc()); 390 } else if (Kind == OO_Call) { 391 return SourceRange(getArg(0)->getSourceRange().getBegin(), getRParenLoc()); 392 } else if (Kind == OO_Subscript) { 393 return SourceRange(getArg(0)->getSourceRange().getBegin(), getRParenLoc()); 394 } else if (getNumArgs() == 1) { 395 return SourceRange(getOperatorLoc(), getArg(0)->getSourceRange().getEnd()); 396 } else if (getNumArgs() == 2) { 397 return SourceRange(getArg(0)->getSourceRange().getBegin(), 398 getArg(1)->getSourceRange().getEnd()); 399 } else { 400 return SourceRange(); 401 } 402} 403 404Expr *CXXMemberCallExpr::getImplicitObjectArgument() { 405 if (MemberExpr *MemExpr = dyn_cast<MemberExpr>(getCallee()->IgnoreParens())) 406 return MemExpr->getBase(); 407 408 // FIXME: Will eventually need to cope with member pointers. 409 return 0; 410} 411 412SourceRange CXXMemberCallExpr::getSourceRange() const { 413 SourceLocation LocStart = getCallee()->getLocStart(); 414 if (LocStart.isInvalid() && getNumArgs() > 0) 415 LocStart = getArg(0)->getLocStart(); 416 return SourceRange(LocStart, getRParenLoc()); 417} 418 419 420//===----------------------------------------------------------------------===// 421// Named casts 422//===----------------------------------------------------------------------===// 423 424/// getCastName - Get the name of the C++ cast being used, e.g., 425/// "static_cast", "dynamic_cast", "reinterpret_cast", or 426/// "const_cast". The returned pointer must not be freed. 427const char *CXXNamedCastExpr::getCastName() const { 428 switch (getStmtClass()) { 429 case CXXStaticCastExprClass: return "static_cast"; 430 case CXXDynamicCastExprClass: return "dynamic_cast"; 431 case CXXReinterpretCastExprClass: return "reinterpret_cast"; 432 case CXXConstCastExprClass: return "const_cast"; 433 default: return "<invalid cast>"; 434 } 435} 436 437CXXDefaultArgExpr * 438CXXDefaultArgExpr::Create(ASTContext &C, SourceLocation Loc, 439 ParmVarDecl *Param, Expr *SubExpr) { 440 void *Mem = C.Allocate(sizeof(CXXDefaultArgExpr) + sizeof(Stmt *)); 441 return new (Mem) CXXDefaultArgExpr(CXXDefaultArgExprClass, Loc, Param, 442 SubExpr); 443} 444 445void CXXDefaultArgExpr::DoDestroy(ASTContext &C) { 446 if (Param.getInt()) 447 getExpr()->Destroy(C); 448 this->~CXXDefaultArgExpr(); 449 C.Deallocate(this); 450} 451 452CXXTemporary *CXXTemporary::Create(ASTContext &C, 453 const CXXDestructorDecl *Destructor) { 454 return new (C) CXXTemporary(Destructor); 455} 456 457void CXXTemporary::Destroy(ASTContext &Ctx) { 458 this->~CXXTemporary(); 459 Ctx.Deallocate(this); 460} 461 462CXXBindTemporaryExpr *CXXBindTemporaryExpr::Create(ASTContext &C, 463 CXXTemporary *Temp, 464 Expr* SubExpr) { 465 assert(SubExpr->getType()->isRecordType() && 466 "Expression bound to a temporary must have record type!"); 467 468 return new (C) CXXBindTemporaryExpr(Temp, SubExpr); 469} 470 471void CXXBindTemporaryExpr::DoDestroy(ASTContext &C) { 472 Temp->Destroy(C); 473 this->~CXXBindTemporaryExpr(); 474 C.Deallocate(this); 475} 476 477CXXBindReferenceExpr *CXXBindReferenceExpr::Create(ASTContext &C, Expr *SubExpr, 478 bool ExtendsLifetime, 479 bool RequiresTemporaryCopy) { 480 return new (C) CXXBindReferenceExpr(SubExpr, 481 ExtendsLifetime, 482 RequiresTemporaryCopy); 483} 484 485void CXXBindReferenceExpr::DoDestroy(ASTContext &C) { 486 this->~CXXBindReferenceExpr(); 487 C.Deallocate(this); 488} 489 490CXXTemporaryObjectExpr::CXXTemporaryObjectExpr(ASTContext &C, 491 CXXConstructorDecl *Cons, 492 QualType writtenTy, 493 SourceLocation tyBeginLoc, 494 Expr **Args, 495 unsigned NumArgs, 496 SourceLocation rParenLoc, 497 bool ZeroInitialization) 498 : CXXConstructExpr(C, CXXTemporaryObjectExprClass, writtenTy, tyBeginLoc, 499 Cons, false, Args, NumArgs, ZeroInitialization), 500 TyBeginLoc(tyBeginLoc), RParenLoc(rParenLoc) { 501} 502 503CXXConstructExpr *CXXConstructExpr::Create(ASTContext &C, QualType T, 504 SourceLocation Loc, 505 CXXConstructorDecl *D, bool Elidable, 506 Expr **Args, unsigned NumArgs, 507 bool ZeroInitialization, 508 ConstructionKind ConstructKind) { 509 return new (C) CXXConstructExpr(C, CXXConstructExprClass, T, Loc, D, 510 Elidable, Args, NumArgs, ZeroInitialization, 511 ConstructKind); 512} 513 514CXXConstructExpr::CXXConstructExpr(ASTContext &C, StmtClass SC, QualType T, 515 SourceLocation Loc, 516 CXXConstructorDecl *D, bool elidable, 517 Expr **args, unsigned numargs, 518 bool ZeroInitialization, 519 ConstructionKind ConstructKind) 520: Expr(SC, T, 521 T->isDependentType(), 522 (T->isDependentType() || 523 CallExpr::hasAnyValueDependentArguments(args, numargs))), 524 Constructor(D), Loc(Loc), Elidable(elidable), 525 ZeroInitialization(ZeroInitialization), ConstructKind(ConstructKind), 526 Args(0), NumArgs(numargs) 527{ 528 if (NumArgs) { 529 Args = new (C) Stmt*[NumArgs]; 530 531 for (unsigned i = 0; i != NumArgs; ++i) { 532 assert(args[i] && "NULL argument in CXXConstructExpr"); 533 Args[i] = args[i]; 534 } 535 } 536} 537 538CXXConstructExpr::CXXConstructExpr(EmptyShell Empty, ASTContext &C, 539 unsigned numargs) 540 : Expr(CXXConstructExprClass, Empty), Args(0), NumArgs(numargs) 541{ 542 if (NumArgs) 543 Args = new (C) Stmt*[NumArgs]; 544} 545 546void CXXConstructExpr::DoDestroy(ASTContext &C) { 547 DestroyChildren(C); 548 if (Args) 549 C.Deallocate(Args); 550 this->~CXXConstructExpr(); 551 C.Deallocate(this); 552} 553 554CXXExprWithTemporaries::CXXExprWithTemporaries(ASTContext &C, 555 Expr *subexpr, 556 CXXTemporary **temps, 557 unsigned numtemps) 558 : Expr(CXXExprWithTemporariesClass, subexpr->getType(), 559 subexpr->isTypeDependent(), subexpr->isValueDependent()), 560 SubExpr(subexpr), Temps(0), NumTemps(0) { 561 if (numtemps) { 562 setNumTemporaries(C, numtemps); 563 for (unsigned i = 0; i != numtemps; ++i) 564 Temps[i] = temps[i]; 565 } 566} 567 568void CXXExprWithTemporaries::setNumTemporaries(ASTContext &C, unsigned N) { 569 assert(Temps == 0 && "Cannot resize with this"); 570 NumTemps = N; 571 Temps = new (C) CXXTemporary*[NumTemps]; 572} 573 574 575CXXExprWithTemporaries *CXXExprWithTemporaries::Create(ASTContext &C, 576 Expr *SubExpr, 577 CXXTemporary **Temps, 578 unsigned NumTemps) { 579 return new (C) CXXExprWithTemporaries(C, SubExpr, Temps, NumTemps); 580} 581 582void CXXExprWithTemporaries::DoDestroy(ASTContext &C) { 583 DestroyChildren(C); 584 if (Temps) 585 C.Deallocate(Temps); 586 this->~CXXExprWithTemporaries(); 587 C.Deallocate(this); 588} 589 590CXXExprWithTemporaries::~CXXExprWithTemporaries() {} 591 592// CXXBindTemporaryExpr 593Stmt::child_iterator CXXBindTemporaryExpr::child_begin() { 594 return &SubExpr; 595} 596 597Stmt::child_iterator CXXBindTemporaryExpr::child_end() { 598 return &SubExpr + 1; 599} 600 601// CXXBindReferenceExpr 602Stmt::child_iterator CXXBindReferenceExpr::child_begin() { 603 return &SubExpr; 604} 605 606Stmt::child_iterator CXXBindReferenceExpr::child_end() { 607 return &SubExpr + 1; 608} 609 610// CXXConstructExpr 611Stmt::child_iterator CXXConstructExpr::child_begin() { 612 return &Args[0]; 613} 614Stmt::child_iterator CXXConstructExpr::child_end() { 615 return &Args[0]+NumArgs; 616} 617 618// CXXExprWithTemporaries 619Stmt::child_iterator CXXExprWithTemporaries::child_begin() { 620 return &SubExpr; 621} 622 623Stmt::child_iterator CXXExprWithTemporaries::child_end() { 624 return &SubExpr + 1; 625} 626 627CXXUnresolvedConstructExpr::CXXUnresolvedConstructExpr( 628 SourceLocation TyBeginLoc, 629 QualType T, 630 SourceLocation LParenLoc, 631 Expr **Args, 632 unsigned NumArgs, 633 SourceLocation RParenLoc) 634 : Expr(CXXUnresolvedConstructExprClass, T.getNonReferenceType(), 635 T->isDependentType(), true), 636 TyBeginLoc(TyBeginLoc), 637 Type(T), 638 LParenLoc(LParenLoc), 639 RParenLoc(RParenLoc), 640 NumArgs(NumArgs) { 641 Stmt **StoredArgs = reinterpret_cast<Stmt **>(this + 1); 642 memcpy(StoredArgs, Args, sizeof(Expr *) * NumArgs); 643} 644 645CXXUnresolvedConstructExpr * 646CXXUnresolvedConstructExpr::Create(ASTContext &C, 647 SourceLocation TyBegin, 648 QualType T, 649 SourceLocation LParenLoc, 650 Expr **Args, 651 unsigned NumArgs, 652 SourceLocation RParenLoc) { 653 void *Mem = C.Allocate(sizeof(CXXUnresolvedConstructExpr) + 654 sizeof(Expr *) * NumArgs); 655 return new (Mem) CXXUnresolvedConstructExpr(TyBegin, T, LParenLoc, 656 Args, NumArgs, RParenLoc); 657} 658 659Stmt::child_iterator CXXUnresolvedConstructExpr::child_begin() { 660 return child_iterator(reinterpret_cast<Stmt **>(this + 1)); 661} 662 663Stmt::child_iterator CXXUnresolvedConstructExpr::child_end() { 664 return child_iterator(reinterpret_cast<Stmt **>(this + 1) + NumArgs); 665} 666 667CXXDependentScopeMemberExpr::CXXDependentScopeMemberExpr(ASTContext &C, 668 Expr *Base, QualType BaseType, 669 bool IsArrow, 670 SourceLocation OperatorLoc, 671 NestedNameSpecifier *Qualifier, 672 SourceRange QualifierRange, 673 NamedDecl *FirstQualifierFoundInScope, 674 DeclarationName Member, 675 SourceLocation MemberLoc, 676 const TemplateArgumentListInfo *TemplateArgs) 677 : Expr(CXXDependentScopeMemberExprClass, C.DependentTy, true, true), 678 Base(Base), BaseType(BaseType), IsArrow(IsArrow), 679 HasExplicitTemplateArgs(TemplateArgs != 0), 680 OperatorLoc(OperatorLoc), 681 Qualifier(Qualifier), QualifierRange(QualifierRange), 682 FirstQualifierFoundInScope(FirstQualifierFoundInScope), 683 Member(Member), MemberLoc(MemberLoc) { 684 if (TemplateArgs) 685 getExplicitTemplateArgumentList()->initializeFrom(*TemplateArgs); 686} 687 688CXXDependentScopeMemberExpr * 689CXXDependentScopeMemberExpr::Create(ASTContext &C, 690 Expr *Base, QualType BaseType, bool IsArrow, 691 SourceLocation OperatorLoc, 692 NestedNameSpecifier *Qualifier, 693 SourceRange QualifierRange, 694 NamedDecl *FirstQualifierFoundInScope, 695 DeclarationName Member, 696 SourceLocation MemberLoc, 697 const TemplateArgumentListInfo *TemplateArgs) { 698 if (!TemplateArgs) 699 return new (C) CXXDependentScopeMemberExpr(C, Base, BaseType, 700 IsArrow, OperatorLoc, 701 Qualifier, QualifierRange, 702 FirstQualifierFoundInScope, 703 Member, MemberLoc); 704 705 std::size_t size = sizeof(CXXDependentScopeMemberExpr); 706 if (TemplateArgs) 707 size += ExplicitTemplateArgumentList::sizeFor(*TemplateArgs); 708 709 void *Mem = C.Allocate(size, llvm::alignof<CXXDependentScopeMemberExpr>()); 710 return new (Mem) CXXDependentScopeMemberExpr(C, Base, BaseType, 711 IsArrow, OperatorLoc, 712 Qualifier, QualifierRange, 713 FirstQualifierFoundInScope, 714 Member, MemberLoc, TemplateArgs); 715} 716 717Stmt::child_iterator CXXDependentScopeMemberExpr::child_begin() { 718 return child_iterator(&Base); 719} 720 721Stmt::child_iterator CXXDependentScopeMemberExpr::child_end() { 722 if (isImplicitAccess()) 723 return child_iterator(&Base); 724 return child_iterator(&Base + 1); 725} 726 727UnresolvedMemberExpr::UnresolvedMemberExpr(ASTContext &C, QualType T, 728 bool Dependent, 729 bool HasUnresolvedUsing, 730 Expr *Base, QualType BaseType, 731 bool IsArrow, 732 SourceLocation OperatorLoc, 733 NestedNameSpecifier *Qualifier, 734 SourceRange QualifierRange, 735 DeclarationName MemberName, 736 SourceLocation MemberLoc, 737 const TemplateArgumentListInfo *TemplateArgs, 738 UnresolvedSetIterator Begin, 739 UnresolvedSetIterator End) 740 : OverloadExpr(UnresolvedMemberExprClass, C, T, Dependent, 741 Qualifier, QualifierRange, MemberName, MemberLoc, 742 TemplateArgs != 0, Begin, End), 743 IsArrow(IsArrow), HasUnresolvedUsing(HasUnresolvedUsing), 744 Base(Base), BaseType(BaseType), OperatorLoc(OperatorLoc) { 745 if (TemplateArgs) 746 getExplicitTemplateArgs().initializeFrom(*TemplateArgs); 747} 748 749UnresolvedMemberExpr * 750UnresolvedMemberExpr::Create(ASTContext &C, bool Dependent, 751 bool HasUnresolvedUsing, 752 Expr *Base, QualType BaseType, bool IsArrow, 753 SourceLocation OperatorLoc, 754 NestedNameSpecifier *Qualifier, 755 SourceRange QualifierRange, 756 DeclarationName Member, 757 SourceLocation MemberLoc, 758 const TemplateArgumentListInfo *TemplateArgs, 759 UnresolvedSetIterator Begin, 760 UnresolvedSetIterator End) { 761 std::size_t size = sizeof(UnresolvedMemberExpr); 762 if (TemplateArgs) 763 size += ExplicitTemplateArgumentList::sizeFor(*TemplateArgs); 764 765 void *Mem = C.Allocate(size, llvm::alignof<UnresolvedMemberExpr>()); 766 return new (Mem) UnresolvedMemberExpr(C, 767 Dependent ? C.DependentTy : C.OverloadTy, 768 Dependent, HasUnresolvedUsing, Base, BaseType, 769 IsArrow, OperatorLoc, Qualifier, QualifierRange, 770 Member, MemberLoc, TemplateArgs, Begin, End); 771} 772 773CXXRecordDecl *UnresolvedMemberExpr::getNamingClass() const { 774 // Unlike for UnresolvedLookupExpr, it is very easy to re-derive this. 775 776 // If there was a nested name specifier, it names the naming class. 777 // It can't be dependent: after all, we were actually able to do the 778 // lookup. 779 CXXRecordDecl *Record = 0; 780 if (getQualifier()) { 781 Type *T = getQualifier()->getAsType(); 782 assert(T && "qualifier in member expression does not name type"); 783 Record = T->getAsCXXRecordDecl(); 784 assert(Record && "qualifier in member expression does not name record"); 785 } 786 // Otherwise the naming class must have been the base class. 787 else { 788 QualType BaseType = getBaseType().getNonReferenceType(); 789 if (isArrow()) { 790 const PointerType *PT = BaseType->getAs<PointerType>(); 791 assert(PT && "base of arrow member access is not pointer"); 792 BaseType = PT->getPointeeType(); 793 } 794 795 Record = BaseType->getAsCXXRecordDecl(); 796 assert(Record && "base of member expression does not name record"); 797 } 798 799 return Record; 800} 801 802Stmt::child_iterator UnresolvedMemberExpr::child_begin() { 803 return child_iterator(&Base); 804} 805 806Stmt::child_iterator UnresolvedMemberExpr::child_end() { 807 if (isImplicitAccess()) 808 return child_iterator(&Base); 809 return child_iterator(&Base + 1); 810} 811