1 //===--- ExprCXX.cpp - (C++) Expression AST Node Implementation -----------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file implements the subclesses of Expr class declared in ExprCXX.h
12 //===----------------------------------------------------------------------===//
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"
19 using namespace clang
;
22 //===----------------------------------------------------------------------===//
23 // Child Iterators for iterating over subexpressions/substatements
24 //===----------------------------------------------------------------------===//
26 QualType
CXXTypeidExpr::getTypeOperand() const {
27 assert(isTypeOperand() && "Cannot call getTypeOperand for typeid(expr)");
28 return Operand
.get
<TypeSourceInfo
*>()->getType().getNonReferenceType()
29 .getUnqualifiedType();
32 // CXXTypeidExpr - has child iterators if the operand is an expression
33 Stmt::child_iterator
CXXTypeidExpr::child_begin() {
34 return isTypeOperand() ? child_iterator()
35 : reinterpret_cast<Stmt
**>(&Operand
);
37 Stmt::child_iterator
CXXTypeidExpr::child_end() {
38 return isTypeOperand() ? child_iterator()
39 : reinterpret_cast<Stmt
**>(&Operand
) + 1;
43 Stmt::child_iterator
CXXBoolLiteralExpr::child_begin() {
44 return child_iterator();
46 Stmt::child_iterator
CXXBoolLiteralExpr::child_end() {
47 return child_iterator();
50 // CXXNullPtrLiteralExpr
51 Stmt::child_iterator
CXXNullPtrLiteralExpr::child_begin() {
52 return child_iterator();
54 Stmt::child_iterator
CXXNullPtrLiteralExpr::child_end() {
55 return child_iterator();
59 Stmt::child_iterator
CXXThisExpr::child_begin() { return child_iterator(); }
60 Stmt::child_iterator
CXXThisExpr::child_end() { return child_iterator(); }
63 Stmt::child_iterator
CXXThrowExpr::child_begin() { return &Op
; }
64 Stmt::child_iterator
CXXThrowExpr::child_end() {
65 // If Op is 0, we are processing throw; which has no children.
66 return Op
? &Op
+1 : &Op
;
70 Stmt::child_iterator
CXXDefaultArgExpr::child_begin() {
71 return child_iterator();
73 Stmt::child_iterator
CXXDefaultArgExpr::child_end() {
74 return child_iterator();
77 // CXXZeroInitValueExpr
78 Stmt::child_iterator
CXXZeroInitValueExpr::child_begin() {
79 return child_iterator();
81 Stmt::child_iterator
CXXZeroInitValueExpr::child_end() {
82 return child_iterator();
86 CXXNewExpr::CXXNewExpr(ASTContext
&C
, bool globalNew
, FunctionDecl
*operatorNew
,
87 Expr
**placementArgs
, unsigned numPlaceArgs
,
88 bool parenTypeId
, Expr
*arraySize
,
89 CXXConstructorDecl
*constructor
, bool initializer
,
90 Expr
**constructorArgs
, unsigned numConsArgs
,
91 FunctionDecl
*operatorDelete
, QualType ty
,
92 SourceLocation startLoc
, SourceLocation endLoc
)
93 : Expr(CXXNewExprClass
, ty
, ty
->isDependentType(), ty
->isDependentType()),
94 GlobalNew(globalNew
), ParenTypeId(parenTypeId
),
95 Initializer(initializer
), SubExprs(0), OperatorNew(operatorNew
),
96 OperatorDelete(operatorDelete
), Constructor(constructor
),
97 StartLoc(startLoc
), EndLoc(endLoc
) {
99 AllocateArgsArray(C
, arraySize
!= 0, numPlaceArgs
, numConsArgs
);
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
];
109 void CXXNewExpr::AllocateArgsArray(ASTContext
&C
, bool isArray
,
110 unsigned numPlaceArgs
, unsigned numConsArgs
){
111 assert(SubExprs
== 0 && "SubExprs already allocated");
113 NumPlacementArgs
= numPlaceArgs
;
114 NumConstructorArgs
= numConsArgs
;
116 unsigned TotalSize
= Array
+ NumPlacementArgs
+ NumConstructorArgs
;
117 SubExprs
= new (C
) Stmt
*[TotalSize
];
121 void CXXNewExpr::DoDestroy(ASTContext
&C
) {
124 C
.Deallocate(SubExprs
);
126 C
.Deallocate((void*)this);
129 Stmt::child_iterator
CXXNewExpr::child_begin() { return &SubExprs
[0]; }
130 Stmt::child_iterator
CXXNewExpr::child_end() {
131 return &SubExprs
[0] + Array
+ getNumPlacementArgs() + getNumConstructorArgs();
135 Stmt::child_iterator
CXXDeleteExpr::child_begin() { return &Argument
; }
136 Stmt::child_iterator
CXXDeleteExpr::child_end() { return &Argument
+1; }
138 // CXXPseudoDestructorExpr
139 Stmt::child_iterator
CXXPseudoDestructorExpr::child_begin() { return &Base
; }
140 Stmt::child_iterator
CXXPseudoDestructorExpr::child_end() {
144 PseudoDestructorTypeStorage::PseudoDestructorTypeStorage(TypeSourceInfo
*Info
)
147 Location
= Info
->getTypeLoc().getLocalSourceRange().getBegin();
150 QualType
CXXPseudoDestructorExpr::getDestroyedType() const {
151 if (TypeSourceInfo
*TInfo
= DestroyedType
.getTypeSourceInfo())
152 return TInfo
->getType();
157 SourceRange
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
);
165 // UnresolvedLookupExpr
166 UnresolvedLookupExpr
*
167 UnresolvedLookupExpr::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
)
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
,
185 /*ExplicitTemplateArgs*/ true,
188 reinterpret_cast<ExplicitTemplateArgumentList
*>(ULE
+1)->initializeFrom(Args
);
193 OverloadExpr::OverloadExpr(StmtClass K
, ASTContext
&C
, QualType T
,
194 bool Dependent
, NestedNameSpecifier
*Qualifier
,
195 SourceRange QRange
, DeclarationName Name
,
196 SourceLocation NameLoc
, bool HasTemplateArgs
,
197 UnresolvedSetIterator Begin
,
198 UnresolvedSetIterator End
)
199 : Expr(K
, T
, Dependent
, Dependent
),
200 Results(0), NumResults(0), Name(Name
), Qualifier(Qualifier
),
201 QualifierRange(QRange
), NameLoc(NameLoc
),
202 HasExplicitTemplateArgs(HasTemplateArgs
)
204 initializeResults(C
, Begin
, End
);
207 void OverloadExpr::initializeResults(ASTContext
&C
,
208 UnresolvedSetIterator Begin
,
209 UnresolvedSetIterator End
) {
210 assert(Results
== 0 && "Results already initialized!");
211 NumResults
= End
- Begin
;
213 Results
= static_cast<DeclAccessPair
*>(
214 C
.Allocate(sizeof(DeclAccessPair
) * NumResults
,
215 llvm::alignof
<DeclAccessPair
>()));
216 memcpy(Results
, &*Begin
.getIterator(),
217 NumResults
* sizeof(DeclAccessPair
));
222 bool OverloadExpr::ComputeDependence(UnresolvedSetIterator Begin
,
223 UnresolvedSetIterator End
,
224 const TemplateArgumentListInfo
*Args
) {
225 for (UnresolvedSetImpl::const_iterator I
= Begin
; I
!= End
; ++I
)
226 if ((*I
)->getDeclContext()->isDependentContext())
229 if (Args
&& TemplateSpecializationType::anyDependentTemplateArguments(*Args
))
235 CXXRecordDecl
*OverloadExpr::getNamingClass() const {
236 if (isa
<UnresolvedLookupExpr
>(this))
237 return cast
<UnresolvedLookupExpr
>(this)->getNamingClass();
239 return cast
<UnresolvedMemberExpr
>(this)->getNamingClass();
242 Stmt::child_iterator
UnresolvedLookupExpr::child_begin() {
243 return child_iterator();
245 Stmt::child_iterator
UnresolvedLookupExpr::child_end() {
246 return child_iterator();
248 // UnaryTypeTraitExpr
249 Stmt::child_iterator
UnaryTypeTraitExpr::child_begin() {
250 return child_iterator();
252 Stmt::child_iterator
UnaryTypeTraitExpr::child_end() {
253 return child_iterator();
256 // DependentScopeDeclRefExpr
257 DependentScopeDeclRefExpr
*
258 DependentScopeDeclRefExpr::Create(ASTContext
&C
,
259 NestedNameSpecifier
*Qualifier
,
260 SourceRange QualifierRange
,
261 DeclarationName Name
,
262 SourceLocation NameLoc
,
263 const TemplateArgumentListInfo
*Args
) {
264 std::size_t size
= sizeof(DependentScopeDeclRefExpr
);
265 if (Args
) size
+= ExplicitTemplateArgumentList::sizeFor(*Args
);
266 void *Mem
= C
.Allocate(size
);
268 DependentScopeDeclRefExpr
*DRE
269 = new (Mem
) DependentScopeDeclRefExpr(C
.DependentTy
,
270 Qualifier
, QualifierRange
,
275 reinterpret_cast<ExplicitTemplateArgumentList
*>(DRE
+1)
276 ->initializeFrom(*Args
);
281 StmtIterator
DependentScopeDeclRefExpr::child_begin() {
282 return child_iterator();
285 StmtIterator
DependentScopeDeclRefExpr::child_end() {
286 return child_iterator();
289 bool UnaryTypeTraitExpr::EvaluateTrait(ASTContext
& C
) const {
291 default: assert(false && "Unknown type trait or not implemented");
292 case UTT_IsPOD
: return QueriedType
->isPODType();
293 case UTT_IsLiteral
: return QueriedType
->isLiteralType();
294 case UTT_IsClass
: // Fallthrough
296 if (const RecordType
*Record
= QueriedType
->getAs
<RecordType
>()) {
297 bool Union
= Record
->getDecl()->isUnion();
298 return UTT
== UTT_IsUnion
? Union
: !Union
;
301 case UTT_IsEnum
: return QueriedType
->isEnumeralType();
302 case UTT_IsPolymorphic
:
303 if (const RecordType
*Record
= QueriedType
->getAs
<RecordType
>()) {
304 // Type traits are only parsed in C++, so we've got CXXRecords.
305 return cast
<CXXRecordDecl
>(Record
->getDecl())->isPolymorphic();
309 if (const RecordType
*RT
= QueriedType
->getAs
<RecordType
>())
310 return cast
<CXXRecordDecl
>(RT
->getDecl())->isAbstract();
313 if (const RecordType
*Record
= QueriedType
->getAs
<RecordType
>()) {
314 return !Record
->getDecl()->isUnion()
315 && cast
<CXXRecordDecl
>(Record
->getDecl())->isEmpty();
318 case UTT_HasTrivialConstructor
:
319 // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
320 // If __is_pod (type) is true then the trait is true, else if type is
321 // a cv class or union type (or array thereof) with a trivial default
322 // constructor ([class.ctor]) then the trait is true, else it is false.
323 if (QueriedType
->isPODType())
325 if (const RecordType
*RT
=
326 C
.getBaseElementType(QueriedType
)->getAs
<RecordType
>())
327 return cast
<CXXRecordDecl
>(RT
->getDecl())->hasTrivialConstructor();
329 case UTT_HasTrivialCopy
:
330 // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
331 // If __is_pod (type) is true or type is a reference type then
332 // the trait is true, else if type is a cv class or union type
333 // with a trivial copy constructor ([class.copy]) then the trait
334 // is true, else it is false.
335 if (QueriedType
->isPODType() || QueriedType
->isReferenceType())
337 if (const RecordType
*RT
= QueriedType
->getAs
<RecordType
>())
338 return cast
<CXXRecordDecl
>(RT
->getDecl())->hasTrivialCopyConstructor();
340 case UTT_HasTrivialAssign
:
341 // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
342 // If type is const qualified or is a reference type then the
343 // trait is false. Otherwise if __is_pod (type) is true then the
344 // trait is true, else if type is a cv class or union type with
345 // a trivial copy assignment ([class.copy]) then the trait is
346 // true, else it is false.
347 // Note: the const and reference restrictions are interesting,
348 // given that const and reference members don't prevent a class
349 // from having a trivial copy assignment operator (but do cause
350 // errors if the copy assignment operator is actually used, q.v.
353 if (C
.getBaseElementType(QueriedType
).isConstQualified())
355 if (QueriedType
->isPODType())
357 if (const RecordType
*RT
= QueriedType
->getAs
<RecordType
>())
358 return cast
<CXXRecordDecl
>(RT
->getDecl())->hasTrivialCopyAssignment();
360 case UTT_HasTrivialDestructor
:
361 // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
362 // If __is_pod (type) is true or type is a reference type
363 // then the trait is true, else if type is a cv class or union
364 // type (or array thereof) with a trivial destructor
365 // ([class.dtor]) then the trait is true, else it is
367 if (QueriedType
->isPODType() || QueriedType
->isReferenceType())
369 if (const RecordType
*RT
=
370 C
.getBaseElementType(QueriedType
)->getAs
<RecordType
>())
371 return cast
<CXXRecordDecl
>(RT
->getDecl())->hasTrivialDestructor();
376 SourceRange
CXXConstructExpr::getSourceRange() const {
377 // FIXME: Should we know where the parentheses are, if there are any?
378 for (std::reverse_iterator
<Stmt
**> I(&Args
[NumArgs
]), E(&Args
[0]); I
!=E
;++I
) {
379 // Ignore CXXDefaultExprs when computing the range, as they don't
381 if (!isa
<CXXDefaultArgExpr
>(*I
))
382 return SourceRange(Loc
, (*I
)->getLocEnd());
385 return SourceRange(Loc
);
388 SourceRange
CXXOperatorCallExpr::getSourceRange() const {
389 OverloadedOperatorKind Kind
= getOperator();
390 if (Kind
== OO_PlusPlus
|| Kind
== OO_MinusMinus
) {
391 if (getNumArgs() == 1)
393 return SourceRange(getOperatorLoc(),
394 getArg(0)->getSourceRange().getEnd());
397 return SourceRange(getArg(0)->getSourceRange().getEnd(),
399 } else if (Kind
== OO_Call
) {
400 return SourceRange(getArg(0)->getSourceRange().getBegin(), getRParenLoc());
401 } else if (Kind
== OO_Subscript
) {
402 return SourceRange(getArg(0)->getSourceRange().getBegin(), getRParenLoc());
403 } else if (getNumArgs() == 1) {
404 return SourceRange(getOperatorLoc(), getArg(0)->getSourceRange().getEnd());
405 } else if (getNumArgs() == 2) {
406 return SourceRange(getArg(0)->getSourceRange().getBegin(),
407 getArg(1)->getSourceRange().getEnd());
409 return SourceRange();
413 Expr
*CXXMemberCallExpr::getImplicitObjectArgument() {
414 if (MemberExpr
*MemExpr
= dyn_cast
<MemberExpr
>(getCallee()->IgnoreParens()))
415 return MemExpr
->getBase();
417 // FIXME: Will eventually need to cope with member pointers.
421 SourceRange
CXXMemberCallExpr::getSourceRange() const {
422 SourceLocation LocStart
= getCallee()->getLocStart();
423 if (LocStart
.isInvalid() && getNumArgs() > 0)
424 LocStart
= getArg(0)->getLocStart();
425 return SourceRange(LocStart
, getRParenLoc());
429 //===----------------------------------------------------------------------===//
431 //===----------------------------------------------------------------------===//
433 /// getCastName - Get the name of the C++ cast being used, e.g.,
434 /// "static_cast", "dynamic_cast", "reinterpret_cast", or
435 /// "const_cast". The returned pointer must not be freed.
436 const char *CXXNamedCastExpr::getCastName() const {
437 switch (getStmtClass()) {
438 case CXXStaticCastExprClass
: return "static_cast";
439 case CXXDynamicCastExprClass
: return "dynamic_cast";
440 case CXXReinterpretCastExprClass
: return "reinterpret_cast";
441 case CXXConstCastExprClass
: return "const_cast";
442 default: return "<invalid cast>";
447 CXXDefaultArgExpr::Create(ASTContext
&C
, SourceLocation Loc
,
448 ParmVarDecl
*Param
, Expr
*SubExpr
) {
449 void *Mem
= C
.Allocate(sizeof(CXXDefaultArgExpr
) + sizeof(Stmt
*));
450 return new (Mem
) CXXDefaultArgExpr(CXXDefaultArgExprClass
, Loc
, Param
,
454 void CXXDefaultArgExpr::DoDestroy(ASTContext
&C
) {
456 getExpr()->Destroy(C
);
457 this->~CXXDefaultArgExpr();
461 CXXTemporary
*CXXTemporary::Create(ASTContext
&C
,
462 const CXXDestructorDecl
*Destructor
) {
463 return new (C
) CXXTemporary(Destructor
);
466 void CXXTemporary::Destroy(ASTContext
&Ctx
) {
467 this->~CXXTemporary();
468 Ctx
.Deallocate(this);
471 CXXBindTemporaryExpr
*CXXBindTemporaryExpr::Create(ASTContext
&C
,
474 assert(SubExpr
->getType()->isRecordType() &&
475 "Expression bound to a temporary must have record type!");
477 return new (C
) CXXBindTemporaryExpr(Temp
, SubExpr
);
480 void CXXBindTemporaryExpr::DoDestroy(ASTContext
&C
) {
482 this->~CXXBindTemporaryExpr();
486 CXXBindReferenceExpr
*CXXBindReferenceExpr::Create(ASTContext
&C
, Expr
*SubExpr
,
487 bool ExtendsLifetime
,
488 bool RequiresTemporaryCopy
) {
489 return new (C
) CXXBindReferenceExpr(SubExpr
,
491 RequiresTemporaryCopy
);
494 void CXXBindReferenceExpr::DoDestroy(ASTContext
&C
) {
495 this->~CXXBindReferenceExpr();
499 CXXTemporaryObjectExpr::CXXTemporaryObjectExpr(ASTContext
&C
,
500 CXXConstructorDecl
*Cons
,
502 SourceLocation tyBeginLoc
,
505 SourceLocation rParenLoc
,
506 bool ZeroInitialization
)
507 : CXXConstructExpr(C
, CXXTemporaryObjectExprClass
, writtenTy
, tyBeginLoc
,
508 Cons
, false, Args
, NumArgs
, ZeroInitialization
),
509 TyBeginLoc(tyBeginLoc
), RParenLoc(rParenLoc
) {
512 CXXConstructExpr
*CXXConstructExpr::Create(ASTContext
&C
, QualType T
,
514 CXXConstructorDecl
*D
, bool Elidable
,
515 Expr
**Args
, unsigned NumArgs
,
516 bool ZeroInitialization
,
517 ConstructionKind ConstructKind
) {
518 return new (C
) CXXConstructExpr(C
, CXXConstructExprClass
, T
, Loc
, D
,
519 Elidable
, Args
, NumArgs
, ZeroInitialization
,
523 CXXConstructExpr::CXXConstructExpr(ASTContext
&C
, StmtClass SC
, QualType T
,
525 CXXConstructorDecl
*D
, bool elidable
,
526 Expr
**args
, unsigned numargs
,
527 bool ZeroInitialization
,
528 ConstructionKind ConstructKind
)
530 T
->isDependentType(),
531 (T
->isDependentType() ||
532 CallExpr::hasAnyValueDependentArguments(args
, numargs
))),
533 Constructor(D
), Loc(Loc
), Elidable(elidable
),
534 ZeroInitialization(ZeroInitialization
), ConstructKind(ConstructKind
),
535 Args(0), NumArgs(numargs
)
538 Args
= new (C
) Stmt
*[NumArgs
];
540 for (unsigned i
= 0; i
!= NumArgs
; ++i
) {
541 assert(args
[i
] && "NULL argument in CXXConstructExpr");
547 CXXConstructExpr::CXXConstructExpr(EmptyShell Empty
, ASTContext
&C
,
549 : Expr(CXXConstructExprClass
, Empty
), Args(0), NumArgs(numargs
)
552 Args
= new (C
) Stmt
*[NumArgs
];
555 void CXXConstructExpr::DoDestroy(ASTContext
&C
) {
559 this->~CXXConstructExpr();
563 CXXExprWithTemporaries::CXXExprWithTemporaries(ASTContext
&C
,
565 CXXTemporary
**temps
,
567 : Expr(CXXExprWithTemporariesClass
, subexpr
->getType(),
568 subexpr
->isTypeDependent(), subexpr
->isValueDependent()),
569 SubExpr(subexpr
), Temps(0), NumTemps(0) {
571 setNumTemporaries(C
, numtemps
);
572 for (unsigned i
= 0; i
!= numtemps
; ++i
)
577 void CXXExprWithTemporaries::setNumTemporaries(ASTContext
&C
, unsigned N
) {
578 assert(Temps
== 0 && "Cannot resize with this");
580 Temps
= new (C
) CXXTemporary
*[NumTemps
];
584 CXXExprWithTemporaries
*CXXExprWithTemporaries::Create(ASTContext
&C
,
586 CXXTemporary
**Temps
,
588 return new (C
) CXXExprWithTemporaries(C
, SubExpr
, Temps
, NumTemps
);
591 void CXXExprWithTemporaries::DoDestroy(ASTContext
&C
) {
595 this->~CXXExprWithTemporaries();
599 CXXExprWithTemporaries::~CXXExprWithTemporaries() {}
601 // CXXBindTemporaryExpr
602 Stmt::child_iterator
CXXBindTemporaryExpr::child_begin() {
606 Stmt::child_iterator
CXXBindTemporaryExpr::child_end() {
610 // CXXBindReferenceExpr
611 Stmt::child_iterator
CXXBindReferenceExpr::child_begin() {
615 Stmt::child_iterator
CXXBindReferenceExpr::child_end() {
620 Stmt::child_iterator
CXXConstructExpr::child_begin() {
623 Stmt::child_iterator
CXXConstructExpr::child_end() {
624 return &Args
[0]+NumArgs
;
627 // CXXExprWithTemporaries
628 Stmt::child_iterator
CXXExprWithTemporaries::child_begin() {
632 Stmt::child_iterator
CXXExprWithTemporaries::child_end() {
636 CXXUnresolvedConstructExpr::CXXUnresolvedConstructExpr(
637 SourceLocation TyBeginLoc
,
639 SourceLocation LParenLoc
,
642 SourceLocation RParenLoc
)
643 : Expr(CXXUnresolvedConstructExprClass
, T
.getNonReferenceType(),
644 T
->isDependentType(), true),
645 TyBeginLoc(TyBeginLoc
),
647 LParenLoc(LParenLoc
),
648 RParenLoc(RParenLoc
),
650 Stmt
**StoredArgs
= reinterpret_cast<Stmt
**>(this + 1);
651 memcpy(StoredArgs
, Args
, sizeof(Expr
*) * NumArgs
);
654 CXXUnresolvedConstructExpr
*
655 CXXUnresolvedConstructExpr::Create(ASTContext
&C
,
656 SourceLocation TyBegin
,
658 SourceLocation LParenLoc
,
661 SourceLocation RParenLoc
) {
662 void *Mem
= C
.Allocate(sizeof(CXXUnresolvedConstructExpr
) +
663 sizeof(Expr
*) * NumArgs
);
664 return new (Mem
) CXXUnresolvedConstructExpr(TyBegin
, T
, LParenLoc
,
665 Args
, NumArgs
, RParenLoc
);
668 CXXUnresolvedConstructExpr
*
669 CXXUnresolvedConstructExpr::CreateEmpty(ASTContext
&C
, unsigned NumArgs
) {
670 Stmt::EmptyShell Empty
;
671 void *Mem
= C
.Allocate(sizeof(CXXUnresolvedConstructExpr
) +
672 sizeof(Expr
*) * NumArgs
);
673 return new (Mem
) CXXUnresolvedConstructExpr(Empty
, NumArgs
);
676 Stmt::child_iterator
CXXUnresolvedConstructExpr::child_begin() {
677 return child_iterator(reinterpret_cast<Stmt
**>(this + 1));
680 Stmt::child_iterator
CXXUnresolvedConstructExpr::child_end() {
681 return child_iterator(reinterpret_cast<Stmt
**>(this + 1) + NumArgs
);
684 CXXDependentScopeMemberExpr::CXXDependentScopeMemberExpr(ASTContext
&C
,
685 Expr
*Base
, QualType BaseType
,
687 SourceLocation OperatorLoc
,
688 NestedNameSpecifier
*Qualifier
,
689 SourceRange QualifierRange
,
690 NamedDecl
*FirstQualifierFoundInScope
,
691 DeclarationName Member
,
692 SourceLocation MemberLoc
,
693 const TemplateArgumentListInfo
*TemplateArgs
)
694 : Expr(CXXDependentScopeMemberExprClass
, C
.DependentTy
, true, true),
695 Base(Base
), BaseType(BaseType
), IsArrow(IsArrow
),
696 HasExplicitTemplateArgs(TemplateArgs
!= 0),
697 OperatorLoc(OperatorLoc
),
698 Qualifier(Qualifier
), QualifierRange(QualifierRange
),
699 FirstQualifierFoundInScope(FirstQualifierFoundInScope
),
700 Member(Member
), MemberLoc(MemberLoc
) {
702 getExplicitTemplateArgumentList()->initializeFrom(*TemplateArgs
);
705 CXXDependentScopeMemberExpr
*
706 CXXDependentScopeMemberExpr::Create(ASTContext
&C
,
707 Expr
*Base
, QualType BaseType
, bool IsArrow
,
708 SourceLocation OperatorLoc
,
709 NestedNameSpecifier
*Qualifier
,
710 SourceRange QualifierRange
,
711 NamedDecl
*FirstQualifierFoundInScope
,
712 DeclarationName Member
,
713 SourceLocation MemberLoc
,
714 const TemplateArgumentListInfo
*TemplateArgs
) {
716 return new (C
) CXXDependentScopeMemberExpr(C
, Base
, BaseType
,
717 IsArrow
, OperatorLoc
,
718 Qualifier
, QualifierRange
,
719 FirstQualifierFoundInScope
,
722 std::size_t size
= sizeof(CXXDependentScopeMemberExpr
);
724 size
+= ExplicitTemplateArgumentList::sizeFor(*TemplateArgs
);
726 void *Mem
= C
.Allocate(size
, llvm::alignof
<CXXDependentScopeMemberExpr
>());
727 return new (Mem
) CXXDependentScopeMemberExpr(C
, Base
, BaseType
,
728 IsArrow
, OperatorLoc
,
729 Qualifier
, QualifierRange
,
730 FirstQualifierFoundInScope
,
731 Member
, MemberLoc
, TemplateArgs
);
734 CXXDependentScopeMemberExpr
*
735 CXXDependentScopeMemberExpr::CreateEmpty(ASTContext
&C
,
736 unsigned NumTemplateArgs
) {
737 if (NumTemplateArgs
== 0)
738 return new (C
) CXXDependentScopeMemberExpr(C
, 0, QualType(),
739 0, SourceLocation(), 0,
744 std::size_t size
= sizeof(CXXDependentScopeMemberExpr
) +
745 ExplicitTemplateArgumentList::sizeFor(NumTemplateArgs
);
746 void *Mem
= C
.Allocate(size
, llvm::alignof
<CXXDependentScopeMemberExpr
>());
747 CXXDependentScopeMemberExpr
*E
748 = new (Mem
) CXXDependentScopeMemberExpr(C
, 0, QualType(),
749 0, SourceLocation(), 0,
752 SourceLocation(), 0);
753 E
->HasExplicitTemplateArgs
= true;
757 Stmt::child_iterator
CXXDependentScopeMemberExpr::child_begin() {
758 return child_iterator(&Base
);
761 Stmt::child_iterator
CXXDependentScopeMemberExpr::child_end() {
762 if (isImplicitAccess())
763 return child_iterator(&Base
);
764 return child_iterator(&Base
+ 1);
767 UnresolvedMemberExpr::UnresolvedMemberExpr(ASTContext
&C
, QualType T
,
769 bool HasUnresolvedUsing
,
770 Expr
*Base
, QualType BaseType
,
772 SourceLocation OperatorLoc
,
773 NestedNameSpecifier
*Qualifier
,
774 SourceRange QualifierRange
,
775 DeclarationName MemberName
,
776 SourceLocation MemberLoc
,
777 const TemplateArgumentListInfo
*TemplateArgs
,
778 UnresolvedSetIterator Begin
,
779 UnresolvedSetIterator End
)
780 : OverloadExpr(UnresolvedMemberExprClass
, C
, T
, Dependent
,
781 Qualifier
, QualifierRange
, MemberName
, MemberLoc
,
782 TemplateArgs
!= 0, Begin
, End
),
783 IsArrow(IsArrow
), HasUnresolvedUsing(HasUnresolvedUsing
),
784 Base(Base
), BaseType(BaseType
), OperatorLoc(OperatorLoc
) {
786 getExplicitTemplateArgs().initializeFrom(*TemplateArgs
);
789 UnresolvedMemberExpr
*
790 UnresolvedMemberExpr::Create(ASTContext
&C
, bool Dependent
,
791 bool HasUnresolvedUsing
,
792 Expr
*Base
, QualType BaseType
, bool IsArrow
,
793 SourceLocation OperatorLoc
,
794 NestedNameSpecifier
*Qualifier
,
795 SourceRange QualifierRange
,
796 DeclarationName Member
,
797 SourceLocation MemberLoc
,
798 const TemplateArgumentListInfo
*TemplateArgs
,
799 UnresolvedSetIterator Begin
,
800 UnresolvedSetIterator End
) {
801 std::size_t size
= sizeof(UnresolvedMemberExpr
);
803 size
+= ExplicitTemplateArgumentList::sizeFor(*TemplateArgs
);
805 void *Mem
= C
.Allocate(size
, llvm::alignof
<UnresolvedMemberExpr
>());
806 return new (Mem
) UnresolvedMemberExpr(C
,
807 Dependent
? C
.DependentTy
: C
.OverloadTy
,
808 Dependent
, HasUnresolvedUsing
, Base
, BaseType
,
809 IsArrow
, OperatorLoc
, Qualifier
, QualifierRange
,
810 Member
, MemberLoc
, TemplateArgs
, Begin
, End
);
813 UnresolvedMemberExpr
*
814 UnresolvedMemberExpr::CreateEmpty(ASTContext
&C
, unsigned NumTemplateArgs
) {
815 std::size_t size
= sizeof(UnresolvedMemberExpr
);
816 if (NumTemplateArgs
!= 0)
817 size
+= ExplicitTemplateArgumentList::sizeFor(NumTemplateArgs
);
819 void *Mem
= C
.Allocate(size
, llvm::alignof
<UnresolvedMemberExpr
>());
820 UnresolvedMemberExpr
*E
= new (Mem
) UnresolvedMemberExpr(EmptyShell());
821 E
->HasExplicitTemplateArgs
= NumTemplateArgs
!= 0;
825 CXXRecordDecl
*UnresolvedMemberExpr::getNamingClass() const {
826 // Unlike for UnresolvedLookupExpr, it is very easy to re-derive this.
828 // If there was a nested name specifier, it names the naming class.
829 // It can't be dependent: after all, we were actually able to do the
831 CXXRecordDecl
*Record
= 0;
832 if (getQualifier()) {
833 Type
*T
= getQualifier()->getAsType();
834 assert(T
&& "qualifier in member expression does not name type");
835 Record
= T
->getAsCXXRecordDecl();
836 assert(Record
&& "qualifier in member expression does not name record");
838 // Otherwise the naming class must have been the base class.
840 QualType BaseType
= getBaseType().getNonReferenceType();
842 const PointerType
*PT
= BaseType
->getAs
<PointerType
>();
843 assert(PT
&& "base of arrow member access is not pointer");
844 BaseType
= PT
->getPointeeType();
847 Record
= BaseType
->getAsCXXRecordDecl();
848 assert(Record
&& "base of member expression does not name record");
854 Stmt::child_iterator
UnresolvedMemberExpr::child_begin() {
855 return child_iterator(&Base
);
858 Stmt::child_iterator
UnresolvedMemberExpr::child_end() {
859 if (isImplicitAccess())
860 return child_iterator(&Base
);
861 return child_iterator(&Base
+ 1);