ExprCXX.cpp revision 210299
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// CXXScalarValueInitExpr 78Stmt::child_iterator CXXScalarValueInitExpr::child_begin() { 79 return child_iterator(); 80} 81Stmt::child_iterator CXXScalarValueInitExpr::child_end() { 82 return child_iterator(); 83} 84 85// CXXNewExpr 86CXXNewExpr::CXXNewExpr(ASTContext &C, bool globalNew, FunctionDecl *operatorNew, 87 Expr **placementArgs, unsigned numPlaceArgs, 88 SourceRange TypeIdParens, 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), 95 Initializer(initializer), SubExprs(0), OperatorNew(operatorNew), 96 OperatorDelete(operatorDelete), Constructor(constructor), 97 TypeIdParens(TypeIdParens), 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 193UnresolvedLookupExpr * 194UnresolvedLookupExpr::CreateEmpty(ASTContext &C, unsigned NumTemplateArgs) { 195 std::size_t size = sizeof(UnresolvedLookupExpr); 196 if (NumTemplateArgs != 0) 197 size += ExplicitTemplateArgumentList::sizeFor(NumTemplateArgs); 198 199 void *Mem = C.Allocate(size, llvm::alignof<UnresolvedLookupExpr>()); 200 UnresolvedLookupExpr *E = new (Mem) UnresolvedLookupExpr(EmptyShell()); 201 E->HasExplicitTemplateArgs = NumTemplateArgs != 0; 202 return E; 203} 204 205OverloadExpr::OverloadExpr(StmtClass K, ASTContext &C, QualType T, 206 bool Dependent, NestedNameSpecifier *Qualifier, 207 SourceRange QRange, DeclarationName Name, 208 SourceLocation NameLoc, bool HasTemplateArgs, 209 UnresolvedSetIterator Begin, 210 UnresolvedSetIterator End) 211 : Expr(K, T, Dependent, Dependent), 212 Results(0), NumResults(0), Name(Name), Qualifier(Qualifier), 213 QualifierRange(QRange), NameLoc(NameLoc), 214 HasExplicitTemplateArgs(HasTemplateArgs) 215{ 216 initializeResults(C, Begin, End); 217} 218 219void OverloadExpr::initializeResults(ASTContext &C, 220 UnresolvedSetIterator Begin, 221 UnresolvedSetIterator End) { 222 assert(Results == 0 && "Results already initialized!"); 223 NumResults = End - Begin; 224 if (NumResults) { 225 Results = static_cast<DeclAccessPair *>( 226 C.Allocate(sizeof(DeclAccessPair) * NumResults, 227 llvm::alignof<DeclAccessPair>())); 228 memcpy(Results, &*Begin.getIterator(), 229 NumResults * sizeof(DeclAccessPair)); 230 } 231} 232 233 234bool OverloadExpr::ComputeDependence(UnresolvedSetIterator Begin, 235 UnresolvedSetIterator End, 236 const TemplateArgumentListInfo *Args) { 237 for (UnresolvedSetImpl::const_iterator I = Begin; I != End; ++I) 238 if ((*I)->getDeclContext()->isDependentContext()) 239 return true; 240 241 if (Args && TemplateSpecializationType::anyDependentTemplateArguments(*Args)) 242 return true; 243 244 return false; 245} 246 247CXXRecordDecl *OverloadExpr::getNamingClass() const { 248 if (isa<UnresolvedLookupExpr>(this)) 249 return cast<UnresolvedLookupExpr>(this)->getNamingClass(); 250 else 251 return cast<UnresolvedMemberExpr>(this)->getNamingClass(); 252} 253 254Stmt::child_iterator UnresolvedLookupExpr::child_begin() { 255 return child_iterator(); 256} 257Stmt::child_iterator UnresolvedLookupExpr::child_end() { 258 return child_iterator(); 259} 260// UnaryTypeTraitExpr 261Stmt::child_iterator UnaryTypeTraitExpr::child_begin() { 262 return child_iterator(); 263} 264Stmt::child_iterator UnaryTypeTraitExpr::child_end() { 265 return child_iterator(); 266} 267 268// DependentScopeDeclRefExpr 269DependentScopeDeclRefExpr * 270DependentScopeDeclRefExpr::Create(ASTContext &C, 271 NestedNameSpecifier *Qualifier, 272 SourceRange QualifierRange, 273 DeclarationName Name, 274 SourceLocation NameLoc, 275 const TemplateArgumentListInfo *Args) { 276 std::size_t size = sizeof(DependentScopeDeclRefExpr); 277 if (Args) size += ExplicitTemplateArgumentList::sizeFor(*Args); 278 void *Mem = C.Allocate(size); 279 280 DependentScopeDeclRefExpr *DRE 281 = new (Mem) DependentScopeDeclRefExpr(C.DependentTy, 282 Qualifier, QualifierRange, 283 Name, NameLoc, 284 Args != 0); 285 286 if (Args) 287 reinterpret_cast<ExplicitTemplateArgumentList*>(DRE+1) 288 ->initializeFrom(*Args); 289 290 return DRE; 291} 292 293DependentScopeDeclRefExpr * 294DependentScopeDeclRefExpr::CreateEmpty(ASTContext &C, 295 unsigned NumTemplateArgs) { 296 std::size_t size = sizeof(DependentScopeDeclRefExpr); 297 if (NumTemplateArgs) 298 size += ExplicitTemplateArgumentList::sizeFor(NumTemplateArgs); 299 void *Mem = C.Allocate(size); 300 301 return new (Mem) DependentScopeDeclRefExpr(QualType(), 0, SourceRange(), 302 DeclarationName(),SourceLocation(), 303 NumTemplateArgs != 0); 304} 305 306StmtIterator DependentScopeDeclRefExpr::child_begin() { 307 return child_iterator(); 308} 309 310StmtIterator DependentScopeDeclRefExpr::child_end() { 311 return child_iterator(); 312} 313 314bool UnaryTypeTraitExpr::EvaluateTrait(ASTContext& C) const { 315 switch(UTT) { 316 default: assert(false && "Unknown type trait or not implemented"); 317 case UTT_IsPOD: return QueriedType->isPODType(); 318 case UTT_IsLiteral: return QueriedType->isLiteralType(); 319 case UTT_IsClass: // Fallthrough 320 case UTT_IsUnion: 321 if (const RecordType *Record = QueriedType->getAs<RecordType>()) { 322 bool Union = Record->getDecl()->isUnion(); 323 return UTT == UTT_IsUnion ? Union : !Union; 324 } 325 return false; 326 case UTT_IsEnum: return QueriedType->isEnumeralType(); 327 case UTT_IsPolymorphic: 328 if (const RecordType *Record = QueriedType->getAs<RecordType>()) { 329 // Type traits are only parsed in C++, so we've got CXXRecords. 330 return cast<CXXRecordDecl>(Record->getDecl())->isPolymorphic(); 331 } 332 return false; 333 case UTT_IsAbstract: 334 if (const RecordType *RT = QueriedType->getAs<RecordType>()) 335 return cast<CXXRecordDecl>(RT->getDecl())->isAbstract(); 336 return false; 337 case UTT_IsEmpty: 338 if (const RecordType *Record = QueriedType->getAs<RecordType>()) { 339 return !Record->getDecl()->isUnion() 340 && cast<CXXRecordDecl>(Record->getDecl())->isEmpty(); 341 } 342 return false; 343 case UTT_HasTrivialConstructor: 344 // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html: 345 // If __is_pod (type) is true then the trait is true, else if type is 346 // a cv class or union type (or array thereof) with a trivial default 347 // constructor ([class.ctor]) then the trait is true, else it is false. 348 if (QueriedType->isPODType()) 349 return true; 350 if (const RecordType *RT = 351 C.getBaseElementType(QueriedType)->getAs<RecordType>()) 352 return cast<CXXRecordDecl>(RT->getDecl())->hasTrivialConstructor(); 353 return false; 354 case UTT_HasTrivialCopy: 355 // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html: 356 // If __is_pod (type) is true or type is a reference type then 357 // the trait is true, else if type is a cv class or union type 358 // with a trivial copy constructor ([class.copy]) then the trait 359 // is true, else it is false. 360 if (QueriedType->isPODType() || QueriedType->isReferenceType()) 361 return true; 362 if (const RecordType *RT = QueriedType->getAs<RecordType>()) 363 return cast<CXXRecordDecl>(RT->getDecl())->hasTrivialCopyConstructor(); 364 return false; 365 case UTT_HasTrivialAssign: 366 // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html: 367 // If type is const qualified or is a reference type then the 368 // trait is false. Otherwise if __is_pod (type) is true then the 369 // trait is true, else if type is a cv class or union type with 370 // a trivial copy assignment ([class.copy]) then the trait is 371 // true, else it is false. 372 // Note: the const and reference restrictions are interesting, 373 // given that const and reference members don't prevent a class 374 // from having a trivial copy assignment operator (but do cause 375 // errors if the copy assignment operator is actually used, q.v. 376 // [class.copy]p12). 377 378 if (C.getBaseElementType(QueriedType).isConstQualified()) 379 return false; 380 if (QueriedType->isPODType()) 381 return true; 382 if (const RecordType *RT = QueriedType->getAs<RecordType>()) 383 return cast<CXXRecordDecl>(RT->getDecl())->hasTrivialCopyAssignment(); 384 return false; 385 case UTT_HasTrivialDestructor: 386 // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html: 387 // If __is_pod (type) is true or type is a reference type 388 // then the trait is true, else if type is a cv class or union 389 // type (or array thereof) with a trivial destructor 390 // ([class.dtor]) then the trait is true, else it is 391 // false. 392 if (QueriedType->isPODType() || QueriedType->isReferenceType()) 393 return true; 394 if (const RecordType *RT = 395 C.getBaseElementType(QueriedType)->getAs<RecordType>()) 396 return cast<CXXRecordDecl>(RT->getDecl())->hasTrivialDestructor(); 397 return false; 398 } 399} 400 401SourceRange CXXConstructExpr::getSourceRange() const { 402 // FIXME: Should we know where the parentheses are, if there are any? 403 for (std::reverse_iterator<Stmt**> I(&Args[NumArgs]), E(&Args[0]); I!=E;++I) { 404 // Ignore CXXDefaultExprs when computing the range, as they don't 405 // have a range. 406 if (!isa<CXXDefaultArgExpr>(*I)) 407 return SourceRange(Loc, (*I)->getLocEnd()); 408 } 409 410 return SourceRange(Loc); 411} 412 413SourceRange CXXOperatorCallExpr::getSourceRange() const { 414 OverloadedOperatorKind Kind = getOperator(); 415 if (Kind == OO_PlusPlus || Kind == OO_MinusMinus) { 416 if (getNumArgs() == 1) 417 // Prefix operator 418 return SourceRange(getOperatorLoc(), 419 getArg(0)->getSourceRange().getEnd()); 420 else 421 // Postfix operator 422 return SourceRange(getArg(0)->getSourceRange().getEnd(), 423 getOperatorLoc()); 424 } else if (Kind == OO_Call) { 425 return SourceRange(getArg(0)->getSourceRange().getBegin(), getRParenLoc()); 426 } else if (Kind == OO_Subscript) { 427 return SourceRange(getArg(0)->getSourceRange().getBegin(), getRParenLoc()); 428 } else if (getNumArgs() == 1) { 429 return SourceRange(getOperatorLoc(), getArg(0)->getSourceRange().getEnd()); 430 } else if (getNumArgs() == 2) { 431 return SourceRange(getArg(0)->getSourceRange().getBegin(), 432 getArg(1)->getSourceRange().getEnd()); 433 } else { 434 return SourceRange(); 435 } 436} 437 438Expr *CXXMemberCallExpr::getImplicitObjectArgument() { 439 if (MemberExpr *MemExpr = dyn_cast<MemberExpr>(getCallee()->IgnoreParens())) 440 return MemExpr->getBase(); 441 442 // FIXME: Will eventually need to cope with member pointers. 443 return 0; 444} 445 446SourceRange CXXMemberCallExpr::getSourceRange() const { 447 SourceLocation LocStart = getCallee()->getLocStart(); 448 if (LocStart.isInvalid() && getNumArgs() > 0) 449 LocStart = getArg(0)->getLocStart(); 450 return SourceRange(LocStart, getRParenLoc()); 451} 452 453 454//===----------------------------------------------------------------------===// 455// Named casts 456//===----------------------------------------------------------------------===// 457 458/// getCastName - Get the name of the C++ cast being used, e.g., 459/// "static_cast", "dynamic_cast", "reinterpret_cast", or 460/// "const_cast". The returned pointer must not be freed. 461const char *CXXNamedCastExpr::getCastName() const { 462 switch (getStmtClass()) { 463 case CXXStaticCastExprClass: return "static_cast"; 464 case CXXDynamicCastExprClass: return "dynamic_cast"; 465 case CXXReinterpretCastExprClass: return "reinterpret_cast"; 466 case CXXConstCastExprClass: return "const_cast"; 467 default: return "<invalid cast>"; 468 } 469} 470 471CXXDefaultArgExpr * 472CXXDefaultArgExpr::Create(ASTContext &C, SourceLocation Loc, 473 ParmVarDecl *Param, Expr *SubExpr) { 474 void *Mem = C.Allocate(sizeof(CXXDefaultArgExpr) + sizeof(Stmt *)); 475 return new (Mem) CXXDefaultArgExpr(CXXDefaultArgExprClass, Loc, Param, 476 SubExpr); 477} 478 479void CXXDefaultArgExpr::DoDestroy(ASTContext &C) { 480 if (Param.getInt()) 481 getExpr()->Destroy(C); 482 this->~CXXDefaultArgExpr(); 483 C.Deallocate(this); 484} 485 486CXXTemporary *CXXTemporary::Create(ASTContext &C, 487 const CXXDestructorDecl *Destructor) { 488 return new (C) CXXTemporary(Destructor); 489} 490 491void CXXTemporary::Destroy(ASTContext &Ctx) { 492 this->~CXXTemporary(); 493 Ctx.Deallocate(this); 494} 495 496CXXBindTemporaryExpr *CXXBindTemporaryExpr::Create(ASTContext &C, 497 CXXTemporary *Temp, 498 Expr* SubExpr) { 499 assert(SubExpr->getType()->isRecordType() && 500 "Expression bound to a temporary must have record type!"); 501 502 return new (C) CXXBindTemporaryExpr(Temp, SubExpr); 503} 504 505void CXXBindTemporaryExpr::DoDestroy(ASTContext &C) { 506 Temp->Destroy(C); 507 this->~CXXBindTemporaryExpr(); 508 C.Deallocate(this); 509} 510 511CXXBindReferenceExpr *CXXBindReferenceExpr::Create(ASTContext &C, Expr *SubExpr, 512 bool ExtendsLifetime, 513 bool RequiresTemporaryCopy) { 514 return new (C) CXXBindReferenceExpr(SubExpr, 515 ExtendsLifetime, 516 RequiresTemporaryCopy); 517} 518 519void CXXBindReferenceExpr::DoDestroy(ASTContext &C) { 520 this->~CXXBindReferenceExpr(); 521 C.Deallocate(this); 522} 523 524CXXTemporaryObjectExpr::CXXTemporaryObjectExpr(ASTContext &C, 525 CXXConstructorDecl *Cons, 526 QualType writtenTy, 527 SourceLocation tyBeginLoc, 528 Expr **Args, 529 unsigned NumArgs, 530 SourceLocation rParenLoc, 531 bool ZeroInitialization) 532 : CXXConstructExpr(C, CXXTemporaryObjectExprClass, writtenTy, tyBeginLoc, 533 Cons, false, Args, NumArgs, ZeroInitialization), 534 TyBeginLoc(tyBeginLoc), RParenLoc(rParenLoc) { 535} 536 537CXXConstructExpr *CXXConstructExpr::Create(ASTContext &C, QualType T, 538 SourceLocation Loc, 539 CXXConstructorDecl *D, bool Elidable, 540 Expr **Args, unsigned NumArgs, 541 bool ZeroInitialization, 542 ConstructionKind ConstructKind) { 543 return new (C) CXXConstructExpr(C, CXXConstructExprClass, T, Loc, D, 544 Elidable, Args, NumArgs, ZeroInitialization, 545 ConstructKind); 546} 547 548CXXConstructExpr::CXXConstructExpr(ASTContext &C, StmtClass SC, QualType T, 549 SourceLocation Loc, 550 CXXConstructorDecl *D, bool elidable, 551 Expr **args, unsigned numargs, 552 bool ZeroInitialization, 553 ConstructionKind ConstructKind) 554: Expr(SC, T, 555 T->isDependentType(), 556 (T->isDependentType() || 557 CallExpr::hasAnyValueDependentArguments(args, numargs))), 558 Constructor(D), Loc(Loc), Elidable(elidable), 559 ZeroInitialization(ZeroInitialization), ConstructKind(ConstructKind), 560 Args(0), NumArgs(numargs) 561{ 562 if (NumArgs) { 563 Args = new (C) Stmt*[NumArgs]; 564 565 for (unsigned i = 0; i != NumArgs; ++i) { 566 assert(args[i] && "NULL argument in CXXConstructExpr"); 567 Args[i] = args[i]; 568 } 569 } 570} 571 572void CXXConstructExpr::DoDestroy(ASTContext &C) { 573 DestroyChildren(C); 574 if (Args) 575 C.Deallocate(Args); 576 this->~CXXConstructExpr(); 577 C.Deallocate(this); 578} 579 580CXXExprWithTemporaries::CXXExprWithTemporaries(ASTContext &C, 581 Expr *subexpr, 582 CXXTemporary **temps, 583 unsigned numtemps) 584 : Expr(CXXExprWithTemporariesClass, subexpr->getType(), 585 subexpr->isTypeDependent(), subexpr->isValueDependent()), 586 SubExpr(subexpr), Temps(0), NumTemps(0) { 587 if (numtemps) { 588 setNumTemporaries(C, numtemps); 589 for (unsigned i = 0; i != numtemps; ++i) 590 Temps[i] = temps[i]; 591 } 592} 593 594void CXXExprWithTemporaries::setNumTemporaries(ASTContext &C, unsigned N) { 595 assert(Temps == 0 && "Cannot resize with this"); 596 NumTemps = N; 597 Temps = new (C) CXXTemporary*[NumTemps]; 598} 599 600 601CXXExprWithTemporaries *CXXExprWithTemporaries::Create(ASTContext &C, 602 Expr *SubExpr, 603 CXXTemporary **Temps, 604 unsigned NumTemps) { 605 return new (C) CXXExprWithTemporaries(C, SubExpr, Temps, NumTemps); 606} 607 608void CXXExprWithTemporaries::DoDestroy(ASTContext &C) { 609 DestroyChildren(C); 610 if (Temps) 611 C.Deallocate(Temps); 612 this->~CXXExprWithTemporaries(); 613 C.Deallocate(this); 614} 615 616CXXExprWithTemporaries::~CXXExprWithTemporaries() {} 617 618// CXXBindTemporaryExpr 619Stmt::child_iterator CXXBindTemporaryExpr::child_begin() { 620 return &SubExpr; 621} 622 623Stmt::child_iterator CXXBindTemporaryExpr::child_end() { 624 return &SubExpr + 1; 625} 626 627// CXXBindReferenceExpr 628Stmt::child_iterator CXXBindReferenceExpr::child_begin() { 629 return &SubExpr; 630} 631 632Stmt::child_iterator CXXBindReferenceExpr::child_end() { 633 return &SubExpr + 1; 634} 635 636// CXXConstructExpr 637Stmt::child_iterator CXXConstructExpr::child_begin() { 638 return &Args[0]; 639} 640Stmt::child_iterator CXXConstructExpr::child_end() { 641 return &Args[0]+NumArgs; 642} 643 644// CXXExprWithTemporaries 645Stmt::child_iterator CXXExprWithTemporaries::child_begin() { 646 return &SubExpr; 647} 648 649Stmt::child_iterator CXXExprWithTemporaries::child_end() { 650 return &SubExpr + 1; 651} 652 653CXXUnresolvedConstructExpr::CXXUnresolvedConstructExpr( 654 SourceLocation TyBeginLoc, 655 QualType T, 656 SourceLocation LParenLoc, 657 Expr **Args, 658 unsigned NumArgs, 659 SourceLocation RParenLoc) 660 : Expr(CXXUnresolvedConstructExprClass, T.getNonReferenceType(), 661 T->isDependentType(), true), 662 TyBeginLoc(TyBeginLoc), 663 Type(T), 664 LParenLoc(LParenLoc), 665 RParenLoc(RParenLoc), 666 NumArgs(NumArgs) { 667 Stmt **StoredArgs = reinterpret_cast<Stmt **>(this + 1); 668 memcpy(StoredArgs, Args, sizeof(Expr *) * NumArgs); 669} 670 671CXXUnresolvedConstructExpr * 672CXXUnresolvedConstructExpr::Create(ASTContext &C, 673 SourceLocation TyBegin, 674 QualType T, 675 SourceLocation LParenLoc, 676 Expr **Args, 677 unsigned NumArgs, 678 SourceLocation RParenLoc) { 679 void *Mem = C.Allocate(sizeof(CXXUnresolvedConstructExpr) + 680 sizeof(Expr *) * NumArgs); 681 return new (Mem) CXXUnresolvedConstructExpr(TyBegin, T, LParenLoc, 682 Args, NumArgs, RParenLoc); 683} 684 685CXXUnresolvedConstructExpr * 686CXXUnresolvedConstructExpr::CreateEmpty(ASTContext &C, unsigned NumArgs) { 687 Stmt::EmptyShell Empty; 688 void *Mem = C.Allocate(sizeof(CXXUnresolvedConstructExpr) + 689 sizeof(Expr *) * NumArgs); 690 return new (Mem) CXXUnresolvedConstructExpr(Empty, NumArgs); 691} 692 693Stmt::child_iterator CXXUnresolvedConstructExpr::child_begin() { 694 return child_iterator(reinterpret_cast<Stmt **>(this + 1)); 695} 696 697Stmt::child_iterator CXXUnresolvedConstructExpr::child_end() { 698 return child_iterator(reinterpret_cast<Stmt **>(this + 1) + NumArgs); 699} 700 701CXXDependentScopeMemberExpr::CXXDependentScopeMemberExpr(ASTContext &C, 702 Expr *Base, QualType BaseType, 703 bool IsArrow, 704 SourceLocation OperatorLoc, 705 NestedNameSpecifier *Qualifier, 706 SourceRange QualifierRange, 707 NamedDecl *FirstQualifierFoundInScope, 708 DeclarationName Member, 709 SourceLocation MemberLoc, 710 const TemplateArgumentListInfo *TemplateArgs) 711 : Expr(CXXDependentScopeMemberExprClass, C.DependentTy, true, true), 712 Base(Base), BaseType(BaseType), IsArrow(IsArrow), 713 HasExplicitTemplateArgs(TemplateArgs != 0), 714 OperatorLoc(OperatorLoc), 715 Qualifier(Qualifier), QualifierRange(QualifierRange), 716 FirstQualifierFoundInScope(FirstQualifierFoundInScope), 717 Member(Member), MemberLoc(MemberLoc) { 718 if (TemplateArgs) 719 getExplicitTemplateArgumentList()->initializeFrom(*TemplateArgs); 720} 721 722CXXDependentScopeMemberExpr * 723CXXDependentScopeMemberExpr::Create(ASTContext &C, 724 Expr *Base, QualType BaseType, bool IsArrow, 725 SourceLocation OperatorLoc, 726 NestedNameSpecifier *Qualifier, 727 SourceRange QualifierRange, 728 NamedDecl *FirstQualifierFoundInScope, 729 DeclarationName Member, 730 SourceLocation MemberLoc, 731 const TemplateArgumentListInfo *TemplateArgs) { 732 if (!TemplateArgs) 733 return new (C) CXXDependentScopeMemberExpr(C, Base, BaseType, 734 IsArrow, OperatorLoc, 735 Qualifier, QualifierRange, 736 FirstQualifierFoundInScope, 737 Member, MemberLoc); 738 739 std::size_t size = sizeof(CXXDependentScopeMemberExpr); 740 if (TemplateArgs) 741 size += ExplicitTemplateArgumentList::sizeFor(*TemplateArgs); 742 743 void *Mem = C.Allocate(size, llvm::alignof<CXXDependentScopeMemberExpr>()); 744 return new (Mem) CXXDependentScopeMemberExpr(C, Base, BaseType, 745 IsArrow, OperatorLoc, 746 Qualifier, QualifierRange, 747 FirstQualifierFoundInScope, 748 Member, MemberLoc, TemplateArgs); 749} 750 751CXXDependentScopeMemberExpr * 752CXXDependentScopeMemberExpr::CreateEmpty(ASTContext &C, 753 unsigned NumTemplateArgs) { 754 if (NumTemplateArgs == 0) 755 return new (C) CXXDependentScopeMemberExpr(C, 0, QualType(), 756 0, SourceLocation(), 0, 757 SourceRange(), 0, 758 DeclarationName(), 759 SourceLocation()); 760 761 std::size_t size = sizeof(CXXDependentScopeMemberExpr) + 762 ExplicitTemplateArgumentList::sizeFor(NumTemplateArgs); 763 void *Mem = C.Allocate(size, llvm::alignof<CXXDependentScopeMemberExpr>()); 764 CXXDependentScopeMemberExpr *E 765 = new (Mem) CXXDependentScopeMemberExpr(C, 0, QualType(), 766 0, SourceLocation(), 0, 767 SourceRange(), 0, 768 DeclarationName(), 769 SourceLocation(), 0); 770 E->HasExplicitTemplateArgs = true; 771 return E; 772} 773 774Stmt::child_iterator CXXDependentScopeMemberExpr::child_begin() { 775 return child_iterator(&Base); 776} 777 778Stmt::child_iterator CXXDependentScopeMemberExpr::child_end() { 779 if (isImplicitAccess()) 780 return child_iterator(&Base); 781 return child_iterator(&Base + 1); 782} 783 784UnresolvedMemberExpr::UnresolvedMemberExpr(ASTContext &C, QualType T, 785 bool Dependent, 786 bool HasUnresolvedUsing, 787 Expr *Base, QualType BaseType, 788 bool IsArrow, 789 SourceLocation OperatorLoc, 790 NestedNameSpecifier *Qualifier, 791 SourceRange QualifierRange, 792 DeclarationName MemberName, 793 SourceLocation MemberLoc, 794 const TemplateArgumentListInfo *TemplateArgs, 795 UnresolvedSetIterator Begin, 796 UnresolvedSetIterator End) 797 : OverloadExpr(UnresolvedMemberExprClass, C, T, Dependent, 798 Qualifier, QualifierRange, MemberName, MemberLoc, 799 TemplateArgs != 0, Begin, End), 800 IsArrow(IsArrow), HasUnresolvedUsing(HasUnresolvedUsing), 801 Base(Base), BaseType(BaseType), OperatorLoc(OperatorLoc) { 802 if (TemplateArgs) 803 getExplicitTemplateArgs().initializeFrom(*TemplateArgs); 804} 805 806UnresolvedMemberExpr * 807UnresolvedMemberExpr::Create(ASTContext &C, bool Dependent, 808 bool HasUnresolvedUsing, 809 Expr *Base, QualType BaseType, bool IsArrow, 810 SourceLocation OperatorLoc, 811 NestedNameSpecifier *Qualifier, 812 SourceRange QualifierRange, 813 DeclarationName Member, 814 SourceLocation MemberLoc, 815 const TemplateArgumentListInfo *TemplateArgs, 816 UnresolvedSetIterator Begin, 817 UnresolvedSetIterator End) { 818 std::size_t size = sizeof(UnresolvedMemberExpr); 819 if (TemplateArgs) 820 size += ExplicitTemplateArgumentList::sizeFor(*TemplateArgs); 821 822 void *Mem = C.Allocate(size, llvm::alignof<UnresolvedMemberExpr>()); 823 return new (Mem) UnresolvedMemberExpr(C, 824 Dependent ? C.DependentTy : C.OverloadTy, 825 Dependent, HasUnresolvedUsing, Base, BaseType, 826 IsArrow, OperatorLoc, Qualifier, QualifierRange, 827 Member, MemberLoc, TemplateArgs, Begin, End); 828} 829 830UnresolvedMemberExpr * 831UnresolvedMemberExpr::CreateEmpty(ASTContext &C, unsigned NumTemplateArgs) { 832 std::size_t size = sizeof(UnresolvedMemberExpr); 833 if (NumTemplateArgs != 0) 834 size += ExplicitTemplateArgumentList::sizeFor(NumTemplateArgs); 835 836 void *Mem = C.Allocate(size, llvm::alignof<UnresolvedMemberExpr>()); 837 UnresolvedMemberExpr *E = new (Mem) UnresolvedMemberExpr(EmptyShell()); 838 E->HasExplicitTemplateArgs = NumTemplateArgs != 0; 839 return E; 840} 841 842CXXRecordDecl *UnresolvedMemberExpr::getNamingClass() const { 843 // Unlike for UnresolvedLookupExpr, it is very easy to re-derive this. 844 845 // If there was a nested name specifier, it names the naming class. 846 // It can't be dependent: after all, we were actually able to do the 847 // lookup. 848 CXXRecordDecl *Record = 0; 849 if (getQualifier()) { 850 Type *T = getQualifier()->getAsType(); 851 assert(T && "qualifier in member expression does not name type"); 852 Record = T->getAsCXXRecordDecl(); 853 assert(Record && "qualifier in member expression does not name record"); 854 } 855 // Otherwise the naming class must have been the base class. 856 else { 857 QualType BaseType = getBaseType().getNonReferenceType(); 858 if (isArrow()) { 859 const PointerType *PT = BaseType->getAs<PointerType>(); 860 assert(PT && "base of arrow member access is not pointer"); 861 BaseType = PT->getPointeeType(); 862 } 863 864 Record = BaseType->getAsCXXRecordDecl(); 865 assert(Record && "base of member expression does not name record"); 866 } 867 868 return Record; 869} 870 871Stmt::child_iterator UnresolvedMemberExpr::child_begin() { 872 return child_iterator(&Base); 873} 874 875Stmt::child_iterator UnresolvedMemberExpr::child_end() { 876 if (isImplicitAccess()) 877 return child_iterator(&Base); 878 return child_iterator(&Base + 1); 879} 880