blob: 5f908096bbb0ccd16f318e7f266ff55c0f899fc1 [file] [log] [blame]
Ted Kremeneka758d092007-08-24 20:21:10 +00001//===--- ExprCXX.cpp - (C++) Expression AST Node Implementation -----------===//
2//
3// The LLVM Compiler Infrastructure
4//
Chris Lattner0bc735f2007-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 Kremeneka758d092007-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 Gregorb4609802008-11-14 16:09:21 +000014#include "clang/Basic/IdentifierTable.h"
15#include "clang/AST/DeclCXX.h"
Douglas Gregoredce4dd2009-06-30 22:34:41 +000016#include "clang/AST/DeclTemplate.h"
Ted Kremeneka758d092007-08-24 20:21:10 +000017#include "clang/AST/ExprCXX.h"
Douglas Gregor26d4ac92010-02-24 23:40:28 +000018#include "clang/AST/TypeLoc.h"
Ted Kremeneka758d092007-08-24 20:21:10 +000019using namespace clang;
20
Douglas Gregor57fdc8a2010-04-26 22:37:10 +000021
Ted Kremeneka758d092007-08-24 20:21:10 +000022//===----------------------------------------------------------------------===//
23// Child Iterators for iterating over subexpressions/substatements
24//===----------------------------------------------------------------------===//
25
Douglas Gregor57fdc8a2010-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 Redlc42e1182008-11-11 11:37:55 +000032// CXXTypeidExpr - has child iterators if the operand is an expression
33Stmt::child_iterator CXXTypeidExpr::child_begin() {
Douglas Gregor57fdc8a2010-04-26 22:37:10 +000034 return isTypeOperand() ? child_iterator()
35 : reinterpret_cast<Stmt **>(&Operand);
Sebastian Redlc42e1182008-11-11 11:37:55 +000036}
37Stmt::child_iterator CXXTypeidExpr::child_end() {
Douglas Gregor57fdc8a2010-04-26 22:37:10 +000038 return isTypeOperand() ? child_iterator()
39 : reinterpret_cast<Stmt **>(&Operand) + 1;
Sebastian Redlc42e1182008-11-11 11:37:55 +000040}
Ted Kremeneka758d092007-08-24 20:21:10 +000041
Ted Kremeneka758d092007-08-24 20:21:10 +000042// CXXBoolLiteralExpr
Mike Stump1eb44332009-09-09 15:08:12 +000043Stmt::child_iterator CXXBoolLiteralExpr::child_begin() {
Ted Kremenek9ac59282007-10-18 23:28:49 +000044 return child_iterator();
45}
46Stmt::child_iterator CXXBoolLiteralExpr::child_end() {
47 return child_iterator();
48}
Chris Lattner50dd2892008-02-26 00:51:44 +000049
Sebastian Redl6e8ed162009-05-10 18:38:11 +000050// CXXNullPtrLiteralExpr
Mike Stump1eb44332009-09-09 15:08:12 +000051Stmt::child_iterator CXXNullPtrLiteralExpr::child_begin() {
Sebastian Redl6e8ed162009-05-10 18:38:11 +000052 return child_iterator();
53}
54Stmt::child_iterator CXXNullPtrLiteralExpr::child_end() {
55 return child_iterator();
56}
57
Douglas Gregor796da182008-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 Lattner50dd2892008-02-26 00:51:44 +000062// CXXThrowExpr
Ted Kremenek1060aff2008-06-17 03:11:08 +000063Stmt::child_iterator CXXThrowExpr::child_begin() { return &Op; }
Chris Lattner50dd2892008-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 Kremenek1060aff2008-06-17 03:11:08 +000066 return Op ? &Op+1 : &Op;
Chris Lattner50dd2892008-02-26 00:51:44 +000067}
Chris Lattner04421082008-04-08 04:40:51 +000068
69// CXXDefaultArgExpr
70Stmt::child_iterator CXXDefaultArgExpr::child_begin() {
Chris Lattner8123a952008-04-10 02:22:51 +000071 return child_iterator();
Chris Lattner04421082008-04-08 04:40:51 +000072}
73Stmt::child_iterator CXXDefaultArgExpr::child_end() {
Chris Lattner8123a952008-04-10 02:22:51 +000074 return child_iterator();
Chris Lattner04421082008-04-08 04:40:51 +000075}
Argyrios Kyrtzidis987a14b2008-08-22 15:38:55 +000076
77// CXXZeroInitValueExpr
Mike Stump1eb44332009-09-09 15:08:12 +000078Stmt::child_iterator CXXZeroInitValueExpr::child_begin() {
Argyrios Kyrtzidis987a14b2008-08-22 15:38:55 +000079 return child_iterator();
80}
81Stmt::child_iterator CXXZeroInitValueExpr::child_end() {
82 return child_iterator();
83}
Argyrios Kyrtzidis9e922b12008-09-09 23:47:53 +000084
Sebastian Redl4c5d3202008-11-21 19:14:01 +000085// CXXNewExpr
Ted Kremenekad7fe862010-02-11 22:51:03 +000086CXXNewExpr::CXXNewExpr(ASTContext &C, bool globalNew, FunctionDecl *operatorNew,
Sebastian Redl4c5d3202008-11-21 19:14:01 +000087 Expr **placementArgs, unsigned numPlaceArgs,
Sebastian Redlcee63fb2008-12-02 14:43:59 +000088 bool parenTypeId, Expr *arraySize,
Sebastian Redl4c5d3202008-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 Redl28507842009-02-26 14:39:58 +000093 : Expr(CXXNewExprClass, ty, ty->isDependentType(), ty->isDependentType()),
94 GlobalNew(globalNew), ParenTypeId(parenTypeId),
Sebastian Redlcee63fb2008-12-02 14:43:59 +000095 Initializer(initializer), Array(arraySize), NumPlacementArgs(numPlaceArgs),
Sebastian Redl4c5d3202008-11-21 19:14:01 +000096 NumConstructorArgs(numConsArgs), OperatorNew(operatorNew),
Sebastian Redlcee63fb2008-12-02 14:43:59 +000097 OperatorDelete(operatorDelete), Constructor(constructor),
Mike Stump1eb44332009-09-09 15:08:12 +000098 StartLoc(startLoc), EndLoc(endLoc) {
Sebastian Redlcee63fb2008-12-02 14:43:59 +000099 unsigned TotalSize = Array + NumPlacementArgs + NumConstructorArgs;
Ted Kremenekad7fe862010-02-11 22:51:03 +0000100 SubExprs = new (C) Stmt*[TotalSize];
Sebastian Redl4c5d3202008-11-21 19:14:01 +0000101 unsigned i = 0;
Sebastian Redlcee63fb2008-12-02 14:43:59 +0000102 if (Array)
103 SubExprs[i++] = arraySize;
104 for (unsigned j = 0; j < NumPlacementArgs; ++j)
Sebastian Redl4c5d3202008-11-21 19:14:01 +0000105 SubExprs[i++] = placementArgs[j];
Sebastian Redlcee63fb2008-12-02 14:43:59 +0000106 for (unsigned j = 0; j < NumConstructorArgs; ++j)
Sebastian Redl4c5d3202008-11-21 19:14:01 +0000107 SubExprs[i++] = constructorArgs[j];
108 assert(i == TotalSize);
109}
110
Ted Kremenekad7fe862010-02-11 22:51:03 +0000111void CXXNewExpr::DoDestroy(ASTContext &C) {
112 DestroyChildren(C);
113 if (SubExprs)
114 C.Deallocate(SubExprs);
115 this->~CXXNewExpr();
116 C.Deallocate((void*)this);
117}
118
Sebastian Redl4c5d3202008-11-21 19:14:01 +0000119Stmt::child_iterator CXXNewExpr::child_begin() { return &SubExprs[0]; }
120Stmt::child_iterator CXXNewExpr::child_end() {
Sebastian Redlcee63fb2008-12-02 14:43:59 +0000121 return &SubExprs[0] + Array + getNumPlacementArgs() + getNumConstructorArgs();
Sebastian Redl4c5d3202008-11-21 19:14:01 +0000122}
123
124// CXXDeleteExpr
125Stmt::child_iterator CXXDeleteExpr::child_begin() { return &Argument; }
126Stmt::child_iterator CXXDeleteExpr::child_end() { return &Argument+1; }
127
Douglas Gregora71d8192009-09-04 17:36:40 +0000128// CXXPseudoDestructorExpr
129Stmt::child_iterator CXXPseudoDestructorExpr::child_begin() { return &Base; }
130Stmt::child_iterator CXXPseudoDestructorExpr::child_end() {
131 return &Base + 1;
132}
133
Douglas Gregora2e7dd22010-02-25 01:56:36 +0000134PseudoDestructorTypeStorage::PseudoDestructorTypeStorage(TypeSourceInfo *Info)
135 : Type(Info)
136{
137 Location = Info->getTypeLoc().getSourceRange().getBegin();
138}
139
140QualType CXXPseudoDestructorExpr::getDestroyedType() const {
141 if (TypeSourceInfo *TInfo = DestroyedType.getTypeSourceInfo())
142 return TInfo->getType();
143
144 return QualType();
145}
146
Douglas Gregor26d4ac92010-02-24 23:40:28 +0000147SourceRange CXXPseudoDestructorExpr::getSourceRange() const {
Douglas Gregora2e7dd22010-02-25 01:56:36 +0000148 SourceLocation End = DestroyedType.getLocation();
149 if (TypeSourceInfo *TInfo = DestroyedType.getTypeSourceInfo())
150 End = TInfo->getTypeLoc().getSourceRange().getEnd();
151 return SourceRange(Base->getLocStart(), End);
Douglas Gregor26d4ac92010-02-24 23:40:28 +0000152}
153
154
John McCallba135432009-11-21 08:51:07 +0000155// UnresolvedLookupExpr
John McCallf7a1a742009-11-24 19:00:30 +0000156UnresolvedLookupExpr *
157UnresolvedLookupExpr::Create(ASTContext &C, bool Dependent,
John McCallc373d482010-01-27 01:50:18 +0000158 CXXRecordDecl *NamingClass,
John McCallf7a1a742009-11-24 19:00:30 +0000159 NestedNameSpecifier *Qualifier,
160 SourceRange QualifierRange, DeclarationName Name,
161 SourceLocation NameLoc, bool ADL,
162 const TemplateArgumentListInfo &Args)
163{
164 void *Mem = C.Allocate(sizeof(UnresolvedLookupExpr) +
165 ExplicitTemplateArgumentList::sizeFor(Args));
166 UnresolvedLookupExpr *ULE
167 = new (Mem) UnresolvedLookupExpr(Dependent ? C.DependentTy : C.OverloadTy,
John McCallc373d482010-01-27 01:50:18 +0000168 Dependent, NamingClass,
169 Qualifier, QualifierRange,
John McCallf7a1a742009-11-24 19:00:30 +0000170 Name, NameLoc, ADL,
171 /*Overload*/ true,
172 /*ExplicitTemplateArgs*/ true);
173
174 reinterpret_cast<ExplicitTemplateArgumentList*>(ULE+1)->initializeFrom(Args);
175
176 return ULE;
177}
178
John McCall7bb12da2010-02-02 06:20:04 +0000179bool OverloadExpr::ComputeDependence(UnresolvedSetIterator Begin,
180 UnresolvedSetIterator End,
181 const TemplateArgumentListInfo *Args) {
John McCalleec51cf2010-01-20 00:46:10 +0000182 for (UnresolvedSetImpl::const_iterator I = Begin; I != End; ++I)
John McCallf7a1a742009-11-24 19:00:30 +0000183 if ((*I)->getDeclContext()->isDependentContext())
184 return true;
185
186 if (Args && TemplateSpecializationType::anyDependentTemplateArguments(*Args))
187 return true;
188
189 return false;
190}
191
John McCalle9ee23e2010-04-22 18:44:12 +0000192CXXRecordDecl *OverloadExpr::getNamingClass() const {
193 if (isa<UnresolvedLookupExpr>(this))
194 return cast<UnresolvedLookupExpr>(this)->getNamingClass();
195 else
196 return cast<UnresolvedMemberExpr>(this)->getNamingClass();
197}
198
John McCallba135432009-11-21 08:51:07 +0000199Stmt::child_iterator UnresolvedLookupExpr::child_begin() {
Mike Stump1eb44332009-09-09 15:08:12 +0000200 return child_iterator();
Douglas Gregor5c37de72008-12-06 00:22:45 +0000201}
John McCallba135432009-11-21 08:51:07 +0000202Stmt::child_iterator UnresolvedLookupExpr::child_end() {
Douglas Gregor5c37de72008-12-06 00:22:45 +0000203 return child_iterator();
204}
Sebastian Redl64b45f72009-01-05 20:52:13 +0000205// UnaryTypeTraitExpr
206Stmt::child_iterator UnaryTypeTraitExpr::child_begin() {
207 return child_iterator();
208}
209Stmt::child_iterator UnaryTypeTraitExpr::child_end() {
210 return child_iterator();
211}
212
John McCall865d4472009-11-19 22:55:06 +0000213// DependentScopeDeclRefExpr
John McCallf7a1a742009-11-24 19:00:30 +0000214DependentScopeDeclRefExpr *
215DependentScopeDeclRefExpr::Create(ASTContext &C,
216 NestedNameSpecifier *Qualifier,
217 SourceRange QualifierRange,
218 DeclarationName Name,
219 SourceLocation NameLoc,
220 const TemplateArgumentListInfo *Args) {
221 std::size_t size = sizeof(DependentScopeDeclRefExpr);
222 if (Args) size += ExplicitTemplateArgumentList::sizeFor(*Args);
223 void *Mem = C.Allocate(size);
224
225 DependentScopeDeclRefExpr *DRE
226 = new (Mem) DependentScopeDeclRefExpr(C.DependentTy,
227 Qualifier, QualifierRange,
228 Name, NameLoc,
229 Args != 0);
230
231 if (Args)
232 reinterpret_cast<ExplicitTemplateArgumentList*>(DRE+1)
233 ->initializeFrom(*Args);
234
235 return DRE;
236}
237
John McCall865d4472009-11-19 22:55:06 +0000238StmtIterator DependentScopeDeclRefExpr::child_begin() {
Douglas Gregor5953d8b2009-03-19 17:26:29 +0000239 return child_iterator();
240}
241
John McCall865d4472009-11-19 22:55:06 +0000242StmtIterator DependentScopeDeclRefExpr::child_end() {
Douglas Gregor5953d8b2009-03-19 17:26:29 +0000243 return child_iterator();
244}
245
Douglas Gregor5e03f9e2009-07-23 23:49:00 +0000246bool UnaryTypeTraitExpr::EvaluateTrait(ASTContext& C) const {
Sebastian Redl64b45f72009-01-05 20:52:13 +0000247 switch(UTT) {
248 default: assert(false && "Unknown type trait or not implemented");
249 case UTT_IsPOD: return QueriedType->isPODType();
Sebastian Redlccf43502009-12-03 00:13:20 +0000250 case UTT_IsLiteral: return QueriedType->isLiteralType();
Sebastian Redl64b45f72009-01-05 20:52:13 +0000251 case UTT_IsClass: // Fallthrough
252 case UTT_IsUnion:
Ted Kremenek6217b802009-07-29 21:53:49 +0000253 if (const RecordType *Record = QueriedType->getAs<RecordType>()) {
Sebastian Redl64b45f72009-01-05 20:52:13 +0000254 bool Union = Record->getDecl()->isUnion();
255 return UTT == UTT_IsUnion ? Union : !Union;
256 }
257 return false;
258 case UTT_IsEnum: return QueriedType->isEnumeralType();
259 case UTT_IsPolymorphic:
Ted Kremenek6217b802009-07-29 21:53:49 +0000260 if (const RecordType *Record = QueriedType->getAs<RecordType>()) {
Sebastian Redl64b45f72009-01-05 20:52:13 +0000261 // Type traits are only parsed in C++, so we've got CXXRecords.
262 return cast<CXXRecordDecl>(Record->getDecl())->isPolymorphic();
263 }
264 return false;
Anders Carlsson67e4dd22009-03-22 01:52:17 +0000265 case UTT_IsAbstract:
Ted Kremenek6217b802009-07-29 21:53:49 +0000266 if (const RecordType *RT = QueriedType->getAs<RecordType>())
Anders Carlsson67e4dd22009-03-22 01:52:17 +0000267 return cast<CXXRecordDecl>(RT->getDecl())->isAbstract();
268 return false;
Eli Friedman1d954f62009-08-15 21:55:26 +0000269 case UTT_IsEmpty:
270 if (const RecordType *Record = QueriedType->getAs<RecordType>()) {
271 return !Record->getDecl()->isUnion()
272 && cast<CXXRecordDecl>(Record->getDecl())->isEmpty();
273 }
274 return false;
Anders Carlsson347ba892009-04-16 00:08:20 +0000275 case UTT_HasTrivialConstructor:
Douglas Gregor5e03f9e2009-07-23 23:49:00 +0000276 // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
277 // If __is_pod (type) is true then the trait is true, else if type is
278 // a cv class or union type (or array thereof) with a trivial default
279 // constructor ([class.ctor]) then the trait is true, else it is false.
280 if (QueriedType->isPODType())
281 return true;
282 if (const RecordType *RT =
Ted Kremenek6217b802009-07-29 21:53:49 +0000283 C.getBaseElementType(QueriedType)->getAs<RecordType>())
Anders Carlsson347ba892009-04-16 00:08:20 +0000284 return cast<CXXRecordDecl>(RT->getDecl())->hasTrivialConstructor();
Anders Carlsson072abef2009-04-17 02:34:54 +0000285 return false;
Douglas Gregor5e03f9e2009-07-23 23:49:00 +0000286 case UTT_HasTrivialCopy:
287 // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
288 // If __is_pod (type) is true or type is a reference type then
289 // the trait is true, else if type is a cv class or union type
290 // with a trivial copy constructor ([class.copy]) then the trait
291 // is true, else it is false.
292 if (QueriedType->isPODType() || QueriedType->isReferenceType())
293 return true;
Ted Kremenek6217b802009-07-29 21:53:49 +0000294 if (const RecordType *RT = QueriedType->getAs<RecordType>())
Douglas Gregor5e03f9e2009-07-23 23:49:00 +0000295 return cast<CXXRecordDecl>(RT->getDecl())->hasTrivialCopyConstructor();
296 return false;
297 case UTT_HasTrivialAssign:
298 // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
299 // If type is const qualified or is a reference type then the
300 // trait is false. Otherwise if __is_pod (type) is true then the
301 // trait is true, else if type is a cv class or union type with
302 // a trivial copy assignment ([class.copy]) then the trait is
303 // true, else it is false.
304 // Note: the const and reference restrictions are interesting,
305 // given that const and reference members don't prevent a class
306 // from having a trivial copy assignment operator (but do cause
307 // errors if the copy assignment operator is actually used, q.v.
308 // [class.copy]p12).
309
310 if (C.getBaseElementType(QueriedType).isConstQualified())
311 return false;
312 if (QueriedType->isPODType())
313 return true;
Ted Kremenek6217b802009-07-29 21:53:49 +0000314 if (const RecordType *RT = QueriedType->getAs<RecordType>())
Douglas Gregor5e03f9e2009-07-23 23:49:00 +0000315 return cast<CXXRecordDecl>(RT->getDecl())->hasTrivialCopyAssignment();
316 return false;
317 case UTT_HasTrivialDestructor:
318 // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
319 // If __is_pod (type) is true or type is a reference type
320 // then the trait is true, else if type is a cv class or union
321 // type (or array thereof) with a trivial destructor
322 // ([class.dtor]) then the trait is true, else it is
323 // false.
324 if (QueriedType->isPODType() || QueriedType->isReferenceType())
325 return true;
326 if (const RecordType *RT =
Ted Kremenek6217b802009-07-29 21:53:49 +0000327 C.getBaseElementType(QueriedType)->getAs<RecordType>())
Anders Carlsson072abef2009-04-17 02:34:54 +0000328 return cast<CXXRecordDecl>(RT->getDecl())->hasTrivialDestructor();
329 return false;
Sebastian Redl64b45f72009-01-05 20:52:13 +0000330 }
331}
332
Ted Kremeneke3837682009-12-23 04:00:48 +0000333SourceRange CXXConstructExpr::getSourceRange() const {
334 // FIXME: Should we know where the parentheses are, if there are any?
335 for (std::reverse_iterator<Stmt**> I(&Args[NumArgs]), E(&Args[0]); I!=E;++I) {
336 // Ignore CXXDefaultExprs when computing the range, as they don't
337 // have a range.
338 if (!isa<CXXDefaultArgExpr>(*I))
339 return SourceRange(Loc, (*I)->getLocEnd());
340 }
341
342 return SourceRange(Loc);
343}
344
Douglas Gregorb4609802008-11-14 16:09:21 +0000345SourceRange CXXOperatorCallExpr::getSourceRange() const {
346 OverloadedOperatorKind Kind = getOperator();
347 if (Kind == OO_PlusPlus || Kind == OO_MinusMinus) {
348 if (getNumArgs() == 1)
349 // Prefix operator
Mike Stump1eb44332009-09-09 15:08:12 +0000350 return SourceRange(getOperatorLoc(),
Douglas Gregorb4609802008-11-14 16:09:21 +0000351 getArg(0)->getSourceRange().getEnd());
352 else
353 // Postfix operator
354 return SourceRange(getArg(0)->getSourceRange().getEnd(),
355 getOperatorLoc());
356 } else if (Kind == OO_Call) {
357 return SourceRange(getArg(0)->getSourceRange().getBegin(), getRParenLoc());
358 } else if (Kind == OO_Subscript) {
359 return SourceRange(getArg(0)->getSourceRange().getBegin(), getRParenLoc());
360 } else if (getNumArgs() == 1) {
361 return SourceRange(getOperatorLoc(), getArg(0)->getSourceRange().getEnd());
362 } else if (getNumArgs() == 2) {
363 return SourceRange(getArg(0)->getSourceRange().getBegin(),
364 getArg(1)->getSourceRange().getEnd());
365 } else {
366 return SourceRange();
367 }
368}
369
Douglas Gregor88a35142008-12-22 05:46:06 +0000370Expr *CXXMemberCallExpr::getImplicitObjectArgument() {
371 if (MemberExpr *MemExpr = dyn_cast<MemberExpr>(getCallee()->IgnoreParens()))
372 return MemExpr->getBase();
373
374 // FIXME: Will eventually need to cope with member pointers.
375 return 0;
376}
377
Douglas Gregor00b98c22009-11-12 15:31:47 +0000378SourceRange CXXMemberCallExpr::getSourceRange() const {
379 SourceLocation LocStart = getCallee()->getLocStart();
380 if (LocStart.isInvalid() && getNumArgs() > 0)
381 LocStart = getArg(0)->getLocStart();
382 return SourceRange(LocStart, getRParenLoc());
383}
384
385
Douglas Gregor49badde2008-10-27 19:41:14 +0000386//===----------------------------------------------------------------------===//
387// Named casts
388//===----------------------------------------------------------------------===//
389
390/// getCastName - Get the name of the C++ cast being used, e.g.,
391/// "static_cast", "dynamic_cast", "reinterpret_cast", or
392/// "const_cast". The returned pointer must not be freed.
393const char *CXXNamedCastExpr::getCastName() const {
394 switch (getStmtClass()) {
395 case CXXStaticCastExprClass: return "static_cast";
396 case CXXDynamicCastExprClass: return "dynamic_cast";
397 case CXXReinterpretCastExprClass: return "reinterpret_cast";
398 case CXXConstCastExprClass: return "const_cast";
399 default: return "<invalid cast>";
400 }
401}
Douglas Gregor506ae412009-01-16 18:33:17 +0000402
Douglas Gregor65222e82009-12-23 18:19:08 +0000403CXXDefaultArgExpr *
Douglas Gregor036aed12009-12-23 23:03:06 +0000404CXXDefaultArgExpr::Create(ASTContext &C, SourceLocation Loc,
405 ParmVarDecl *Param, Expr *SubExpr) {
Douglas Gregor65222e82009-12-23 18:19:08 +0000406 void *Mem = C.Allocate(sizeof(CXXDefaultArgExpr) + sizeof(Stmt *));
Douglas Gregor036aed12009-12-23 23:03:06 +0000407 return new (Mem) CXXDefaultArgExpr(CXXDefaultArgExprClass, Loc, Param,
408 SubExpr);
Douglas Gregor65222e82009-12-23 18:19:08 +0000409}
410
411void CXXDefaultArgExpr::DoDestroy(ASTContext &C) {
412 if (Param.getInt())
413 getExpr()->Destroy(C);
414 this->~CXXDefaultArgExpr();
415 C.Deallocate(this);
416}
417
Mike Stump1eb44332009-09-09 15:08:12 +0000418CXXTemporary *CXXTemporary::Create(ASTContext &C,
Anders Carlssonb859f352009-05-30 20:34:37 +0000419 const CXXDestructorDecl *Destructor) {
Anders Carlsson88eaf072009-05-30 22:38:53 +0000420 return new (C) CXXTemporary(Destructor);
421}
422
Douglas Gregor42602bb2009-08-07 06:08:38 +0000423void CXXTemporary::Destroy(ASTContext &Ctx) {
Anders Carlsson88eaf072009-05-30 22:38:53 +0000424 this->~CXXTemporary();
Douglas Gregor42602bb2009-08-07 06:08:38 +0000425 Ctx.Deallocate(this);
Anders Carlssonc1ce4772009-05-30 19:54:15 +0000426}
427
Mike Stump1eb44332009-09-09 15:08:12 +0000428CXXBindTemporaryExpr *CXXBindTemporaryExpr::Create(ASTContext &C,
Anders Carlssonfceb0a82009-05-30 20:03:25 +0000429 CXXTemporary *Temp,
430 Expr* SubExpr) {
Mike Stump1eb44332009-09-09 15:08:12 +0000431 assert(SubExpr->getType()->isRecordType() &&
Anders Carlssonfceb0a82009-05-30 20:03:25 +0000432 "Expression bound to a temporary must have record type!");
433
Anders Carlssonb859f352009-05-30 20:34:37 +0000434 return new (C) CXXBindTemporaryExpr(Temp, SubExpr);
Anders Carlssonfceb0a82009-05-30 20:03:25 +0000435}
436
Douglas Gregor42602bb2009-08-07 06:08:38 +0000437void CXXBindTemporaryExpr::DoDestroy(ASTContext &C) {
Anders Carlsson88eaf072009-05-30 22:38:53 +0000438 Temp->Destroy(C);
439 this->~CXXBindTemporaryExpr();
440 C.Deallocate(this);
441}
442
Anders Carlssoneb60edf2010-01-29 02:39:32 +0000443CXXBindReferenceExpr *CXXBindReferenceExpr::Create(ASTContext &C, Expr *SubExpr,
444 bool ExtendsLifetime,
445 bool RequiresTemporaryCopy) {
446 return new (C) CXXBindReferenceExpr(SubExpr,
447 ExtendsLifetime,
448 RequiresTemporaryCopy);
449}
450
451void CXXBindReferenceExpr::DoDestroy(ASTContext &C) {
452 this->~CXXBindReferenceExpr();
453 C.Deallocate(this);
454}
455
Anders Carlsson8e587a12009-05-30 20:56:46 +0000456CXXTemporaryObjectExpr::CXXTemporaryObjectExpr(ASTContext &C,
Anders Carlsson26de5492009-04-24 05:23:13 +0000457 CXXConstructorDecl *Cons,
Douglas Gregor506ae412009-01-16 18:33:17 +0000458 QualType writtenTy,
Mike Stump1eb44332009-09-09 15:08:12 +0000459 SourceLocation tyBeginLoc,
Douglas Gregor506ae412009-01-16 18:33:17 +0000460 Expr **Args,
Mike Stump1eb44332009-09-09 15:08:12 +0000461 unsigned NumArgs,
Douglas Gregor506ae412009-01-16 18:33:17 +0000462 SourceLocation rParenLoc)
Douglas Gregor99a2e602009-12-16 01:38:02 +0000463 : CXXConstructExpr(C, CXXTemporaryObjectExprClass, writtenTy, tyBeginLoc,
464 Cons, false, Args, NumArgs),
Anders Carlsson524fa132009-04-24 17:34:38 +0000465 TyBeginLoc(tyBeginLoc), RParenLoc(rParenLoc) {
Douglas Gregor506ae412009-01-16 18:33:17 +0000466}
Anders Carlsson19d28a62009-04-21 02:22:11 +0000467
Mike Stump1eb44332009-09-09 15:08:12 +0000468CXXConstructExpr *CXXConstructExpr::Create(ASTContext &C, QualType T,
Douglas Gregor99a2e602009-12-16 01:38:02 +0000469 SourceLocation Loc,
Anders Carlsson8e587a12009-05-30 20:56:46 +0000470 CXXConstructorDecl *D, bool Elidable,
Douglas Gregor16006c92009-12-16 18:50:27 +0000471 Expr **Args, unsigned NumArgs,
Douglas Gregor9db7dbb2010-01-31 09:12:51 +0000472 bool ZeroInitialization,
473 bool BaseInitialization) {
Douglas Gregor99a2e602009-12-16 01:38:02 +0000474 return new (C) CXXConstructExpr(C, CXXConstructExprClass, T, Loc, D,
Douglas Gregor9db7dbb2010-01-31 09:12:51 +0000475 Elidable, Args, NumArgs, ZeroInitialization,
476 BaseInitialization);
Anders Carlssone349bea2009-04-23 02:32:43 +0000477}
478
Mike Stump1eb44332009-09-09 15:08:12 +0000479CXXConstructExpr::CXXConstructExpr(ASTContext &C, StmtClass SC, QualType T,
Douglas Gregor99a2e602009-12-16 01:38:02 +0000480 SourceLocation Loc,
Anders Carlsson8e587a12009-05-30 20:56:46 +0000481 CXXConstructorDecl *D, bool elidable,
Douglas Gregor16006c92009-12-16 18:50:27 +0000482 Expr **args, unsigned numargs,
Douglas Gregor9db7dbb2010-01-31 09:12:51 +0000483 bool ZeroInitialization,
484 bool BaseInitialization)
Anders Carlssonbd6734e2009-04-24 05:04:04 +0000485: Expr(SC, T,
Anders Carlssone349bea2009-04-23 02:32:43 +0000486 T->isDependentType(),
487 (T->isDependentType() ||
488 CallExpr::hasAnyValueDependentArguments(args, numargs))),
Douglas Gregor16006c92009-12-16 18:50:27 +0000489 Constructor(D), Loc(Loc), Elidable(elidable),
Douglas Gregor9db7dbb2010-01-31 09:12:51 +0000490 ZeroInitialization(ZeroInitialization),
491 BaseInitialization(BaseInitialization), Args(0), NumArgs(numargs)
Douglas Gregor16006c92009-12-16 18:50:27 +0000492{
493 if (NumArgs) {
494 Args = new (C) Stmt*[NumArgs];
495
496 for (unsigned i = 0; i != NumArgs; ++i) {
497 assert(args[i] && "NULL argument in CXXConstructExpr");
498 Args[i] = args[i];
Anders Carlssone349bea2009-04-23 02:32:43 +0000499 }
Douglas Gregor16006c92009-12-16 18:50:27 +0000500 }
Anders Carlssone349bea2009-04-23 02:32:43 +0000501}
502
Douglas Gregor39da0b82009-09-09 23:08:42 +0000503CXXConstructExpr::CXXConstructExpr(EmptyShell Empty, ASTContext &C,
504 unsigned numargs)
505 : Expr(CXXConstructExprClass, Empty), Args(0), NumArgs(numargs)
506{
507 if (NumArgs)
508 Args = new (C) Stmt*[NumArgs];
509}
510
Douglas Gregor42602bb2009-08-07 06:08:38 +0000511void CXXConstructExpr::DoDestroy(ASTContext &C) {
Anders Carlssone349bea2009-04-23 02:32:43 +0000512 DestroyChildren(C);
513 if (Args)
514 C.Deallocate(Args);
515 this->~CXXConstructExpr();
516 C.Deallocate(this);
517}
518
Mike Stump1eb44332009-09-09 15:08:12 +0000519CXXExprWithTemporaries::CXXExprWithTemporaries(Expr *subexpr,
520 CXXTemporary **temps,
Anders Carlsson0ece4912009-12-15 20:51:39 +0000521 unsigned numtemps)
Anders Carlsson2d44e8a2009-05-01 22:18:43 +0000522: Expr(CXXExprWithTemporariesClass, subexpr->getType(),
Mike Stump1eb44332009-09-09 15:08:12 +0000523 subexpr->isTypeDependent(), subexpr->isValueDependent()),
Anders Carlsson0ece4912009-12-15 20:51:39 +0000524 SubExpr(subexpr), Temps(0), NumTemps(numtemps) {
Anders Carlssonff6b3d62009-05-30 21:05:25 +0000525 if (NumTemps > 0) {
526 Temps = new CXXTemporary*[NumTemps];
527 for (unsigned i = 0; i < NumTemps; ++i)
528 Temps[i] = temps[i];
Anders Carlsson02bbfa32009-04-24 22:47:04 +0000529 }
530}
531
Mike Stump1eb44332009-09-09 15:08:12 +0000532CXXExprWithTemporaries *CXXExprWithTemporaries::Create(ASTContext &C,
Anders Carlsson88eaf072009-05-30 22:38:53 +0000533 Expr *SubExpr,
Mike Stump1eb44332009-09-09 15:08:12 +0000534 CXXTemporary **Temps,
Anders Carlsson0ece4912009-12-15 20:51:39 +0000535 unsigned NumTemps) {
536 return new (C) CXXExprWithTemporaries(SubExpr, Temps, NumTemps);
Anders Carlsson88eaf072009-05-30 22:38:53 +0000537}
538
Douglas Gregor42602bb2009-08-07 06:08:38 +0000539void CXXExprWithTemporaries::DoDestroy(ASTContext &C) {
Anders Carlsson88eaf072009-05-30 22:38:53 +0000540 DestroyChildren(C);
541 this->~CXXExprWithTemporaries();
542 C.Deallocate(this);
543}
544
Anders Carlsson2d44e8a2009-05-01 22:18:43 +0000545CXXExprWithTemporaries::~CXXExprWithTemporaries() {
Anders Carlssonff6b3d62009-05-30 21:05:25 +0000546 delete[] Temps;
Anders Carlsson02bbfa32009-04-24 22:47:04 +0000547}
548
Anders Carlssonfceb0a82009-05-30 20:03:25 +0000549// CXXBindTemporaryExpr
550Stmt::child_iterator CXXBindTemporaryExpr::child_begin() {
551 return &SubExpr;
552}
553
Mike Stump1eb44332009-09-09 15:08:12 +0000554Stmt::child_iterator CXXBindTemporaryExpr::child_end() {
Anders Carlssonfceb0a82009-05-30 20:03:25 +0000555 return &SubExpr + 1;
556}
557
Anders Carlssoneb60edf2010-01-29 02:39:32 +0000558// CXXBindReferenceExpr
559Stmt::child_iterator CXXBindReferenceExpr::child_begin() {
560 return &SubExpr;
561}
562
563Stmt::child_iterator CXXBindReferenceExpr::child_end() {
564 return &SubExpr + 1;
565}
566
Anders Carlssone349bea2009-04-23 02:32:43 +0000567// CXXConstructExpr
568Stmt::child_iterator CXXConstructExpr::child_begin() {
569 return &Args[0];
570}
571Stmt::child_iterator CXXConstructExpr::child_end() {
572 return &Args[0]+NumArgs;
573}
574
Anders Carlsson55674ac2009-05-01 22:21:22 +0000575// CXXExprWithTemporaries
576Stmt::child_iterator CXXExprWithTemporaries::child_begin() {
577 return &SubExpr;
Anders Carlsson19d28a62009-04-21 02:22:11 +0000578}
Anders Carlsson02bbfa32009-04-24 22:47:04 +0000579
Mike Stump1eb44332009-09-09 15:08:12 +0000580Stmt::child_iterator CXXExprWithTemporaries::child_end() {
Anders Carlsson55674ac2009-05-01 22:21:22 +0000581 return &SubExpr + 1;
582}
Anders Carlsson02bbfa32009-04-24 22:47:04 +0000583
Douglas Gregord81e6ca2009-05-20 18:46:25 +0000584CXXUnresolvedConstructExpr::CXXUnresolvedConstructExpr(
585 SourceLocation TyBeginLoc,
586 QualType T,
587 SourceLocation LParenLoc,
588 Expr **Args,
589 unsigned NumArgs,
590 SourceLocation RParenLoc)
591 : Expr(CXXUnresolvedConstructExprClass, T.getNonReferenceType(),
592 T->isDependentType(), true),
593 TyBeginLoc(TyBeginLoc),
594 Type(T),
595 LParenLoc(LParenLoc),
596 RParenLoc(RParenLoc),
597 NumArgs(NumArgs) {
598 Stmt **StoredArgs = reinterpret_cast<Stmt **>(this + 1);
599 memcpy(StoredArgs, Args, sizeof(Expr *) * NumArgs);
600}
601
602CXXUnresolvedConstructExpr *
Mike Stump1eb44332009-09-09 15:08:12 +0000603CXXUnresolvedConstructExpr::Create(ASTContext &C,
Douglas Gregord81e6ca2009-05-20 18:46:25 +0000604 SourceLocation TyBegin,
605 QualType T,
606 SourceLocation LParenLoc,
607 Expr **Args,
608 unsigned NumArgs,
609 SourceLocation RParenLoc) {
610 void *Mem = C.Allocate(sizeof(CXXUnresolvedConstructExpr) +
611 sizeof(Expr *) * NumArgs);
612 return new (Mem) CXXUnresolvedConstructExpr(TyBegin, T, LParenLoc,
613 Args, NumArgs, RParenLoc);
614}
615
616Stmt::child_iterator CXXUnresolvedConstructExpr::child_begin() {
617 return child_iterator(reinterpret_cast<Stmt **>(this + 1));
618}
619
620Stmt::child_iterator CXXUnresolvedConstructExpr::child_end() {
621 return child_iterator(reinterpret_cast<Stmt **>(this + 1) + NumArgs);
622}
Sebastian Redl8b0b4752009-05-16 18:50:46 +0000623
John McCall865d4472009-11-19 22:55:06 +0000624CXXDependentScopeMemberExpr::CXXDependentScopeMemberExpr(ASTContext &C,
John McCallaa81e162009-12-01 22:10:20 +0000625 Expr *Base, QualType BaseType,
626 bool IsArrow,
Douglas Gregor3b6afbb2009-09-09 00:23:06 +0000627 SourceLocation OperatorLoc,
628 NestedNameSpecifier *Qualifier,
629 SourceRange QualifierRange,
630 NamedDecl *FirstQualifierFoundInScope,
631 DeclarationName Member,
632 SourceLocation MemberLoc,
John McCalld5532b62009-11-23 01:53:49 +0000633 const TemplateArgumentListInfo *TemplateArgs)
John McCall865d4472009-11-19 22:55:06 +0000634 : Expr(CXXDependentScopeMemberExprClass, C.DependentTy, true, true),
John McCallaa81e162009-12-01 22:10:20 +0000635 Base(Base), BaseType(BaseType), IsArrow(IsArrow),
636 HasExplicitTemplateArgs(TemplateArgs != 0),
Douglas Gregor3b6afbb2009-09-09 00:23:06 +0000637 OperatorLoc(OperatorLoc),
638 Qualifier(Qualifier), QualifierRange(QualifierRange),
639 FirstQualifierFoundInScope(FirstQualifierFoundInScope),
Mike Stump1eb44332009-09-09 15:08:12 +0000640 Member(Member), MemberLoc(MemberLoc) {
John McCalld5532b62009-11-23 01:53:49 +0000641 if (TemplateArgs)
642 getExplicitTemplateArgumentList()->initializeFrom(*TemplateArgs);
Douglas Gregor3b6afbb2009-09-09 00:23:06 +0000643}
644
John McCall865d4472009-11-19 22:55:06 +0000645CXXDependentScopeMemberExpr *
646CXXDependentScopeMemberExpr::Create(ASTContext &C,
John McCallaa81e162009-12-01 22:10:20 +0000647 Expr *Base, QualType BaseType, bool IsArrow,
Douglas Gregor3b6afbb2009-09-09 00:23:06 +0000648 SourceLocation OperatorLoc,
649 NestedNameSpecifier *Qualifier,
650 SourceRange QualifierRange,
651 NamedDecl *FirstQualifierFoundInScope,
652 DeclarationName Member,
653 SourceLocation MemberLoc,
John McCalld5532b62009-11-23 01:53:49 +0000654 const TemplateArgumentListInfo *TemplateArgs) {
655 if (!TemplateArgs)
John McCallaa81e162009-12-01 22:10:20 +0000656 return new (C) CXXDependentScopeMemberExpr(C, Base, BaseType,
657 IsArrow, OperatorLoc,
658 Qualifier, QualifierRange,
659 FirstQualifierFoundInScope,
660 Member, MemberLoc);
Mike Stump1eb44332009-09-09 15:08:12 +0000661
John McCalld5532b62009-11-23 01:53:49 +0000662 std::size_t size = sizeof(CXXDependentScopeMemberExpr);
663 if (TemplateArgs)
664 size += ExplicitTemplateArgumentList::sizeFor(*TemplateArgs);
665
666 void *Mem = C.Allocate(size, llvm::alignof<CXXDependentScopeMemberExpr>());
John McCallaa81e162009-12-01 22:10:20 +0000667 return new (Mem) CXXDependentScopeMemberExpr(C, Base, BaseType,
668 IsArrow, OperatorLoc,
669 Qualifier, QualifierRange,
670 FirstQualifierFoundInScope,
671 Member, MemberLoc, TemplateArgs);
Douglas Gregor3b6afbb2009-09-09 00:23:06 +0000672}
673
John McCall865d4472009-11-19 22:55:06 +0000674Stmt::child_iterator CXXDependentScopeMemberExpr::child_begin() {
Douglas Gregor1c0ca592009-05-22 21:13:27 +0000675 return child_iterator(&Base);
676}
677
John McCall865d4472009-11-19 22:55:06 +0000678Stmt::child_iterator CXXDependentScopeMemberExpr::child_end() {
John McCallaa81e162009-12-01 22:10:20 +0000679 if (isImplicitAccess())
680 return child_iterator(&Base);
Douglas Gregor1c0ca592009-05-22 21:13:27 +0000681 return child_iterator(&Base + 1);
682}
John McCall129e2df2009-11-30 22:42:35 +0000683
684UnresolvedMemberExpr::UnresolvedMemberExpr(QualType T, bool Dependent,
685 bool HasUnresolvedUsing,
John McCallaa81e162009-12-01 22:10:20 +0000686 Expr *Base, QualType BaseType,
687 bool IsArrow,
John McCall129e2df2009-11-30 22:42:35 +0000688 SourceLocation OperatorLoc,
689 NestedNameSpecifier *Qualifier,
690 SourceRange QualifierRange,
691 DeclarationName MemberName,
692 SourceLocation MemberLoc,
693 const TemplateArgumentListInfo *TemplateArgs)
John McCall7bb12da2010-02-02 06:20:04 +0000694 : OverloadExpr(UnresolvedMemberExprClass, T, Dependent,
695 Qualifier, QualifierRange, MemberName, MemberLoc,
696 TemplateArgs != 0),
697 IsArrow(IsArrow), HasUnresolvedUsing(HasUnresolvedUsing),
698 Base(Base), BaseType(BaseType), OperatorLoc(OperatorLoc) {
John McCall129e2df2009-11-30 22:42:35 +0000699 if (TemplateArgs)
John McCall7bb12da2010-02-02 06:20:04 +0000700 getExplicitTemplateArgs().initializeFrom(*TemplateArgs);
John McCall129e2df2009-11-30 22:42:35 +0000701}
702
703UnresolvedMemberExpr *
704UnresolvedMemberExpr::Create(ASTContext &C, bool Dependent,
705 bool HasUnresolvedUsing,
John McCallaa81e162009-12-01 22:10:20 +0000706 Expr *Base, QualType BaseType, bool IsArrow,
John McCall129e2df2009-11-30 22:42:35 +0000707 SourceLocation OperatorLoc,
708 NestedNameSpecifier *Qualifier,
709 SourceRange QualifierRange,
710 DeclarationName Member,
711 SourceLocation MemberLoc,
712 const TemplateArgumentListInfo *TemplateArgs) {
713 std::size_t size = sizeof(UnresolvedMemberExpr);
714 if (TemplateArgs)
715 size += ExplicitTemplateArgumentList::sizeFor(*TemplateArgs);
716
717 void *Mem = C.Allocate(size, llvm::alignof<UnresolvedMemberExpr>());
718 return new (Mem) UnresolvedMemberExpr(
719 Dependent ? C.DependentTy : C.OverloadTy,
John McCallaa81e162009-12-01 22:10:20 +0000720 Dependent, HasUnresolvedUsing, Base, BaseType,
721 IsArrow, OperatorLoc, Qualifier, QualifierRange,
John McCall129e2df2009-11-30 22:42:35 +0000722 Member, MemberLoc, TemplateArgs);
723}
724
John McCallc373d482010-01-27 01:50:18 +0000725CXXRecordDecl *UnresolvedMemberExpr::getNamingClass() const {
726 // Unlike for UnresolvedLookupExpr, it is very easy to re-derive this.
727
728 // If there was a nested name specifier, it names the naming class.
729 // It can't be dependent: after all, we were actually able to do the
730 // lookup.
731 const RecordType *RT;
John McCall7bb12da2010-02-02 06:20:04 +0000732 if (getQualifier()) {
733 Type *T = getQualifier()->getAsType();
John McCallc373d482010-01-27 01:50:18 +0000734 assert(T && "qualifier in member expression does not name type");
735 RT = T->getAs<RecordType>();
736 assert(RT && "qualifier in member expression does not name record");
737
738 // Otherwise the naming class must have been the base class.
739 } else {
740 QualType BaseType = getBaseType().getNonReferenceType();
741 if (isArrow()) {
742 const PointerType *PT = BaseType->getAs<PointerType>();
743 assert(PT && "base of arrow member access is not pointer");
744 BaseType = PT->getPointeeType();
745 }
746
747 RT = BaseType->getAs<RecordType>();
748 assert(RT && "base of member expression does not name record");
749 }
750
751 return cast<CXXRecordDecl>(RT->getDecl());
752}
753
John McCall129e2df2009-11-30 22:42:35 +0000754Stmt::child_iterator UnresolvedMemberExpr::child_begin() {
755 return child_iterator(&Base);
756}
757
758Stmt::child_iterator UnresolvedMemberExpr::child_end() {
John McCallaa81e162009-12-01 22:10:20 +0000759 if (isImplicitAccess())
760 return child_iterator(&Base);
John McCall129e2df2009-11-30 22:42:35 +0000761 return child_iterator(&Base + 1);
762}