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