blob: 1ec662de21f97560bc42bd122bdbe55b6ec9cbed [file] [log] [blame]
Ted Kremeneke3a0c142007-08-24 20:21:10 +00001//===--- ExprCXX.cpp - (C++) Expression AST Node Implementation -----------===//
2//
3// The LLVM Compiler Infrastructure
4//
Chris Lattner5b12ab82007-12-29 19:59:25 +00005// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Ted Kremeneke3a0c142007-08-24 20:21:10 +00007//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the subclesses of Expr class declared in ExprCXX.h
11//
12//===----------------------------------------------------------------------===//
13
Douglas Gregor993603d2008-11-14 16:09:21 +000014#include "clang/Basic/IdentifierTable.h"
15#include "clang/AST/DeclCXX.h"
Douglas Gregora727cb92009-06-30 22:34:41 +000016#include "clang/AST/DeclTemplate.h"
Ted Kremeneke3a0c142007-08-24 20:21:10 +000017#include "clang/AST/ExprCXX.h"
Douglas Gregor651fe5e2010-02-24 23:40:28 +000018#include "clang/AST/TypeLoc.h"
Ted Kremeneke3a0c142007-08-24 20:21:10 +000019using namespace clang;
20
Douglas Gregor9da64192010-04-26 22:37:10 +000021
Ted Kremeneke3a0c142007-08-24 20:21:10 +000022//===----------------------------------------------------------------------===//
23// Child Iterators for iterating over subexpressions/substatements
24//===----------------------------------------------------------------------===//
25
Douglas Gregor9da64192010-04-26 22:37:10 +000026QualType CXXTypeidExpr::getTypeOperand() const {
27 assert(isTypeOperand() && "Cannot call getTypeOperand for typeid(expr)");
28 return Operand.get<TypeSourceInfo *>()->getType().getNonReferenceType()
29 .getUnqualifiedType();
30}
31
Sebastian Redlc4704762008-11-11 11:37:55 +000032// CXXTypeidExpr - has child iterators if the operand is an expression
33Stmt::child_iterator CXXTypeidExpr::child_begin() {
Douglas Gregor9da64192010-04-26 22:37:10 +000034 return isTypeOperand() ? child_iterator()
35 : reinterpret_cast<Stmt **>(&Operand);
Sebastian Redlc4704762008-11-11 11:37:55 +000036}
37Stmt::child_iterator CXXTypeidExpr::child_end() {
Douglas Gregor9da64192010-04-26 22:37:10 +000038 return isTypeOperand() ? child_iterator()
39 : reinterpret_cast<Stmt **>(&Operand) + 1;
Sebastian Redlc4704762008-11-11 11:37:55 +000040}
Ted Kremeneke3a0c142007-08-24 20:21:10 +000041
Ted Kremeneke3a0c142007-08-24 20:21:10 +000042// CXXBoolLiteralExpr
Mike Stump11289f42009-09-09 15:08:12 +000043Stmt::child_iterator CXXBoolLiteralExpr::child_begin() {
Ted Kremenek04746ce2007-10-18 23:28:49 +000044 return child_iterator();
45}
46Stmt::child_iterator CXXBoolLiteralExpr::child_end() {
47 return child_iterator();
48}
Chris Lattnerb7e656b2008-02-26 00:51:44 +000049
Sebastian Redl576fd422009-05-10 18:38:11 +000050// CXXNullPtrLiteralExpr
Mike Stump11289f42009-09-09 15:08:12 +000051Stmt::child_iterator CXXNullPtrLiteralExpr::child_begin() {
Sebastian Redl576fd422009-05-10 18:38:11 +000052 return child_iterator();
53}
54Stmt::child_iterator CXXNullPtrLiteralExpr::child_end() {
55 return child_iterator();
56}
57
Douglas Gregor97a9c812008-11-04 14:32:21 +000058// CXXThisExpr
59Stmt::child_iterator CXXThisExpr::child_begin() { return child_iterator(); }
60Stmt::child_iterator CXXThisExpr::child_end() { return child_iterator(); }
61
Chris Lattnerb7e656b2008-02-26 00:51:44 +000062// CXXThrowExpr
Ted Kremenekc6501db2008-06-17 03:11:08 +000063Stmt::child_iterator CXXThrowExpr::child_begin() { return &Op; }
Chris Lattnerb7e656b2008-02-26 00:51:44 +000064Stmt::child_iterator CXXThrowExpr::child_end() {
65 // If Op is 0, we are processing throw; which has no children.
Ted Kremenekc6501db2008-06-17 03:11:08 +000066 return Op ? &Op+1 : &Op;
Chris Lattnerb7e656b2008-02-26 00:51:44 +000067}
Chris Lattneraa9c7ae2008-04-08 04:40:51 +000068
69// CXXDefaultArgExpr
70Stmt::child_iterator CXXDefaultArgExpr::child_begin() {
Chris Lattner58258242008-04-10 02:22:51 +000071 return child_iterator();
Chris Lattneraa9c7ae2008-04-08 04:40:51 +000072}
73Stmt::child_iterator CXXDefaultArgExpr::child_end() {
Chris Lattner58258242008-04-10 02:22:51 +000074 return child_iterator();
Chris Lattneraa9c7ae2008-04-08 04:40:51 +000075}
Argyrios Kyrtzidis857fcc22008-08-22 15:38:55 +000076
77// CXXZeroInitValueExpr
Mike Stump11289f42009-09-09 15:08:12 +000078Stmt::child_iterator CXXZeroInitValueExpr::child_begin() {
Argyrios Kyrtzidis857fcc22008-08-22 15:38:55 +000079 return child_iterator();
80}
81Stmt::child_iterator CXXZeroInitValueExpr::child_end() {
82 return child_iterator();
83}
Argyrios Kyrtzidisaa479132008-09-09 23:47:53 +000084
Sebastian Redlbd150f42008-11-21 19:14:01 +000085// CXXNewExpr
Ted Kremenek9d6eb402010-02-11 22:51:03 +000086CXXNewExpr::CXXNewExpr(ASTContext &C, bool globalNew, FunctionDecl *operatorNew,
Sebastian Redlbd150f42008-11-21 19:14:01 +000087 Expr **placementArgs, unsigned numPlaceArgs,
Sebastian Redl351bb782008-12-02 14:43:59 +000088 bool parenTypeId, Expr *arraySize,
Sebastian Redlbd150f42008-11-21 19:14:01 +000089 CXXConstructorDecl *constructor, bool initializer,
90 Expr **constructorArgs, unsigned numConsArgs,
91 FunctionDecl *operatorDelete, QualType ty,
92 SourceLocation startLoc, SourceLocation endLoc)
Sebastian Redl8d2ccae2009-02-26 14:39:58 +000093 : Expr(CXXNewExprClass, ty, ty->isDependentType(), ty->isDependentType()),
94 GlobalNew(globalNew), ParenTypeId(parenTypeId),
Chris Lattnerabfb58d2010-05-10 01:22:27 +000095 Initializer(initializer), SubExprs(0), OperatorNew(operatorNew),
Sebastian Redl351bb782008-12-02 14:43:59 +000096 OperatorDelete(operatorDelete), Constructor(constructor),
Mike Stump11289f42009-09-09 15:08:12 +000097 StartLoc(startLoc), EndLoc(endLoc) {
Chris Lattnerabfb58d2010-05-10 01:22:27 +000098
99 AllocateArgsArray(C, arraySize != 0, numPlaceArgs, numConsArgs);
Sebastian Redlbd150f42008-11-21 19:14:01 +0000100 unsigned i = 0;
Sebastian Redl351bb782008-12-02 14:43:59 +0000101 if (Array)
102 SubExprs[i++] = arraySize;
103 for (unsigned j = 0; j < NumPlacementArgs; ++j)
Sebastian Redlbd150f42008-11-21 19:14:01 +0000104 SubExprs[i++] = placementArgs[j];
Sebastian Redl351bb782008-12-02 14:43:59 +0000105 for (unsigned j = 0; j < NumConstructorArgs; ++j)
Sebastian Redlbd150f42008-11-21 19:14:01 +0000106 SubExprs[i++] = constructorArgs[j];
Sebastian Redlbd150f42008-11-21 19:14:01 +0000107}
108
Chris Lattnerabfb58d2010-05-10 01:22:27 +0000109void CXXNewExpr::AllocateArgsArray(ASTContext &C, bool isArray,
110 unsigned numPlaceArgs, unsigned numConsArgs){
111 assert(SubExprs == 0 && "SubExprs already allocated");
112 Array = isArray;
113 NumPlacementArgs = numPlaceArgs;
114 NumConstructorArgs = numConsArgs;
115
116 unsigned TotalSize = Array + NumPlacementArgs + NumConstructorArgs;
117 SubExprs = new (C) Stmt*[TotalSize];
118}
119
120
Ted Kremenek9d6eb402010-02-11 22:51:03 +0000121void CXXNewExpr::DoDestroy(ASTContext &C) {
122 DestroyChildren(C);
123 if (SubExprs)
124 C.Deallocate(SubExprs);
125 this->~CXXNewExpr();
126 C.Deallocate((void*)this);
127}
128
Sebastian Redlbd150f42008-11-21 19:14:01 +0000129Stmt::child_iterator CXXNewExpr::child_begin() { return &SubExprs[0]; }
130Stmt::child_iterator CXXNewExpr::child_end() {
Sebastian Redl351bb782008-12-02 14:43:59 +0000131 return &SubExprs[0] + Array + getNumPlacementArgs() + getNumConstructorArgs();
Sebastian Redlbd150f42008-11-21 19:14:01 +0000132}
133
134// CXXDeleteExpr
135Stmt::child_iterator CXXDeleteExpr::child_begin() { return &Argument; }
136Stmt::child_iterator CXXDeleteExpr::child_end() { return &Argument+1; }
137
Douglas Gregorad8a3362009-09-04 17:36:40 +0000138// CXXPseudoDestructorExpr
139Stmt::child_iterator CXXPseudoDestructorExpr::child_begin() { return &Base; }
140Stmt::child_iterator CXXPseudoDestructorExpr::child_end() {
141 return &Base + 1;
142}
143
Douglas Gregor678f90d2010-02-25 01:56:36 +0000144PseudoDestructorTypeStorage::PseudoDestructorTypeStorage(TypeSourceInfo *Info)
145 : Type(Info)
146{
Abramo Bagnara1108e7b2010-05-20 10:00:11 +0000147 Location = Info->getTypeLoc().getLocalSourceRange().getBegin();
Douglas Gregor678f90d2010-02-25 01:56:36 +0000148}
149
150QualType CXXPseudoDestructorExpr::getDestroyedType() const {
151 if (TypeSourceInfo *TInfo = DestroyedType.getTypeSourceInfo())
152 return TInfo->getType();
153
154 return QualType();
155}
156
Douglas Gregor651fe5e2010-02-24 23:40:28 +0000157SourceRange CXXPseudoDestructorExpr::getSourceRange() const {
Douglas Gregor678f90d2010-02-25 01:56:36 +0000158 SourceLocation End = DestroyedType.getLocation();
159 if (TypeSourceInfo *TInfo = DestroyedType.getTypeSourceInfo())
Abramo Bagnara1108e7b2010-05-20 10:00:11 +0000160 End = TInfo->getTypeLoc().getLocalSourceRange().getEnd();
Douglas Gregor678f90d2010-02-25 01:56:36 +0000161 return SourceRange(Base->getLocStart(), End);
Douglas Gregor651fe5e2010-02-24 23:40:28 +0000162}
163
164
John McCalld14a8642009-11-21 08:51:07 +0000165// UnresolvedLookupExpr
John McCalle66edc12009-11-24 19:00:30 +0000166UnresolvedLookupExpr *
167UnresolvedLookupExpr::Create(ASTContext &C, bool Dependent,
John McCall58cc69d2010-01-27 01:50:18 +0000168 CXXRecordDecl *NamingClass,
John McCalle66edc12009-11-24 19:00:30 +0000169 NestedNameSpecifier *Qualifier,
170 SourceRange QualifierRange, DeclarationName Name,
171 SourceLocation NameLoc, bool ADL,
Douglas Gregor30a4f4c2010-05-23 18:57:34 +0000172 const TemplateArgumentListInfo &Args,
173 UnresolvedSetIterator Begin,
174 UnresolvedSetIterator End)
John McCalle66edc12009-11-24 19:00:30 +0000175{
176 void *Mem = C.Allocate(sizeof(UnresolvedLookupExpr) +
177 ExplicitTemplateArgumentList::sizeFor(Args));
178 UnresolvedLookupExpr *ULE
179 = new (Mem) UnresolvedLookupExpr(Dependent ? C.DependentTy : C.OverloadTy,
John McCall58cc69d2010-01-27 01:50:18 +0000180 Dependent, NamingClass,
181 Qualifier, QualifierRange,
John McCalle66edc12009-11-24 19:00:30 +0000182 Name, NameLoc, ADL,
183 /*Overload*/ true,
Douglas Gregor30a4f4c2010-05-23 18:57:34 +0000184 /*ExplicitTemplateArgs*/ true,
185 Begin, End);
John McCalle66edc12009-11-24 19:00:30 +0000186
187 reinterpret_cast<ExplicitTemplateArgumentList*>(ULE+1)->initializeFrom(Args);
188
189 return ULE;
190}
191
John McCall1acbbb52010-02-02 06:20:04 +0000192bool OverloadExpr::ComputeDependence(UnresolvedSetIterator Begin,
193 UnresolvedSetIterator End,
194 const TemplateArgumentListInfo *Args) {
John McCallad371252010-01-20 00:46:10 +0000195 for (UnresolvedSetImpl::const_iterator I = Begin; I != End; ++I)
John McCalle66edc12009-11-24 19:00:30 +0000196 if ((*I)->getDeclContext()->isDependentContext())
197 return true;
198
199 if (Args && TemplateSpecializationType::anyDependentTemplateArguments(*Args))
200 return true;
201
202 return false;
203}
204
John McCall8c12dc42010-04-22 18:44:12 +0000205CXXRecordDecl *OverloadExpr::getNamingClass() const {
206 if (isa<UnresolvedLookupExpr>(this))
207 return cast<UnresolvedLookupExpr>(this)->getNamingClass();
208 else
209 return cast<UnresolvedMemberExpr>(this)->getNamingClass();
210}
211
John McCalld14a8642009-11-21 08:51:07 +0000212Stmt::child_iterator UnresolvedLookupExpr::child_begin() {
Mike Stump11289f42009-09-09 15:08:12 +0000213 return child_iterator();
Douglas Gregorb0846b02008-12-06 00:22:45 +0000214}
John McCalld14a8642009-11-21 08:51:07 +0000215Stmt::child_iterator UnresolvedLookupExpr::child_end() {
Douglas Gregorb0846b02008-12-06 00:22:45 +0000216 return child_iterator();
217}
Sebastian Redlbaad4e72009-01-05 20:52:13 +0000218// UnaryTypeTraitExpr
219Stmt::child_iterator UnaryTypeTraitExpr::child_begin() {
220 return child_iterator();
221}
222Stmt::child_iterator UnaryTypeTraitExpr::child_end() {
223 return child_iterator();
224}
225
John McCall8cd78132009-11-19 22:55:06 +0000226// DependentScopeDeclRefExpr
John McCalle66edc12009-11-24 19:00:30 +0000227DependentScopeDeclRefExpr *
228DependentScopeDeclRefExpr::Create(ASTContext &C,
229 NestedNameSpecifier *Qualifier,
230 SourceRange QualifierRange,
231 DeclarationName Name,
232 SourceLocation NameLoc,
233 const TemplateArgumentListInfo *Args) {
234 std::size_t size = sizeof(DependentScopeDeclRefExpr);
235 if (Args) size += ExplicitTemplateArgumentList::sizeFor(*Args);
236 void *Mem = C.Allocate(size);
237
238 DependentScopeDeclRefExpr *DRE
239 = new (Mem) DependentScopeDeclRefExpr(C.DependentTy,
240 Qualifier, QualifierRange,
241 Name, NameLoc,
242 Args != 0);
243
244 if (Args)
245 reinterpret_cast<ExplicitTemplateArgumentList*>(DRE+1)
246 ->initializeFrom(*Args);
247
248 return DRE;
249}
250
John McCall8cd78132009-11-19 22:55:06 +0000251StmtIterator DependentScopeDeclRefExpr::child_begin() {
Douglas Gregor90a1a652009-03-19 17:26:29 +0000252 return child_iterator();
253}
254
John McCall8cd78132009-11-19 22:55:06 +0000255StmtIterator DependentScopeDeclRefExpr::child_end() {
Douglas Gregor90a1a652009-03-19 17:26:29 +0000256 return child_iterator();
257}
258
Douglas Gregor79f83ed2009-07-23 23:49:00 +0000259bool UnaryTypeTraitExpr::EvaluateTrait(ASTContext& C) const {
Sebastian Redlbaad4e72009-01-05 20:52:13 +0000260 switch(UTT) {
261 default: assert(false && "Unknown type trait or not implemented");
262 case UTT_IsPOD: return QueriedType->isPODType();
Sebastian Redl79eba1c2009-12-03 00:13:20 +0000263 case UTT_IsLiteral: return QueriedType->isLiteralType();
Sebastian Redlbaad4e72009-01-05 20:52:13 +0000264 case UTT_IsClass: // Fallthrough
265 case UTT_IsUnion:
Ted Kremenekc23c7e62009-07-29 21:53:49 +0000266 if (const RecordType *Record = QueriedType->getAs<RecordType>()) {
Sebastian Redlbaad4e72009-01-05 20:52:13 +0000267 bool Union = Record->getDecl()->isUnion();
268 return UTT == UTT_IsUnion ? Union : !Union;
269 }
270 return false;
271 case UTT_IsEnum: return QueriedType->isEnumeralType();
272 case UTT_IsPolymorphic:
Ted Kremenekc23c7e62009-07-29 21:53:49 +0000273 if (const RecordType *Record = QueriedType->getAs<RecordType>()) {
Sebastian Redlbaad4e72009-01-05 20:52:13 +0000274 // Type traits are only parsed in C++, so we've got CXXRecords.
275 return cast<CXXRecordDecl>(Record->getDecl())->isPolymorphic();
276 }
277 return false;
Anders Carlsson7cbd8fb2009-03-22 01:52:17 +0000278 case UTT_IsAbstract:
Ted Kremenekc23c7e62009-07-29 21:53:49 +0000279 if (const RecordType *RT = QueriedType->getAs<RecordType>())
Anders Carlsson7cbd8fb2009-03-22 01:52:17 +0000280 return cast<CXXRecordDecl>(RT->getDecl())->isAbstract();
281 return false;
Eli Friedmanc96d4962009-08-15 21:55:26 +0000282 case UTT_IsEmpty:
283 if (const RecordType *Record = QueriedType->getAs<RecordType>()) {
284 return !Record->getDecl()->isUnion()
285 && cast<CXXRecordDecl>(Record->getDecl())->isEmpty();
286 }
287 return false;
Anders Carlssonfe63dc52009-04-16 00:08:20 +0000288 case UTT_HasTrivialConstructor:
Douglas Gregor79f83ed2009-07-23 23:49:00 +0000289 // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
290 // If __is_pod (type) is true then the trait is true, else if type is
291 // a cv class or union type (or array thereof) with a trivial default
292 // constructor ([class.ctor]) then the trait is true, else it is false.
293 if (QueriedType->isPODType())
294 return true;
295 if (const RecordType *RT =
Ted Kremenekc23c7e62009-07-29 21:53:49 +0000296 C.getBaseElementType(QueriedType)->getAs<RecordType>())
Anders Carlssonfe63dc52009-04-16 00:08:20 +0000297 return cast<CXXRecordDecl>(RT->getDecl())->hasTrivialConstructor();
Anders Carlsson6dc35752009-04-17 02:34:54 +0000298 return false;
Douglas Gregor79f83ed2009-07-23 23:49:00 +0000299 case UTT_HasTrivialCopy:
300 // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
301 // If __is_pod (type) is true or type is a reference type then
302 // the trait is true, else if type is a cv class or union type
303 // with a trivial copy constructor ([class.copy]) then the trait
304 // is true, else it is false.
305 if (QueriedType->isPODType() || QueriedType->isReferenceType())
306 return true;
Ted Kremenekc23c7e62009-07-29 21:53:49 +0000307 if (const RecordType *RT = QueriedType->getAs<RecordType>())
Douglas Gregor79f83ed2009-07-23 23:49:00 +0000308 return cast<CXXRecordDecl>(RT->getDecl())->hasTrivialCopyConstructor();
309 return false;
310 case UTT_HasTrivialAssign:
311 // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
312 // If type is const qualified or is a reference type then the
313 // trait is false. Otherwise if __is_pod (type) is true then the
314 // trait is true, else if type is a cv class or union type with
315 // a trivial copy assignment ([class.copy]) then the trait is
316 // true, else it is false.
317 // Note: the const and reference restrictions are interesting,
318 // given that const and reference members don't prevent a class
319 // from having a trivial copy assignment operator (but do cause
320 // errors if the copy assignment operator is actually used, q.v.
321 // [class.copy]p12).
322
323 if (C.getBaseElementType(QueriedType).isConstQualified())
324 return false;
325 if (QueriedType->isPODType())
326 return true;
Ted Kremenekc23c7e62009-07-29 21:53:49 +0000327 if (const RecordType *RT = QueriedType->getAs<RecordType>())
Douglas Gregor79f83ed2009-07-23 23:49:00 +0000328 return cast<CXXRecordDecl>(RT->getDecl())->hasTrivialCopyAssignment();
329 return false;
330 case UTT_HasTrivialDestructor:
331 // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
332 // If __is_pod (type) is true or type is a reference type
333 // then the trait is true, else if type is a cv class or union
334 // type (or array thereof) with a trivial destructor
335 // ([class.dtor]) then the trait is true, else it is
336 // false.
337 if (QueriedType->isPODType() || QueriedType->isReferenceType())
338 return true;
339 if (const RecordType *RT =
Ted Kremenekc23c7e62009-07-29 21:53:49 +0000340 C.getBaseElementType(QueriedType)->getAs<RecordType>())
Anders Carlsson6dc35752009-04-17 02:34:54 +0000341 return cast<CXXRecordDecl>(RT->getDecl())->hasTrivialDestructor();
342 return false;
Sebastian Redlbaad4e72009-01-05 20:52:13 +0000343 }
344}
345
Ted Kremenek49ace5c2009-12-23 04:00:48 +0000346SourceRange CXXConstructExpr::getSourceRange() const {
347 // FIXME: Should we know where the parentheses are, if there are any?
348 for (std::reverse_iterator<Stmt**> I(&Args[NumArgs]), E(&Args[0]); I!=E;++I) {
349 // Ignore CXXDefaultExprs when computing the range, as they don't
350 // have a range.
351 if (!isa<CXXDefaultArgExpr>(*I))
352 return SourceRange(Loc, (*I)->getLocEnd());
353 }
354
355 return SourceRange(Loc);
356}
357
Douglas Gregor993603d2008-11-14 16:09:21 +0000358SourceRange CXXOperatorCallExpr::getSourceRange() const {
359 OverloadedOperatorKind Kind = getOperator();
360 if (Kind == OO_PlusPlus || Kind == OO_MinusMinus) {
361 if (getNumArgs() == 1)
362 // Prefix operator
Mike Stump11289f42009-09-09 15:08:12 +0000363 return SourceRange(getOperatorLoc(),
Douglas Gregor993603d2008-11-14 16:09:21 +0000364 getArg(0)->getSourceRange().getEnd());
365 else
366 // Postfix operator
367 return SourceRange(getArg(0)->getSourceRange().getEnd(),
368 getOperatorLoc());
369 } else if (Kind == OO_Call) {
370 return SourceRange(getArg(0)->getSourceRange().getBegin(), getRParenLoc());
371 } else if (Kind == OO_Subscript) {
372 return SourceRange(getArg(0)->getSourceRange().getBegin(), getRParenLoc());
373 } else if (getNumArgs() == 1) {
374 return SourceRange(getOperatorLoc(), getArg(0)->getSourceRange().getEnd());
375 } else if (getNumArgs() == 2) {
376 return SourceRange(getArg(0)->getSourceRange().getBegin(),
377 getArg(1)->getSourceRange().getEnd());
378 } else {
379 return SourceRange();
380 }
381}
382
Douglas Gregor97fd6e22008-12-22 05:46:06 +0000383Expr *CXXMemberCallExpr::getImplicitObjectArgument() {
384 if (MemberExpr *MemExpr = dyn_cast<MemberExpr>(getCallee()->IgnoreParens()))
385 return MemExpr->getBase();
386
387 // FIXME: Will eventually need to cope with member pointers.
388 return 0;
389}
390
Douglas Gregoref986e82009-11-12 15:31:47 +0000391SourceRange CXXMemberCallExpr::getSourceRange() const {
392 SourceLocation LocStart = getCallee()->getLocStart();
393 if (LocStart.isInvalid() && getNumArgs() > 0)
394 LocStart = getArg(0)->getLocStart();
395 return SourceRange(LocStart, getRParenLoc());
396}
397
398
Douglas Gregore200adc2008-10-27 19:41:14 +0000399//===----------------------------------------------------------------------===//
400// Named casts
401//===----------------------------------------------------------------------===//
402
403/// getCastName - Get the name of the C++ cast being used, e.g.,
404/// "static_cast", "dynamic_cast", "reinterpret_cast", or
405/// "const_cast". The returned pointer must not be freed.
406const char *CXXNamedCastExpr::getCastName() const {
407 switch (getStmtClass()) {
408 case CXXStaticCastExprClass: return "static_cast";
409 case CXXDynamicCastExprClass: return "dynamic_cast";
410 case CXXReinterpretCastExprClass: return "reinterpret_cast";
411 case CXXConstCastExprClass: return "const_cast";
412 default: return "<invalid cast>";
413 }
414}
Douglas Gregordd04d332009-01-16 18:33:17 +0000415
Douglas Gregor25ab25f2009-12-23 18:19:08 +0000416CXXDefaultArgExpr *
Douglas Gregor033f6752009-12-23 23:03:06 +0000417CXXDefaultArgExpr::Create(ASTContext &C, SourceLocation Loc,
418 ParmVarDecl *Param, Expr *SubExpr) {
Douglas Gregor25ab25f2009-12-23 18:19:08 +0000419 void *Mem = C.Allocate(sizeof(CXXDefaultArgExpr) + sizeof(Stmt *));
Douglas Gregor033f6752009-12-23 23:03:06 +0000420 return new (Mem) CXXDefaultArgExpr(CXXDefaultArgExprClass, Loc, Param,
421 SubExpr);
Douglas Gregor25ab25f2009-12-23 18:19:08 +0000422}
423
424void CXXDefaultArgExpr::DoDestroy(ASTContext &C) {
425 if (Param.getInt())
426 getExpr()->Destroy(C);
427 this->~CXXDefaultArgExpr();
428 C.Deallocate(this);
429}
430
Mike Stump11289f42009-09-09 15:08:12 +0000431CXXTemporary *CXXTemporary::Create(ASTContext &C,
Anders Carlssonffda6062009-05-30 20:34:37 +0000432 const CXXDestructorDecl *Destructor) {
Anders Carlsson73b836b2009-05-30 22:38:53 +0000433 return new (C) CXXTemporary(Destructor);
434}
435
Douglas Gregore26a2852009-08-07 06:08:38 +0000436void CXXTemporary::Destroy(ASTContext &Ctx) {
Anders Carlsson73b836b2009-05-30 22:38:53 +0000437 this->~CXXTemporary();
Douglas Gregore26a2852009-08-07 06:08:38 +0000438 Ctx.Deallocate(this);
Anders Carlssonf337d8c2009-05-30 19:54:15 +0000439}
440
Mike Stump11289f42009-09-09 15:08:12 +0000441CXXBindTemporaryExpr *CXXBindTemporaryExpr::Create(ASTContext &C,
Anders Carlsson993a4b32009-05-30 20:03:25 +0000442 CXXTemporary *Temp,
443 Expr* SubExpr) {
Mike Stump11289f42009-09-09 15:08:12 +0000444 assert(SubExpr->getType()->isRecordType() &&
Anders Carlsson993a4b32009-05-30 20:03:25 +0000445 "Expression bound to a temporary must have record type!");
446
Anders Carlssonffda6062009-05-30 20:34:37 +0000447 return new (C) CXXBindTemporaryExpr(Temp, SubExpr);
Anders Carlsson993a4b32009-05-30 20:03:25 +0000448}
449
Douglas Gregore26a2852009-08-07 06:08:38 +0000450void CXXBindTemporaryExpr::DoDestroy(ASTContext &C) {
Anders Carlsson73b836b2009-05-30 22:38:53 +0000451 Temp->Destroy(C);
452 this->~CXXBindTemporaryExpr();
453 C.Deallocate(this);
454}
455
Anders Carlssonba6c4372010-01-29 02:39:32 +0000456CXXBindReferenceExpr *CXXBindReferenceExpr::Create(ASTContext &C, Expr *SubExpr,
457 bool ExtendsLifetime,
458 bool RequiresTemporaryCopy) {
459 return new (C) CXXBindReferenceExpr(SubExpr,
460 ExtendsLifetime,
461 RequiresTemporaryCopy);
462}
463
464void CXXBindReferenceExpr::DoDestroy(ASTContext &C) {
465 this->~CXXBindReferenceExpr();
466 C.Deallocate(this);
467}
468
Anders Carlsson4b2434d2009-05-30 20:56:46 +0000469CXXTemporaryObjectExpr::CXXTemporaryObjectExpr(ASTContext &C,
Anders Carlsson56c5bd82009-04-24 05:23:13 +0000470 CXXConstructorDecl *Cons,
Douglas Gregordd04d332009-01-16 18:33:17 +0000471 QualType writtenTy,
Mike Stump11289f42009-09-09 15:08:12 +0000472 SourceLocation tyBeginLoc,
Douglas Gregordd04d332009-01-16 18:33:17 +0000473 Expr **Args,
Mike Stump11289f42009-09-09 15:08:12 +0000474 unsigned NumArgs,
Douglas Gregor199db362010-04-27 20:36:09 +0000475 SourceLocation rParenLoc,
476 bool ZeroInitialization)
Douglas Gregor85dabae2009-12-16 01:38:02 +0000477 : CXXConstructExpr(C, CXXTemporaryObjectExprClass, writtenTy, tyBeginLoc,
Douglas Gregor199db362010-04-27 20:36:09 +0000478 Cons, false, Args, NumArgs, ZeroInitialization),
Anders Carlsson95c56eb2009-04-24 17:34:38 +0000479 TyBeginLoc(tyBeginLoc), RParenLoc(rParenLoc) {
Douglas Gregordd04d332009-01-16 18:33:17 +0000480}
Anders Carlsson6f287832009-04-21 02:22:11 +0000481
Mike Stump11289f42009-09-09 15:08:12 +0000482CXXConstructExpr *CXXConstructExpr::Create(ASTContext &C, QualType T,
Douglas Gregor85dabae2009-12-16 01:38:02 +0000483 SourceLocation Loc,
Anders Carlsson4b2434d2009-05-30 20:56:46 +0000484 CXXConstructorDecl *D, bool Elidable,
Douglas Gregor4f4b1862009-12-16 18:50:27 +0000485 Expr **Args, unsigned NumArgs,
Douglas Gregor7ae2d772010-01-31 09:12:51 +0000486 bool ZeroInitialization,
Anders Carlssonedea1de2010-05-02 23:53:04 +0000487 ConstructionKind ConstructKind) {
Douglas Gregor85dabae2009-12-16 01:38:02 +0000488 return new (C) CXXConstructExpr(C, CXXConstructExprClass, T, Loc, D,
Douglas Gregor7ae2d772010-01-31 09:12:51 +0000489 Elidable, Args, NumArgs, ZeroInitialization,
Anders Carlssonedea1de2010-05-02 23:53:04 +0000490 ConstructKind);
Anders Carlsson0781ce72009-04-23 02:32:43 +0000491}
492
Mike Stump11289f42009-09-09 15:08:12 +0000493CXXConstructExpr::CXXConstructExpr(ASTContext &C, StmtClass SC, QualType T,
Douglas Gregor85dabae2009-12-16 01:38:02 +0000494 SourceLocation Loc,
Anders Carlsson4b2434d2009-05-30 20:56:46 +0000495 CXXConstructorDecl *D, bool elidable,
Douglas Gregor4f4b1862009-12-16 18:50:27 +0000496 Expr **args, unsigned numargs,
Anders Carlssonbcc066b2010-05-02 22:54:08 +0000497 bool ZeroInitialization,
498 ConstructionKind ConstructKind)
Anders Carlsson32ebd292009-04-24 05:04:04 +0000499: Expr(SC, T,
Anders Carlsson0781ce72009-04-23 02:32:43 +0000500 T->isDependentType(),
501 (T->isDependentType() ||
502 CallExpr::hasAnyValueDependentArguments(args, numargs))),
Douglas Gregor4f4b1862009-12-16 18:50:27 +0000503 Constructor(D), Loc(Loc), Elidable(elidable),
Anders Carlssonbcc066b2010-05-02 22:54:08 +0000504 ZeroInitialization(ZeroInitialization), ConstructKind(ConstructKind),
505 Args(0), NumArgs(numargs)
Douglas Gregor4f4b1862009-12-16 18:50:27 +0000506{
507 if (NumArgs) {
508 Args = new (C) Stmt*[NumArgs];
509
510 for (unsigned i = 0; i != NumArgs; ++i) {
511 assert(args[i] && "NULL argument in CXXConstructExpr");
512 Args[i] = args[i];
Anders Carlsson0781ce72009-04-23 02:32:43 +0000513 }
Douglas Gregor4f4b1862009-12-16 18:50:27 +0000514 }
Anders Carlsson0781ce72009-04-23 02:32:43 +0000515}
516
Douglas Gregor5d3507d2009-09-09 23:08:42 +0000517CXXConstructExpr::CXXConstructExpr(EmptyShell Empty, ASTContext &C,
518 unsigned numargs)
519 : Expr(CXXConstructExprClass, Empty), Args(0), NumArgs(numargs)
520{
521 if (NumArgs)
522 Args = new (C) Stmt*[NumArgs];
523}
524
Douglas Gregore26a2852009-08-07 06:08:38 +0000525void CXXConstructExpr::DoDestroy(ASTContext &C) {
Anders Carlsson0781ce72009-04-23 02:32:43 +0000526 DestroyChildren(C);
527 if (Args)
528 C.Deallocate(Args);
529 this->~CXXConstructExpr();
530 C.Deallocate(this);
531}
532
Ted Kremeneka9084c12010-05-10 20:06:30 +0000533CXXExprWithTemporaries::CXXExprWithTemporaries(ASTContext &C,
534 Expr *subexpr,
Mike Stump11289f42009-09-09 15:08:12 +0000535 CXXTemporary **temps,
Anders Carlsson6e997b22009-12-15 20:51:39 +0000536 unsigned numtemps)
Chris Lattnercba86142010-05-10 00:25:06 +0000537 : Expr(CXXExprWithTemporariesClass, subexpr->getType(),
Mike Stump11289f42009-09-09 15:08:12 +0000538 subexpr->isTypeDependent(), subexpr->isValueDependent()),
Chris Lattnercba86142010-05-10 00:25:06 +0000539 SubExpr(subexpr), Temps(0), NumTemps(0) {
Chris Lattnerbc7d55d2010-05-10 00:45:12 +0000540 if (numtemps) {
Ted Kremeneka9084c12010-05-10 20:06:30 +0000541 setNumTemporaries(C, numtemps);
Chris Lattnercba86142010-05-10 00:25:06 +0000542 for (unsigned i = 0; i != numtemps; ++i)
Anders Carlssona29ded92009-05-30 21:05:25 +0000543 Temps[i] = temps[i];
Anders Carlssondefc6442009-04-24 22:47:04 +0000544 }
545}
546
Ted Kremeneka9084c12010-05-10 20:06:30 +0000547void CXXExprWithTemporaries::setNumTemporaries(ASTContext &C, unsigned N) {
Chris Lattnercba86142010-05-10 00:25:06 +0000548 assert(Temps == 0 && "Cannot resize with this");
Daniel Dunbarc8a7bdb2010-05-10 15:59:37 +0000549 NumTemps = N;
Ted Kremeneka9084c12010-05-10 20:06:30 +0000550 Temps = new (C) CXXTemporary*[NumTemps];
Chris Lattnercba86142010-05-10 00:25:06 +0000551}
552
553
Mike Stump11289f42009-09-09 15:08:12 +0000554CXXExprWithTemporaries *CXXExprWithTemporaries::Create(ASTContext &C,
Anders Carlsson73b836b2009-05-30 22:38:53 +0000555 Expr *SubExpr,
Mike Stump11289f42009-09-09 15:08:12 +0000556 CXXTemporary **Temps,
Anders Carlsson6e997b22009-12-15 20:51:39 +0000557 unsigned NumTemps) {
Ted Kremeneka9084c12010-05-10 20:06:30 +0000558 return new (C) CXXExprWithTemporaries(C, SubExpr, Temps, NumTemps);
Anders Carlsson73b836b2009-05-30 22:38:53 +0000559}
560
Douglas Gregore26a2852009-08-07 06:08:38 +0000561void CXXExprWithTemporaries::DoDestroy(ASTContext &C) {
Anders Carlsson73b836b2009-05-30 22:38:53 +0000562 DestroyChildren(C);
Ted Kremeneka9084c12010-05-10 20:06:30 +0000563 if (Temps)
564 C.Deallocate(Temps);
Anders Carlsson73b836b2009-05-30 22:38:53 +0000565 this->~CXXExprWithTemporaries();
566 C.Deallocate(this);
567}
568
Ted Kremeneka9084c12010-05-10 20:06:30 +0000569CXXExprWithTemporaries::~CXXExprWithTemporaries() {}
Anders Carlssondefc6442009-04-24 22:47:04 +0000570
Anders Carlsson993a4b32009-05-30 20:03:25 +0000571// CXXBindTemporaryExpr
572Stmt::child_iterator CXXBindTemporaryExpr::child_begin() {
573 return &SubExpr;
574}
575
Mike Stump11289f42009-09-09 15:08:12 +0000576Stmt::child_iterator CXXBindTemporaryExpr::child_end() {
Anders Carlsson993a4b32009-05-30 20:03:25 +0000577 return &SubExpr + 1;
578}
579
Anders Carlssonba6c4372010-01-29 02:39:32 +0000580// CXXBindReferenceExpr
581Stmt::child_iterator CXXBindReferenceExpr::child_begin() {
582 return &SubExpr;
583}
584
585Stmt::child_iterator CXXBindReferenceExpr::child_end() {
586 return &SubExpr + 1;
587}
588
Anders Carlsson0781ce72009-04-23 02:32:43 +0000589// CXXConstructExpr
590Stmt::child_iterator CXXConstructExpr::child_begin() {
591 return &Args[0];
592}
593Stmt::child_iterator CXXConstructExpr::child_end() {
594 return &Args[0]+NumArgs;
595}
596
Anders Carlssonaa10d652009-05-01 22:21:22 +0000597// CXXExprWithTemporaries
598Stmt::child_iterator CXXExprWithTemporaries::child_begin() {
599 return &SubExpr;
Anders Carlsson6f287832009-04-21 02:22:11 +0000600}
Anders Carlssondefc6442009-04-24 22:47:04 +0000601
Mike Stump11289f42009-09-09 15:08:12 +0000602Stmt::child_iterator CXXExprWithTemporaries::child_end() {
Anders Carlssonaa10d652009-05-01 22:21:22 +0000603 return &SubExpr + 1;
604}
Anders Carlssondefc6442009-04-24 22:47:04 +0000605
Douglas Gregorce934142009-05-20 18:46:25 +0000606CXXUnresolvedConstructExpr::CXXUnresolvedConstructExpr(
607 SourceLocation TyBeginLoc,
608 QualType T,
609 SourceLocation LParenLoc,
610 Expr **Args,
611 unsigned NumArgs,
612 SourceLocation RParenLoc)
613 : Expr(CXXUnresolvedConstructExprClass, T.getNonReferenceType(),
614 T->isDependentType(), true),
615 TyBeginLoc(TyBeginLoc),
616 Type(T),
617 LParenLoc(LParenLoc),
618 RParenLoc(RParenLoc),
619 NumArgs(NumArgs) {
620 Stmt **StoredArgs = reinterpret_cast<Stmt **>(this + 1);
621 memcpy(StoredArgs, Args, sizeof(Expr *) * NumArgs);
622}
623
624CXXUnresolvedConstructExpr *
Mike Stump11289f42009-09-09 15:08:12 +0000625CXXUnresolvedConstructExpr::Create(ASTContext &C,
Douglas Gregorce934142009-05-20 18:46:25 +0000626 SourceLocation TyBegin,
627 QualType T,
628 SourceLocation LParenLoc,
629 Expr **Args,
630 unsigned NumArgs,
631 SourceLocation RParenLoc) {
632 void *Mem = C.Allocate(sizeof(CXXUnresolvedConstructExpr) +
633 sizeof(Expr *) * NumArgs);
634 return new (Mem) CXXUnresolvedConstructExpr(TyBegin, T, LParenLoc,
635 Args, NumArgs, RParenLoc);
636}
637
638Stmt::child_iterator CXXUnresolvedConstructExpr::child_begin() {
639 return child_iterator(reinterpret_cast<Stmt **>(this + 1));
640}
641
642Stmt::child_iterator CXXUnresolvedConstructExpr::child_end() {
643 return child_iterator(reinterpret_cast<Stmt **>(this + 1) + NumArgs);
644}
Sebastian Redle769ecf2009-05-16 18:50:46 +0000645
John McCall8cd78132009-11-19 22:55:06 +0000646CXXDependentScopeMemberExpr::CXXDependentScopeMemberExpr(ASTContext &C,
John McCall2d74de92009-12-01 22:10:20 +0000647 Expr *Base, QualType BaseType,
648 bool IsArrow,
Douglas Gregor308047d2009-09-09 00:23:06 +0000649 SourceLocation OperatorLoc,
650 NestedNameSpecifier *Qualifier,
651 SourceRange QualifierRange,
652 NamedDecl *FirstQualifierFoundInScope,
653 DeclarationName Member,
654 SourceLocation MemberLoc,
John McCall6b51f282009-11-23 01:53:49 +0000655 const TemplateArgumentListInfo *TemplateArgs)
John McCall8cd78132009-11-19 22:55:06 +0000656 : Expr(CXXDependentScopeMemberExprClass, C.DependentTy, true, true),
John McCall2d74de92009-12-01 22:10:20 +0000657 Base(Base), BaseType(BaseType), IsArrow(IsArrow),
658 HasExplicitTemplateArgs(TemplateArgs != 0),
Douglas Gregor308047d2009-09-09 00:23:06 +0000659 OperatorLoc(OperatorLoc),
660 Qualifier(Qualifier), QualifierRange(QualifierRange),
661 FirstQualifierFoundInScope(FirstQualifierFoundInScope),
Mike Stump11289f42009-09-09 15:08:12 +0000662 Member(Member), MemberLoc(MemberLoc) {
John McCall6b51f282009-11-23 01:53:49 +0000663 if (TemplateArgs)
664 getExplicitTemplateArgumentList()->initializeFrom(*TemplateArgs);
Douglas Gregor308047d2009-09-09 00:23:06 +0000665}
666
John McCall8cd78132009-11-19 22:55:06 +0000667CXXDependentScopeMemberExpr *
668CXXDependentScopeMemberExpr::Create(ASTContext &C,
John McCall2d74de92009-12-01 22:10:20 +0000669 Expr *Base, QualType BaseType, bool IsArrow,
Douglas Gregor308047d2009-09-09 00:23:06 +0000670 SourceLocation OperatorLoc,
671 NestedNameSpecifier *Qualifier,
672 SourceRange QualifierRange,
673 NamedDecl *FirstQualifierFoundInScope,
674 DeclarationName Member,
675 SourceLocation MemberLoc,
John McCall6b51f282009-11-23 01:53:49 +0000676 const TemplateArgumentListInfo *TemplateArgs) {
677 if (!TemplateArgs)
John McCall2d74de92009-12-01 22:10:20 +0000678 return new (C) CXXDependentScopeMemberExpr(C, Base, BaseType,
679 IsArrow, OperatorLoc,
680 Qualifier, QualifierRange,
681 FirstQualifierFoundInScope,
682 Member, MemberLoc);
Mike Stump11289f42009-09-09 15:08:12 +0000683
John McCall6b51f282009-11-23 01:53:49 +0000684 std::size_t size = sizeof(CXXDependentScopeMemberExpr);
685 if (TemplateArgs)
686 size += ExplicitTemplateArgumentList::sizeFor(*TemplateArgs);
687
688 void *Mem = C.Allocate(size, llvm::alignof<CXXDependentScopeMemberExpr>());
John McCall2d74de92009-12-01 22:10:20 +0000689 return new (Mem) CXXDependentScopeMemberExpr(C, Base, BaseType,
690 IsArrow, OperatorLoc,
691 Qualifier, QualifierRange,
692 FirstQualifierFoundInScope,
693 Member, MemberLoc, TemplateArgs);
Douglas Gregor308047d2009-09-09 00:23:06 +0000694}
695
John McCall8cd78132009-11-19 22:55:06 +0000696Stmt::child_iterator CXXDependentScopeMemberExpr::child_begin() {
Douglas Gregora8db9542009-05-22 21:13:27 +0000697 return child_iterator(&Base);
698}
699
John McCall8cd78132009-11-19 22:55:06 +0000700Stmt::child_iterator CXXDependentScopeMemberExpr::child_end() {
John McCall2d74de92009-12-01 22:10:20 +0000701 if (isImplicitAccess())
702 return child_iterator(&Base);
Douglas Gregora8db9542009-05-22 21:13:27 +0000703 return child_iterator(&Base + 1);
704}
John McCall10eae182009-11-30 22:42:35 +0000705
706UnresolvedMemberExpr::UnresolvedMemberExpr(QualType T, bool Dependent,
707 bool HasUnresolvedUsing,
John McCall2d74de92009-12-01 22:10:20 +0000708 Expr *Base, QualType BaseType,
709 bool IsArrow,
John McCall10eae182009-11-30 22:42:35 +0000710 SourceLocation OperatorLoc,
711 NestedNameSpecifier *Qualifier,
712 SourceRange QualifierRange,
713 DeclarationName MemberName,
714 SourceLocation MemberLoc,
Douglas Gregor30a4f4c2010-05-23 18:57:34 +0000715 const TemplateArgumentListInfo *TemplateArgs,
716 UnresolvedSetIterator Begin,
717 UnresolvedSetIterator End)
John McCall1acbbb52010-02-02 06:20:04 +0000718 : OverloadExpr(UnresolvedMemberExprClass, T, Dependent,
719 Qualifier, QualifierRange, MemberName, MemberLoc,
Douglas Gregor30a4f4c2010-05-23 18:57:34 +0000720 TemplateArgs != 0, Begin, End),
John McCall1acbbb52010-02-02 06:20:04 +0000721 IsArrow(IsArrow), HasUnresolvedUsing(HasUnresolvedUsing),
722 Base(Base), BaseType(BaseType), OperatorLoc(OperatorLoc) {
John McCall10eae182009-11-30 22:42:35 +0000723 if (TemplateArgs)
John McCall1acbbb52010-02-02 06:20:04 +0000724 getExplicitTemplateArgs().initializeFrom(*TemplateArgs);
John McCall10eae182009-11-30 22:42:35 +0000725}
726
727UnresolvedMemberExpr *
728UnresolvedMemberExpr::Create(ASTContext &C, bool Dependent,
729 bool HasUnresolvedUsing,
John McCall2d74de92009-12-01 22:10:20 +0000730 Expr *Base, QualType BaseType, bool IsArrow,
John McCall10eae182009-11-30 22:42:35 +0000731 SourceLocation OperatorLoc,
732 NestedNameSpecifier *Qualifier,
733 SourceRange QualifierRange,
734 DeclarationName Member,
735 SourceLocation MemberLoc,
Douglas Gregor30a4f4c2010-05-23 18:57:34 +0000736 const TemplateArgumentListInfo *TemplateArgs,
737 UnresolvedSetIterator Begin,
738 UnresolvedSetIterator End) {
John McCall10eae182009-11-30 22:42:35 +0000739 std::size_t size = sizeof(UnresolvedMemberExpr);
740 if (TemplateArgs)
741 size += ExplicitTemplateArgumentList::sizeFor(*TemplateArgs);
742
743 void *Mem = C.Allocate(size, llvm::alignof<UnresolvedMemberExpr>());
744 return new (Mem) UnresolvedMemberExpr(
745 Dependent ? C.DependentTy : C.OverloadTy,
John McCall2d74de92009-12-01 22:10:20 +0000746 Dependent, HasUnresolvedUsing, Base, BaseType,
747 IsArrow, OperatorLoc, Qualifier, QualifierRange,
Douglas Gregor30a4f4c2010-05-23 18:57:34 +0000748 Member, MemberLoc, TemplateArgs, Begin, End);
John McCall10eae182009-11-30 22:42:35 +0000749}
750
John McCall58cc69d2010-01-27 01:50:18 +0000751CXXRecordDecl *UnresolvedMemberExpr::getNamingClass() const {
752 // Unlike for UnresolvedLookupExpr, it is very easy to re-derive this.
753
754 // If there was a nested name specifier, it names the naming class.
755 // It can't be dependent: after all, we were actually able to do the
756 // lookup.
Douglas Gregor9262f472010-04-27 18:19:34 +0000757 CXXRecordDecl *Record = 0;
John McCall1acbbb52010-02-02 06:20:04 +0000758 if (getQualifier()) {
759 Type *T = getQualifier()->getAsType();
John McCall58cc69d2010-01-27 01:50:18 +0000760 assert(T && "qualifier in member expression does not name type");
Douglas Gregor9262f472010-04-27 18:19:34 +0000761 Record = T->getAsCXXRecordDecl();
762 assert(Record && "qualifier in member expression does not name record");
763 }
John McCall58cc69d2010-01-27 01:50:18 +0000764 // Otherwise the naming class must have been the base class.
Douglas Gregor9262f472010-04-27 18:19:34 +0000765 else {
John McCall58cc69d2010-01-27 01:50:18 +0000766 QualType BaseType = getBaseType().getNonReferenceType();
767 if (isArrow()) {
768 const PointerType *PT = BaseType->getAs<PointerType>();
769 assert(PT && "base of arrow member access is not pointer");
770 BaseType = PT->getPointeeType();
771 }
772
Douglas Gregor9262f472010-04-27 18:19:34 +0000773 Record = BaseType->getAsCXXRecordDecl();
774 assert(Record && "base of member expression does not name record");
John McCall58cc69d2010-01-27 01:50:18 +0000775 }
776
Douglas Gregor9262f472010-04-27 18:19:34 +0000777 return Record;
John McCall58cc69d2010-01-27 01:50:18 +0000778}
779
John McCall10eae182009-11-30 22:42:35 +0000780Stmt::child_iterator UnresolvedMemberExpr::child_begin() {
781 return child_iterator(&Base);
782}
783
784Stmt::child_iterator UnresolvedMemberExpr::child_end() {
John McCall2d74de92009-12-01 22:10:20 +0000785 if (isImplicitAccess())
786 return child_iterator(&Base);
John McCall10eae182009-11-30 22:42:35 +0000787 return child_iterator(&Base + 1);
788}