ExprCXX.cpp revision 317ae5eb67c34b9be76e991c7851d72dd355f78d
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_IsClass: // Fallthrough 203 case UTT_IsUnion: 204 if (const RecordType *Record = QueriedType->getAs<RecordType>()) { 205 bool Union = Record->getDecl()->isUnion(); 206 return UTT == UTT_IsUnion ? Union : !Union; 207 } 208 return false; 209 case UTT_IsEnum: return QueriedType->isEnumeralType(); 210 case UTT_IsPolymorphic: 211 if (const RecordType *Record = QueriedType->getAs<RecordType>()) { 212 // Type traits are only parsed in C++, so we've got CXXRecords. 213 return cast<CXXRecordDecl>(Record->getDecl())->isPolymorphic(); 214 } 215 return false; 216 case UTT_IsAbstract: 217 if (const RecordType *RT = QueriedType->getAs<RecordType>()) 218 return cast<CXXRecordDecl>(RT->getDecl())->isAbstract(); 219 return false; 220 case UTT_IsEmpty: 221 if (const RecordType *Record = QueriedType->getAs<RecordType>()) { 222 return !Record->getDecl()->isUnion() 223 && cast<CXXRecordDecl>(Record->getDecl())->isEmpty(); 224 } 225 return false; 226 case UTT_HasTrivialConstructor: 227 // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html: 228 // If __is_pod (type) is true then the trait is true, else if type is 229 // a cv class or union type (or array thereof) with a trivial default 230 // constructor ([class.ctor]) then the trait is true, else it is false. 231 if (QueriedType->isPODType()) 232 return true; 233 if (const RecordType *RT = 234 C.getBaseElementType(QueriedType)->getAs<RecordType>()) 235 return cast<CXXRecordDecl>(RT->getDecl())->hasTrivialConstructor(); 236 return false; 237 case UTT_HasTrivialCopy: 238 // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html: 239 // If __is_pod (type) is true or type is a reference type then 240 // the trait is true, else if type is a cv class or union type 241 // with a trivial copy constructor ([class.copy]) then the trait 242 // is true, else it is false. 243 if (QueriedType->isPODType() || QueriedType->isReferenceType()) 244 return true; 245 if (const RecordType *RT = QueriedType->getAs<RecordType>()) 246 return cast<CXXRecordDecl>(RT->getDecl())->hasTrivialCopyConstructor(); 247 return false; 248 case UTT_HasTrivialAssign: 249 // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html: 250 // If type is const qualified or is a reference type then the 251 // trait is false. Otherwise if __is_pod (type) is true then the 252 // trait is true, else if type is a cv class or union type with 253 // a trivial copy assignment ([class.copy]) then the trait is 254 // true, else it is false. 255 // Note: the const and reference restrictions are interesting, 256 // given that const and reference members don't prevent a class 257 // from having a trivial copy assignment operator (but do cause 258 // errors if the copy assignment operator is actually used, q.v. 259 // [class.copy]p12). 260 261 if (C.getBaseElementType(QueriedType).isConstQualified()) 262 return false; 263 if (QueriedType->isPODType()) 264 return true; 265 if (const RecordType *RT = QueriedType->getAs<RecordType>()) 266 return cast<CXXRecordDecl>(RT->getDecl())->hasTrivialCopyAssignment(); 267 return false; 268 case UTT_HasTrivialDestructor: 269 // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html: 270 // If __is_pod (type) is true or type is a reference type 271 // then the trait is true, else if type is a cv class or union 272 // type (or array thereof) with a trivial destructor 273 // ([class.dtor]) then the trait is true, else it is 274 // false. 275 if (QueriedType->isPODType() || QueriedType->isReferenceType()) 276 return true; 277 if (const RecordType *RT = 278 C.getBaseElementType(QueriedType)->getAs<RecordType>()) 279 return cast<CXXRecordDecl>(RT->getDecl())->hasTrivialDestructor(); 280 return false; 281 } 282} 283 284SourceRange CXXOperatorCallExpr::getSourceRange() const { 285 OverloadedOperatorKind Kind = getOperator(); 286 if (Kind == OO_PlusPlus || Kind == OO_MinusMinus) { 287 if (getNumArgs() == 1) 288 // Prefix operator 289 return SourceRange(getOperatorLoc(), 290 getArg(0)->getSourceRange().getEnd()); 291 else 292 // Postfix operator 293 return SourceRange(getArg(0)->getSourceRange().getEnd(), 294 getOperatorLoc()); 295 } else if (Kind == OO_Call) { 296 return SourceRange(getArg(0)->getSourceRange().getBegin(), getRParenLoc()); 297 } else if (Kind == OO_Subscript) { 298 return SourceRange(getArg(0)->getSourceRange().getBegin(), getRParenLoc()); 299 } else if (getNumArgs() == 1) { 300 return SourceRange(getOperatorLoc(), getArg(0)->getSourceRange().getEnd()); 301 } else if (getNumArgs() == 2) { 302 return SourceRange(getArg(0)->getSourceRange().getBegin(), 303 getArg(1)->getSourceRange().getEnd()); 304 } else { 305 return SourceRange(); 306 } 307} 308 309Expr *CXXMemberCallExpr::getImplicitObjectArgument() { 310 if (MemberExpr *MemExpr = dyn_cast<MemberExpr>(getCallee()->IgnoreParens())) 311 return MemExpr->getBase(); 312 313 // FIXME: Will eventually need to cope with member pointers. 314 return 0; 315} 316 317SourceRange CXXMemberCallExpr::getSourceRange() const { 318 SourceLocation LocStart = getCallee()->getLocStart(); 319 if (LocStart.isInvalid() && getNumArgs() > 0) 320 LocStart = getArg(0)->getLocStart(); 321 return SourceRange(LocStart, getRParenLoc()); 322} 323 324 325//===----------------------------------------------------------------------===// 326// Named casts 327//===----------------------------------------------------------------------===// 328 329/// getCastName - Get the name of the C++ cast being used, e.g., 330/// "static_cast", "dynamic_cast", "reinterpret_cast", or 331/// "const_cast". The returned pointer must not be freed. 332const char *CXXNamedCastExpr::getCastName() const { 333 switch (getStmtClass()) { 334 case CXXStaticCastExprClass: return "static_cast"; 335 case CXXDynamicCastExprClass: return "dynamic_cast"; 336 case CXXReinterpretCastExprClass: return "reinterpret_cast"; 337 case CXXConstCastExprClass: return "const_cast"; 338 default: return "<invalid cast>"; 339 } 340} 341 342CXXTemporary *CXXTemporary::Create(ASTContext &C, 343 const CXXDestructorDecl *Destructor) { 344 return new (C) CXXTemporary(Destructor); 345} 346 347void CXXTemporary::Destroy(ASTContext &Ctx) { 348 this->~CXXTemporary(); 349 Ctx.Deallocate(this); 350} 351 352CXXBindTemporaryExpr *CXXBindTemporaryExpr::Create(ASTContext &C, 353 CXXTemporary *Temp, 354 Expr* SubExpr) { 355 assert(SubExpr->getType()->isRecordType() && 356 "Expression bound to a temporary must have record type!"); 357 358 return new (C) CXXBindTemporaryExpr(Temp, SubExpr); 359} 360 361void CXXBindTemporaryExpr::DoDestroy(ASTContext &C) { 362 Temp->Destroy(C); 363 this->~CXXBindTemporaryExpr(); 364 C.Deallocate(this); 365} 366 367CXXTemporaryObjectExpr::CXXTemporaryObjectExpr(ASTContext &C, 368 CXXConstructorDecl *Cons, 369 QualType writtenTy, 370 SourceLocation tyBeginLoc, 371 Expr **Args, 372 unsigned NumArgs, 373 SourceLocation rParenLoc) 374 : CXXConstructExpr(C, CXXTemporaryObjectExprClass, writtenTy, Cons, 375 false, Args, NumArgs), 376 TyBeginLoc(tyBeginLoc), RParenLoc(rParenLoc) { 377} 378 379CXXConstructExpr *CXXConstructExpr::Create(ASTContext &C, QualType T, 380 CXXConstructorDecl *D, bool Elidable, 381 Expr **Args, unsigned NumArgs) { 382 return new (C) CXXConstructExpr(C, CXXConstructExprClass, T, D, Elidable, 383 Args, NumArgs); 384} 385 386CXXConstructExpr::CXXConstructExpr(ASTContext &C, StmtClass SC, QualType T, 387 CXXConstructorDecl *D, bool elidable, 388 Expr **args, unsigned numargs) 389: Expr(SC, T, 390 T->isDependentType(), 391 (T->isDependentType() || 392 CallExpr::hasAnyValueDependentArguments(args, numargs))), 393 Constructor(D), Elidable(elidable), Args(0), NumArgs(numargs) { 394 if (NumArgs) { 395 Args = new (C) Stmt*[NumArgs]; 396 397 for (unsigned i = 0; i != NumArgs; ++i) { 398 assert(args[i] && "NULL argument in CXXConstructExpr"); 399 Args[i] = args[i]; 400 } 401 } 402} 403 404CXXConstructExpr::CXXConstructExpr(EmptyShell Empty, ASTContext &C, 405 unsigned numargs) 406 : Expr(CXXConstructExprClass, Empty), Args(0), NumArgs(numargs) 407{ 408 if (NumArgs) 409 Args = new (C) Stmt*[NumArgs]; 410} 411 412void CXXConstructExpr::DoDestroy(ASTContext &C) { 413 DestroyChildren(C); 414 if (Args) 415 C.Deallocate(Args); 416 this->~CXXConstructExpr(); 417 C.Deallocate(this); 418} 419 420CXXExprWithTemporaries::CXXExprWithTemporaries(Expr *subexpr, 421 CXXTemporary **temps, 422 unsigned numtemps, 423 bool shoulddestroytemps) 424: Expr(CXXExprWithTemporariesClass, subexpr->getType(), 425 subexpr->isTypeDependent(), subexpr->isValueDependent()), 426 SubExpr(subexpr), Temps(0), NumTemps(numtemps), 427 ShouldDestroyTemps(shoulddestroytemps) { 428 if (NumTemps > 0) { 429 Temps = new CXXTemporary*[NumTemps]; 430 for (unsigned i = 0; i < NumTemps; ++i) 431 Temps[i] = temps[i]; 432 } 433} 434 435CXXExprWithTemporaries *CXXExprWithTemporaries::Create(ASTContext &C, 436 Expr *SubExpr, 437 CXXTemporary **Temps, 438 unsigned NumTemps, 439 bool ShouldDestroyTemps){ 440 return new (C) CXXExprWithTemporaries(SubExpr, Temps, NumTemps, 441 ShouldDestroyTemps); 442} 443 444void CXXExprWithTemporaries::DoDestroy(ASTContext &C) { 445 DestroyChildren(C); 446 this->~CXXExprWithTemporaries(); 447 C.Deallocate(this); 448} 449 450CXXExprWithTemporaries::~CXXExprWithTemporaries() { 451 delete[] Temps; 452} 453 454// CXXBindTemporaryExpr 455Stmt::child_iterator CXXBindTemporaryExpr::child_begin() { 456 return &SubExpr; 457} 458 459Stmt::child_iterator CXXBindTemporaryExpr::child_end() { 460 return &SubExpr + 1; 461} 462 463// CXXConstructExpr 464Stmt::child_iterator CXXConstructExpr::child_begin() { 465 return &Args[0]; 466} 467Stmt::child_iterator CXXConstructExpr::child_end() { 468 return &Args[0]+NumArgs; 469} 470 471// CXXExprWithTemporaries 472Stmt::child_iterator CXXExprWithTemporaries::child_begin() { 473 return &SubExpr; 474} 475 476Stmt::child_iterator CXXExprWithTemporaries::child_end() { 477 return &SubExpr + 1; 478} 479 480CXXUnresolvedConstructExpr::CXXUnresolvedConstructExpr( 481 SourceLocation TyBeginLoc, 482 QualType T, 483 SourceLocation LParenLoc, 484 Expr **Args, 485 unsigned NumArgs, 486 SourceLocation RParenLoc) 487 : Expr(CXXUnresolvedConstructExprClass, T.getNonReferenceType(), 488 T->isDependentType(), true), 489 TyBeginLoc(TyBeginLoc), 490 Type(T), 491 LParenLoc(LParenLoc), 492 RParenLoc(RParenLoc), 493 NumArgs(NumArgs) { 494 Stmt **StoredArgs = reinterpret_cast<Stmt **>(this + 1); 495 memcpy(StoredArgs, Args, sizeof(Expr *) * NumArgs); 496} 497 498CXXUnresolvedConstructExpr * 499CXXUnresolvedConstructExpr::Create(ASTContext &C, 500 SourceLocation TyBegin, 501 QualType T, 502 SourceLocation LParenLoc, 503 Expr **Args, 504 unsigned NumArgs, 505 SourceLocation RParenLoc) { 506 void *Mem = C.Allocate(sizeof(CXXUnresolvedConstructExpr) + 507 sizeof(Expr *) * NumArgs); 508 return new (Mem) CXXUnresolvedConstructExpr(TyBegin, T, LParenLoc, 509 Args, NumArgs, RParenLoc); 510} 511 512Stmt::child_iterator CXXUnresolvedConstructExpr::child_begin() { 513 return child_iterator(reinterpret_cast<Stmt **>(this + 1)); 514} 515 516Stmt::child_iterator CXXUnresolvedConstructExpr::child_end() { 517 return child_iterator(reinterpret_cast<Stmt **>(this + 1) + NumArgs); 518} 519 520CXXDependentScopeMemberExpr::CXXDependentScopeMemberExpr(ASTContext &C, 521 Expr *Base, QualType BaseType, 522 bool IsArrow, 523 SourceLocation OperatorLoc, 524 NestedNameSpecifier *Qualifier, 525 SourceRange QualifierRange, 526 NamedDecl *FirstQualifierFoundInScope, 527 DeclarationName Member, 528 SourceLocation MemberLoc, 529 const TemplateArgumentListInfo *TemplateArgs) 530 : Expr(CXXDependentScopeMemberExprClass, C.DependentTy, true, true), 531 Base(Base), BaseType(BaseType), IsArrow(IsArrow), 532 HasExplicitTemplateArgs(TemplateArgs != 0), 533 OperatorLoc(OperatorLoc), 534 Qualifier(Qualifier), QualifierRange(QualifierRange), 535 FirstQualifierFoundInScope(FirstQualifierFoundInScope), 536 Member(Member), MemberLoc(MemberLoc) { 537 if (TemplateArgs) 538 getExplicitTemplateArgumentList()->initializeFrom(*TemplateArgs); 539} 540 541CXXDependentScopeMemberExpr * 542CXXDependentScopeMemberExpr::Create(ASTContext &C, 543 Expr *Base, QualType BaseType, bool IsArrow, 544 SourceLocation OperatorLoc, 545 NestedNameSpecifier *Qualifier, 546 SourceRange QualifierRange, 547 NamedDecl *FirstQualifierFoundInScope, 548 DeclarationName Member, 549 SourceLocation MemberLoc, 550 const TemplateArgumentListInfo *TemplateArgs) { 551 if (!TemplateArgs) 552 return new (C) CXXDependentScopeMemberExpr(C, Base, BaseType, 553 IsArrow, OperatorLoc, 554 Qualifier, QualifierRange, 555 FirstQualifierFoundInScope, 556 Member, MemberLoc); 557 558 std::size_t size = sizeof(CXXDependentScopeMemberExpr); 559 if (TemplateArgs) 560 size += ExplicitTemplateArgumentList::sizeFor(*TemplateArgs); 561 562 void *Mem = C.Allocate(size, llvm::alignof<CXXDependentScopeMemberExpr>()); 563 return new (Mem) CXXDependentScopeMemberExpr(C, Base, BaseType, 564 IsArrow, OperatorLoc, 565 Qualifier, QualifierRange, 566 FirstQualifierFoundInScope, 567 Member, MemberLoc, TemplateArgs); 568} 569 570Stmt::child_iterator CXXDependentScopeMemberExpr::child_begin() { 571 return child_iterator(&Base); 572} 573 574Stmt::child_iterator CXXDependentScopeMemberExpr::child_end() { 575 if (isImplicitAccess()) 576 return child_iterator(&Base); 577 return child_iterator(&Base + 1); 578} 579 580UnresolvedMemberExpr::UnresolvedMemberExpr(QualType T, bool Dependent, 581 bool HasUnresolvedUsing, 582 Expr *Base, QualType BaseType, 583 bool IsArrow, 584 SourceLocation OperatorLoc, 585 NestedNameSpecifier *Qualifier, 586 SourceRange QualifierRange, 587 DeclarationName MemberName, 588 SourceLocation MemberLoc, 589 const TemplateArgumentListInfo *TemplateArgs) 590 : Expr(UnresolvedMemberExprClass, T, Dependent, Dependent), 591 Base(Base), BaseType(BaseType), IsArrow(IsArrow), 592 HasUnresolvedUsing(HasUnresolvedUsing), 593 HasExplicitTemplateArgs(TemplateArgs != 0), 594 OperatorLoc(OperatorLoc), 595 Qualifier(Qualifier), QualifierRange(QualifierRange), 596 MemberName(MemberName), MemberLoc(MemberLoc) { 597 if (TemplateArgs) 598 getExplicitTemplateArgs()->initializeFrom(*TemplateArgs); 599} 600 601UnresolvedMemberExpr * 602UnresolvedMemberExpr::Create(ASTContext &C, bool Dependent, 603 bool HasUnresolvedUsing, 604 Expr *Base, QualType BaseType, bool IsArrow, 605 SourceLocation OperatorLoc, 606 NestedNameSpecifier *Qualifier, 607 SourceRange QualifierRange, 608 DeclarationName Member, 609 SourceLocation MemberLoc, 610 const TemplateArgumentListInfo *TemplateArgs) { 611 std::size_t size = sizeof(UnresolvedMemberExpr); 612 if (TemplateArgs) 613 size += ExplicitTemplateArgumentList::sizeFor(*TemplateArgs); 614 615 void *Mem = C.Allocate(size, llvm::alignof<UnresolvedMemberExpr>()); 616 return new (Mem) UnresolvedMemberExpr( 617 Dependent ? C.DependentTy : C.OverloadTy, 618 Dependent, HasUnresolvedUsing, Base, BaseType, 619 IsArrow, OperatorLoc, Qualifier, QualifierRange, 620 Member, MemberLoc, TemplateArgs); 621} 622 623Stmt::child_iterator UnresolvedMemberExpr::child_begin() { 624 return child_iterator(&Base); 625} 626 627Stmt::child_iterator UnresolvedMemberExpr::child_end() { 628 if (isImplicitAccess()) 629 return child_iterator(&Base); 630 return child_iterator(&Base + 1); 631} 632