blob: 454dc14b6c88c97765b8c767f5f28bd13b2bf063 [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"
18using namespace clang;
19
20//===----------------------------------------------------------------------===//
21// Child Iterators for iterating over subexpressions/substatements
22//===----------------------------------------------------------------------===//
23
Sebastian Redlc42e1182008-11-11 11:37:55 +000024// CXXTypeidExpr - has child iterators if the operand is an expression
25Stmt::child_iterator CXXTypeidExpr::child_begin() {
Sebastian Redld4575892008-12-03 23:17:54 +000026 return isTypeOperand() ? child_iterator() : &Operand.Ex;
Sebastian Redlc42e1182008-11-11 11:37:55 +000027}
28Stmt::child_iterator CXXTypeidExpr::child_end() {
Sebastian Redld4575892008-12-03 23:17:54 +000029 return isTypeOperand() ? child_iterator() : &Operand.Ex+1;
Sebastian Redlc42e1182008-11-11 11:37:55 +000030}
Ted Kremeneka758d092007-08-24 20:21:10 +000031
Ted Kremeneka758d092007-08-24 20:21:10 +000032// CXXBoolLiteralExpr
Ted Kremenek9ac59282007-10-18 23:28:49 +000033Stmt::child_iterator CXXBoolLiteralExpr::child_begin() {
34 return child_iterator();
35}
36Stmt::child_iterator CXXBoolLiteralExpr::child_end() {
37 return child_iterator();
38}
Chris Lattner50dd2892008-02-26 00:51:44 +000039
Sebastian Redl6e8ed162009-05-10 18:38:11 +000040// CXXNullPtrLiteralExpr
41Stmt::child_iterator CXXNullPtrLiteralExpr::child_begin() {
42 return child_iterator();
43}
44Stmt::child_iterator CXXNullPtrLiteralExpr::child_end() {
45 return child_iterator();
46}
47
Douglas Gregor796da182008-11-04 14:32:21 +000048// CXXThisExpr
49Stmt::child_iterator CXXThisExpr::child_begin() { return child_iterator(); }
50Stmt::child_iterator CXXThisExpr::child_end() { return child_iterator(); }
51
Chris Lattner50dd2892008-02-26 00:51:44 +000052// CXXThrowExpr
Ted Kremenek1060aff2008-06-17 03:11:08 +000053Stmt::child_iterator CXXThrowExpr::child_begin() { return &Op; }
Chris Lattner50dd2892008-02-26 00:51:44 +000054Stmt::child_iterator CXXThrowExpr::child_end() {
55 // If Op is 0, we are processing throw; which has no children.
Ted Kremenek1060aff2008-06-17 03:11:08 +000056 return Op ? &Op+1 : &Op;
Chris Lattner50dd2892008-02-26 00:51:44 +000057}
Chris Lattner04421082008-04-08 04:40:51 +000058
59// CXXDefaultArgExpr
60Stmt::child_iterator CXXDefaultArgExpr::child_begin() {
Chris Lattner8123a952008-04-10 02:22:51 +000061 return child_iterator();
Chris Lattner04421082008-04-08 04:40:51 +000062}
63Stmt::child_iterator CXXDefaultArgExpr::child_end() {
Chris Lattner8123a952008-04-10 02:22:51 +000064 return child_iterator();
Chris Lattner04421082008-04-08 04:40:51 +000065}
Argyrios Kyrtzidis987a14b2008-08-22 15:38:55 +000066
67// CXXZeroInitValueExpr
68Stmt::child_iterator CXXZeroInitValueExpr::child_begin() {
69 return child_iterator();
70}
71Stmt::child_iterator CXXZeroInitValueExpr::child_end() {
72 return child_iterator();
73}
Argyrios Kyrtzidis9e922b12008-09-09 23:47:53 +000074
75// CXXConditionDeclExpr
76Stmt::child_iterator CXXConditionDeclExpr::child_begin() {
77 return getVarDecl();
78}
79Stmt::child_iterator CXXConditionDeclExpr::child_end() {
80 return child_iterator();
81}
Douglas Gregor49badde2008-10-27 19:41:14 +000082
Sebastian Redl4c5d3202008-11-21 19:14:01 +000083// CXXNewExpr
84CXXNewExpr::CXXNewExpr(bool globalNew, FunctionDecl *operatorNew,
85 Expr **placementArgs, unsigned numPlaceArgs,
Sebastian Redlcee63fb2008-12-02 14:43:59 +000086 bool parenTypeId, Expr *arraySize,
Sebastian Redl4c5d3202008-11-21 19:14:01 +000087 CXXConstructorDecl *constructor, bool initializer,
88 Expr **constructorArgs, unsigned numConsArgs,
89 FunctionDecl *operatorDelete, QualType ty,
90 SourceLocation startLoc, SourceLocation endLoc)
Sebastian Redl28507842009-02-26 14:39:58 +000091 : Expr(CXXNewExprClass, ty, ty->isDependentType(), ty->isDependentType()),
92 GlobalNew(globalNew), ParenTypeId(parenTypeId),
Sebastian Redlcee63fb2008-12-02 14:43:59 +000093 Initializer(initializer), Array(arraySize), NumPlacementArgs(numPlaceArgs),
Sebastian Redl4c5d3202008-11-21 19:14:01 +000094 NumConstructorArgs(numConsArgs), OperatorNew(operatorNew),
Sebastian Redlcee63fb2008-12-02 14:43:59 +000095 OperatorDelete(operatorDelete), Constructor(constructor),
Sebastian Redl4c5d3202008-11-21 19:14:01 +000096 StartLoc(startLoc), EndLoc(endLoc)
97{
Sebastian Redlcee63fb2008-12-02 14:43:59 +000098 unsigned TotalSize = Array + NumPlacementArgs + NumConstructorArgs;
Sebastian Redl4c5d3202008-11-21 19:14:01 +000099 SubExprs = new Stmt*[TotalSize];
100 unsigned i = 0;
Sebastian Redlcee63fb2008-12-02 14:43:59 +0000101 if (Array)
102 SubExprs[i++] = arraySize;
103 for (unsigned j = 0; j < NumPlacementArgs; ++j)
Sebastian Redl4c5d3202008-11-21 19:14:01 +0000104 SubExprs[i++] = placementArgs[j];
Sebastian Redlcee63fb2008-12-02 14:43:59 +0000105 for (unsigned j = 0; j < NumConstructorArgs; ++j)
Sebastian Redl4c5d3202008-11-21 19:14:01 +0000106 SubExprs[i++] = constructorArgs[j];
107 assert(i == TotalSize);
108}
109
110Stmt::child_iterator CXXNewExpr::child_begin() { return &SubExprs[0]; }
111Stmt::child_iterator CXXNewExpr::child_end() {
Sebastian Redlcee63fb2008-12-02 14:43:59 +0000112 return &SubExprs[0] + Array + getNumPlacementArgs() + getNumConstructorArgs();
Sebastian Redl4c5d3202008-11-21 19:14:01 +0000113}
114
115// CXXDeleteExpr
116Stmt::child_iterator CXXDeleteExpr::child_begin() { return &Argument; }
117Stmt::child_iterator CXXDeleteExpr::child_end() { return &Argument+1; }
118
Douglas Gregor17330012009-02-04 15:01:18 +0000119// UnresolvedFunctionNameExpr
120Stmt::child_iterator UnresolvedFunctionNameExpr::child_begin() {
Douglas Gregor5c37de72008-12-06 00:22:45 +0000121 return child_iterator();
122}
Douglas Gregor17330012009-02-04 15:01:18 +0000123Stmt::child_iterator UnresolvedFunctionNameExpr::child_end() {
Douglas Gregor5c37de72008-12-06 00:22:45 +0000124 return child_iterator();
125}
Sebastian Redl64b45f72009-01-05 20:52:13 +0000126// UnaryTypeTraitExpr
127Stmt::child_iterator UnaryTypeTraitExpr::child_begin() {
128 return child_iterator();
129}
130Stmt::child_iterator UnaryTypeTraitExpr::child_end() {
131 return child_iterator();
132}
133
Douglas Gregor5953d8b2009-03-19 17:26:29 +0000134// UnresolvedDeclRefExpr
135StmtIterator UnresolvedDeclRefExpr::child_begin() {
136 return child_iterator();
137}
138
139StmtIterator UnresolvedDeclRefExpr::child_end() {
140 return child_iterator();
141}
142
Douglas Gregoredce4dd2009-06-30 22:34:41 +0000143TemplateIdRefExpr::TemplateIdRefExpr(QualType T,
144 NestedNameSpecifier *Qualifier,
145 SourceRange QualifierRange,
146 TemplateName Template,
147 SourceLocation TemplateNameLoc,
148 SourceLocation LAngleLoc,
149 const TemplateArgument *TemplateArgs,
150 unsigned NumTemplateArgs,
151 SourceLocation RAngleLoc)
152 : Expr(TemplateIdRefExprClass, T,
153 (Template.isDependent() ||
154 TemplateSpecializationType::anyDependentTemplateArguments(
155 TemplateArgs, NumTemplateArgs)),
156 (Template.isDependent() ||
157 TemplateSpecializationType::anyDependentTemplateArguments(
158 TemplateArgs, NumTemplateArgs))),
159 Qualifier(Qualifier), QualifierRange(QualifierRange), Template(Template),
160 TemplateNameLoc(TemplateNameLoc), LAngleLoc(LAngleLoc),
161 RAngleLoc(RAngleLoc), NumTemplateArgs(NumTemplateArgs)
162
163{
164 TemplateArgument *StoredTemplateArgs
165 = reinterpret_cast<TemplateArgument *> (this+1);
166 for (unsigned I = 0; I != NumTemplateArgs; ++I)
167 new (StoredTemplateArgs + I) TemplateArgument(TemplateArgs[I]);
168}
169
170TemplateIdRefExpr *
171TemplateIdRefExpr::Create(ASTContext &Context, QualType T,
172 NestedNameSpecifier *Qualifier,
173 SourceRange QualifierRange,
174 TemplateName Template, SourceLocation TemplateNameLoc,
175 SourceLocation LAngleLoc,
176 const TemplateArgument *TemplateArgs,
177 unsigned NumTemplateArgs, SourceLocation RAngleLoc) {
178 void *Mem = Context.Allocate(sizeof(TemplateIdRefExpr) +
179 sizeof(TemplateArgument) * NumTemplateArgs);
180 return new (Mem) TemplateIdRefExpr(T, Qualifier, QualifierRange, Template,
181 TemplateNameLoc, LAngleLoc, TemplateArgs,
182 NumTemplateArgs, RAngleLoc);
183}
184
Douglas Gregor42602bb2009-08-07 06:08:38 +0000185void TemplateIdRefExpr::DoDestroy(ASTContext &Context) {
Douglas Gregoredce4dd2009-06-30 22:34:41 +0000186 const TemplateArgument *TemplateArgs = getTemplateArgs();
187 for (unsigned I = 0; I != NumTemplateArgs; ++I)
188 if (Expr *E = TemplateArgs[I].getAsExpr())
189 E->Destroy(Context);
Douglas Gregor42602bb2009-08-07 06:08:38 +0000190 this->~TemplateIdRefExpr();
191 Context.Deallocate(this);
Douglas Gregoredce4dd2009-06-30 22:34:41 +0000192}
193
194Stmt::child_iterator TemplateIdRefExpr::child_begin() {
195 // FIXME: Walk the expressions in the template arguments (?)
196 return Stmt::child_iterator();
197}
198
199Stmt::child_iterator TemplateIdRefExpr::child_end() {
200 // FIXME: Walk the expressions in the template arguments (?)
201 return Stmt::child_iterator();
202}
203
Douglas Gregor5e03f9e2009-07-23 23:49:00 +0000204bool UnaryTypeTraitExpr::EvaluateTrait(ASTContext& C) const {
Sebastian Redl64b45f72009-01-05 20:52:13 +0000205 switch(UTT) {
206 default: assert(false && "Unknown type trait or not implemented");
207 case UTT_IsPOD: return QueriedType->isPODType();
208 case UTT_IsClass: // Fallthrough
209 case UTT_IsUnion:
Ted Kremenek6217b802009-07-29 21:53:49 +0000210 if (const RecordType *Record = QueriedType->getAs<RecordType>()) {
Sebastian Redl64b45f72009-01-05 20:52:13 +0000211 bool Union = Record->getDecl()->isUnion();
212 return UTT == UTT_IsUnion ? Union : !Union;
213 }
214 return false;
215 case UTT_IsEnum: return QueriedType->isEnumeralType();
216 case UTT_IsPolymorphic:
Ted Kremenek6217b802009-07-29 21:53:49 +0000217 if (const RecordType *Record = QueriedType->getAs<RecordType>()) {
Sebastian Redl64b45f72009-01-05 20:52:13 +0000218 // Type traits are only parsed in C++, so we've got CXXRecords.
219 return cast<CXXRecordDecl>(Record->getDecl())->isPolymorphic();
220 }
221 return false;
Anders Carlsson67e4dd22009-03-22 01:52:17 +0000222 case UTT_IsAbstract:
Ted Kremenek6217b802009-07-29 21:53:49 +0000223 if (const RecordType *RT = QueriedType->getAs<RecordType>())
Anders Carlsson67e4dd22009-03-22 01:52:17 +0000224 return cast<CXXRecordDecl>(RT->getDecl())->isAbstract();
225 return false;
Anders Carlsson347ba892009-04-16 00:08:20 +0000226 case UTT_HasTrivialConstructor:
Douglas Gregor5e03f9e2009-07-23 23:49:00 +0000227 // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
228 // If __is_pod (type) is true then the trait is true, else if type is
229 // a cv class or union type (or array thereof) with a trivial default
230 // constructor ([class.ctor]) then the trait is true, else it is false.
231 if (QueriedType->isPODType())
232 return true;
233 if (const RecordType *RT =
Ted Kremenek6217b802009-07-29 21:53:49 +0000234 C.getBaseElementType(QueriedType)->getAs<RecordType>())
Anders Carlsson347ba892009-04-16 00:08:20 +0000235 return cast<CXXRecordDecl>(RT->getDecl())->hasTrivialConstructor();
Anders Carlsson072abef2009-04-17 02:34:54 +0000236 return false;
Douglas Gregor5e03f9e2009-07-23 23:49:00 +0000237 case UTT_HasTrivialCopy:
238 // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
239 // If __is_pod (type) is true or type is a reference type then
240 // the trait is true, else if type is a cv class or union type
241 // with a trivial copy constructor ([class.copy]) then the trait
242 // is true, else it is false.
243 if (QueriedType->isPODType() || QueriedType->isReferenceType())
244 return true;
Ted Kremenek6217b802009-07-29 21:53:49 +0000245 if (const RecordType *RT = QueriedType->getAs<RecordType>())
Douglas Gregor5e03f9e2009-07-23 23:49:00 +0000246 return cast<CXXRecordDecl>(RT->getDecl())->hasTrivialCopyConstructor();
247 return false;
248 case UTT_HasTrivialAssign:
249 // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
250 // If type is const qualified or is a reference type then the
251 // trait is false. Otherwise if __is_pod (type) is true then the
252 // trait is true, else if type is a cv class or union type with
253 // a trivial copy assignment ([class.copy]) then the trait is
254 // true, else it is false.
255 // Note: the const and reference restrictions are interesting,
256 // given that const and reference members don't prevent a class
257 // from having a trivial copy assignment operator (but do cause
258 // errors if the copy assignment operator is actually used, q.v.
259 // [class.copy]p12).
260
261 if (C.getBaseElementType(QueriedType).isConstQualified())
262 return false;
263 if (QueriedType->isPODType())
264 return true;
Ted Kremenek6217b802009-07-29 21:53:49 +0000265 if (const RecordType *RT = QueriedType->getAs<RecordType>())
Douglas Gregor5e03f9e2009-07-23 23:49:00 +0000266 return cast<CXXRecordDecl>(RT->getDecl())->hasTrivialCopyAssignment();
267 return false;
268 case UTT_HasTrivialDestructor:
269 // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
270 // If __is_pod (type) is true or type is a reference type
271 // then the trait is true, else if type is a cv class or union
272 // type (or array thereof) with a trivial destructor
273 // ([class.dtor]) then the trait is true, else it is
274 // false.
275 if (QueriedType->isPODType() || QueriedType->isReferenceType())
276 return true;
277 if (const RecordType *RT =
Ted Kremenek6217b802009-07-29 21:53:49 +0000278 C.getBaseElementType(QueriedType)->getAs<RecordType>())
Anders Carlsson072abef2009-04-17 02:34:54 +0000279 return cast<CXXRecordDecl>(RT->getDecl())->hasTrivialDestructor();
280 return false;
Sebastian Redl64b45f72009-01-05 20:52:13 +0000281 }
282}
283
Douglas Gregorb4609802008-11-14 16:09:21 +0000284SourceRange CXXOperatorCallExpr::getSourceRange() const {
285 OverloadedOperatorKind Kind = getOperator();
286 if (Kind == OO_PlusPlus || Kind == OO_MinusMinus) {
287 if (getNumArgs() == 1)
288 // Prefix operator
289 return SourceRange(getOperatorLoc(),
290 getArg(0)->getSourceRange().getEnd());
291 else
292 // Postfix operator
293 return SourceRange(getArg(0)->getSourceRange().getEnd(),
294 getOperatorLoc());
295 } else if (Kind == OO_Call) {
296 return SourceRange(getArg(0)->getSourceRange().getBegin(), getRParenLoc());
297 } else if (Kind == OO_Subscript) {
298 return SourceRange(getArg(0)->getSourceRange().getBegin(), getRParenLoc());
299 } else if (getNumArgs() == 1) {
300 return SourceRange(getOperatorLoc(), getArg(0)->getSourceRange().getEnd());
301 } else if (getNumArgs() == 2) {
302 return SourceRange(getArg(0)->getSourceRange().getBegin(),
303 getArg(1)->getSourceRange().getEnd());
304 } else {
305 return SourceRange();
306 }
307}
308
Douglas Gregor88a35142008-12-22 05:46:06 +0000309Expr *CXXMemberCallExpr::getImplicitObjectArgument() {
310 if (MemberExpr *MemExpr = dyn_cast<MemberExpr>(getCallee()->IgnoreParens()))
311 return MemExpr->getBase();
312
313 // FIXME: Will eventually need to cope with member pointers.
314 return 0;
315}
316
Douglas Gregor49badde2008-10-27 19:41:14 +0000317//===----------------------------------------------------------------------===//
318// Named casts
319//===----------------------------------------------------------------------===//
320
321/// getCastName - Get the name of the C++ cast being used, e.g.,
322/// "static_cast", "dynamic_cast", "reinterpret_cast", or
323/// "const_cast". The returned pointer must not be freed.
324const char *CXXNamedCastExpr::getCastName() const {
325 switch (getStmtClass()) {
326 case CXXStaticCastExprClass: return "static_cast";
327 case CXXDynamicCastExprClass: return "dynamic_cast";
328 case CXXReinterpretCastExprClass: return "reinterpret_cast";
329 case CXXConstCastExprClass: return "const_cast";
330 default: return "<invalid cast>";
331 }
332}
Douglas Gregor506ae412009-01-16 18:33:17 +0000333
Anders Carlssonc1ce4772009-05-30 19:54:15 +0000334CXXTemporary *CXXTemporary::Create(ASTContext &C,
Anders Carlssonb859f352009-05-30 20:34:37 +0000335 const CXXDestructorDecl *Destructor) {
Anders Carlsson88eaf072009-05-30 22:38:53 +0000336 return new (C) CXXTemporary(Destructor);
337}
338
Douglas Gregor42602bb2009-08-07 06:08:38 +0000339void CXXTemporary::Destroy(ASTContext &Ctx) {
Anders Carlsson88eaf072009-05-30 22:38:53 +0000340 this->~CXXTemporary();
Douglas Gregor42602bb2009-08-07 06:08:38 +0000341 Ctx.Deallocate(this);
Anders Carlssonc1ce4772009-05-30 19:54:15 +0000342}
343
Anders Carlssonfceb0a82009-05-30 20:03:25 +0000344CXXBindTemporaryExpr *CXXBindTemporaryExpr::Create(ASTContext &C,
345 CXXTemporary *Temp,
346 Expr* SubExpr) {
347 assert(SubExpr->getType()->isRecordType() &&
348 "Expression bound to a temporary must have record type!");
349
Anders Carlssonb859f352009-05-30 20:34:37 +0000350 return new (C) CXXBindTemporaryExpr(Temp, SubExpr);
Anders Carlssonfceb0a82009-05-30 20:03:25 +0000351}
352
Douglas Gregor42602bb2009-08-07 06:08:38 +0000353void CXXBindTemporaryExpr::DoDestroy(ASTContext &C) {
Anders Carlsson88eaf072009-05-30 22:38:53 +0000354 Temp->Destroy(C);
355 this->~CXXBindTemporaryExpr();
356 C.Deallocate(this);
357}
358
Anders Carlsson8e587a12009-05-30 20:56:46 +0000359CXXTemporaryObjectExpr::CXXTemporaryObjectExpr(ASTContext &C,
Anders Carlsson26de5492009-04-24 05:23:13 +0000360 CXXConstructorDecl *Cons,
Douglas Gregor506ae412009-01-16 18:33:17 +0000361 QualType writtenTy,
362 SourceLocation tyBeginLoc,
363 Expr **Args,
364 unsigned NumArgs,
365 SourceLocation rParenLoc)
Anders Carlsson8e587a12009-05-30 20:56:46 +0000366 : CXXConstructExpr(C, CXXTemporaryObjectExprClass, writtenTy, Cons,
Anders Carlsson524fa132009-04-24 17:34:38 +0000367 false, Args, NumArgs),
368 TyBeginLoc(tyBeginLoc), RParenLoc(rParenLoc) {
Douglas Gregor506ae412009-01-16 18:33:17 +0000369}
Anders Carlsson19d28a62009-04-21 02:22:11 +0000370
Anders Carlsson8e587a12009-05-30 20:56:46 +0000371CXXConstructExpr *CXXConstructExpr::Create(ASTContext &C, QualType T,
372 CXXConstructorDecl *D, bool Elidable,
Anders Carlssone349bea2009-04-23 02:32:43 +0000373 Expr **Args, unsigned NumArgs) {
Anders Carlsson8e587a12009-05-30 20:56:46 +0000374 return new (C) CXXConstructExpr(C, CXXConstructExprClass, T, D, Elidable,
Anders Carlssonbd6734e2009-04-24 05:04:04 +0000375 Args, NumArgs);
Anders Carlssone349bea2009-04-23 02:32:43 +0000376}
377
Anders Carlsson8e587a12009-05-30 20:56:46 +0000378CXXConstructExpr::CXXConstructExpr(ASTContext &C, StmtClass SC, QualType T,
379 CXXConstructorDecl *D, bool elidable,
Anders Carlssone349bea2009-04-23 02:32:43 +0000380 Expr **args, unsigned numargs)
Anders Carlssonbd6734e2009-04-24 05:04:04 +0000381: Expr(SC, T,
Anders Carlssone349bea2009-04-23 02:32:43 +0000382 T->isDependentType(),
383 (T->isDependentType() ||
384 CallExpr::hasAnyValueDependentArguments(args, numargs))),
Anders Carlsson8e587a12009-05-30 20:56:46 +0000385 Constructor(D), Elidable(elidable), Args(0), NumArgs(numargs) {
Fariborz Jahanian2eeed7b2009-08-05 00:26:10 +0000386 // leave room for default arguments;
387 FunctionDecl *FDecl = cast<FunctionDecl>(D);
388 unsigned NumArgsInProto = FDecl->param_size();
389 NumArgs += (NumArgsInProto - numargs);
Anders Carlssone349bea2009-04-23 02:32:43 +0000390 if (NumArgs > 0) {
391 Args = new (C) Stmt*[NumArgs];
Fariborz Jahanian2eeed7b2009-08-05 00:26:10 +0000392 for (unsigned i = 0; i < numargs; ++i)
Anders Carlssone349bea2009-04-23 02:32:43 +0000393 Args[i] = args[i];
394 }
395}
396
Douglas Gregor42602bb2009-08-07 06:08:38 +0000397void CXXConstructExpr::DoDestroy(ASTContext &C) {
Anders Carlssone349bea2009-04-23 02:32:43 +0000398 DestroyChildren(C);
399 if (Args)
400 C.Deallocate(Args);
401 this->~CXXConstructExpr();
402 C.Deallocate(this);
403}
404
Anders Carlsson2d44e8a2009-05-01 22:18:43 +0000405CXXExprWithTemporaries::CXXExprWithTemporaries(Expr *subexpr,
Anders Carlssonff6b3d62009-05-30 21:05:25 +0000406 CXXTemporary **temps,
Anders Carlsson99ba36d2009-06-05 15:38:08 +0000407 unsigned numtemps,
Anders Carlssonf54741e2009-06-16 03:37:31 +0000408 bool shoulddestroytemps)
Anders Carlsson2d44e8a2009-05-01 22:18:43 +0000409: Expr(CXXExprWithTemporariesClass, subexpr->getType(),
Anders Carlsson02bbfa32009-04-24 22:47:04 +0000410 subexpr->isTypeDependent(), subexpr->isValueDependent()),
Anders Carlssonf54741e2009-06-16 03:37:31 +0000411 SubExpr(subexpr), Temps(0), NumTemps(numtemps),
412 ShouldDestroyTemps(shoulddestroytemps) {
Anders Carlssonff6b3d62009-05-30 21:05:25 +0000413 if (NumTemps > 0) {
414 Temps = new CXXTemporary*[NumTemps];
415 for (unsigned i = 0; i < NumTemps; ++i)
416 Temps[i] = temps[i];
Anders Carlsson02bbfa32009-04-24 22:47:04 +0000417 }
418}
419
Anders Carlsson88eaf072009-05-30 22:38:53 +0000420CXXExprWithTemporaries *CXXExprWithTemporaries::Create(ASTContext &C,
421 Expr *SubExpr,
422 CXXTemporary **Temps,
Anders Carlsson99ba36d2009-06-05 15:38:08 +0000423 unsigned NumTemps,
Anders Carlssonf54741e2009-06-16 03:37:31 +0000424 bool ShouldDestroyTemps){
Anders Carlsson99ba36d2009-06-05 15:38:08 +0000425 return new (C) CXXExprWithTemporaries(SubExpr, Temps, NumTemps,
Anders Carlssonf54741e2009-06-16 03:37:31 +0000426 ShouldDestroyTemps);
Anders Carlsson88eaf072009-05-30 22:38:53 +0000427}
428
Douglas Gregor42602bb2009-08-07 06:08:38 +0000429void CXXExprWithTemporaries::DoDestroy(ASTContext &C) {
Anders Carlsson88eaf072009-05-30 22:38:53 +0000430 DestroyChildren(C);
431 this->~CXXExprWithTemporaries();
432 C.Deallocate(this);
433}
434
Anders Carlsson2d44e8a2009-05-01 22:18:43 +0000435CXXExprWithTemporaries::~CXXExprWithTemporaries() {
Anders Carlssonff6b3d62009-05-30 21:05:25 +0000436 delete[] Temps;
Anders Carlsson02bbfa32009-04-24 22:47:04 +0000437}
438
Anders Carlssonfceb0a82009-05-30 20:03:25 +0000439// CXXBindTemporaryExpr
440Stmt::child_iterator CXXBindTemporaryExpr::child_begin() {
441 return &SubExpr;
442}
443
444Stmt::child_iterator CXXBindTemporaryExpr::child_end() {
445 return &SubExpr + 1;
446}
447
Anders Carlssone349bea2009-04-23 02:32:43 +0000448// CXXConstructExpr
449Stmt::child_iterator CXXConstructExpr::child_begin() {
450 return &Args[0];
451}
452Stmt::child_iterator CXXConstructExpr::child_end() {
453 return &Args[0]+NumArgs;
454}
455
Anders Carlsson55674ac2009-05-01 22:21:22 +0000456// CXXExprWithTemporaries
457Stmt::child_iterator CXXExprWithTemporaries::child_begin() {
458 return &SubExpr;
Anders Carlsson19d28a62009-04-21 02:22:11 +0000459}
Anders Carlsson02bbfa32009-04-24 22:47:04 +0000460
Anders Carlsson55674ac2009-05-01 22:21:22 +0000461Stmt::child_iterator CXXExprWithTemporaries::child_end() {
462 return &SubExpr + 1;
463}
Anders Carlsson02bbfa32009-04-24 22:47:04 +0000464
Douglas Gregord81e6ca2009-05-20 18:46:25 +0000465CXXUnresolvedConstructExpr::CXXUnresolvedConstructExpr(
466 SourceLocation TyBeginLoc,
467 QualType T,
468 SourceLocation LParenLoc,
469 Expr **Args,
470 unsigned NumArgs,
471 SourceLocation RParenLoc)
472 : Expr(CXXUnresolvedConstructExprClass, T.getNonReferenceType(),
473 T->isDependentType(), true),
474 TyBeginLoc(TyBeginLoc),
475 Type(T),
476 LParenLoc(LParenLoc),
477 RParenLoc(RParenLoc),
478 NumArgs(NumArgs) {
479 Stmt **StoredArgs = reinterpret_cast<Stmt **>(this + 1);
480 memcpy(StoredArgs, Args, sizeof(Expr *) * NumArgs);
481}
482
483CXXUnresolvedConstructExpr *
484CXXUnresolvedConstructExpr::Create(ASTContext &C,
485 SourceLocation TyBegin,
486 QualType T,
487 SourceLocation LParenLoc,
488 Expr **Args,
489 unsigned NumArgs,
490 SourceLocation RParenLoc) {
491 void *Mem = C.Allocate(sizeof(CXXUnresolvedConstructExpr) +
492 sizeof(Expr *) * NumArgs);
493 return new (Mem) CXXUnresolvedConstructExpr(TyBegin, T, LParenLoc,
494 Args, NumArgs, RParenLoc);
495}
496
497Stmt::child_iterator CXXUnresolvedConstructExpr::child_begin() {
498 return child_iterator(reinterpret_cast<Stmt **>(this + 1));
499}
500
501Stmt::child_iterator CXXUnresolvedConstructExpr::child_end() {
502 return child_iterator(reinterpret_cast<Stmt **>(this + 1) + NumArgs);
503}
Sebastian Redl8b0b4752009-05-16 18:50:46 +0000504
Douglas Gregor1c0ca592009-05-22 21:13:27 +0000505Stmt::child_iterator CXXUnresolvedMemberExpr::child_begin() {
506 return child_iterator(&Base);
507}
508
509Stmt::child_iterator CXXUnresolvedMemberExpr::child_end() {
510 return child_iterator(&Base + 1);
511}