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