blob: 8591a4d8bd7f38248564e14f647c7e822b100abc [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"
18using namespace clang;
19
20//===----------------------------------------------------------------------===//
21// Child Iterators for iterating over subexpressions/substatements
22//===----------------------------------------------------------------------===//
23
Sebastian Redlc4704762008-11-11 11:37:55 +000024// CXXTypeidExpr - has child iterators if the operand is an expression
25Stmt::child_iterator CXXTypeidExpr::child_begin() {
Sebastian Redlba3fdfc2008-12-03 23:17:54 +000026 return isTypeOperand() ? child_iterator() : &Operand.Ex;
Sebastian Redlc4704762008-11-11 11:37:55 +000027}
28Stmt::child_iterator CXXTypeidExpr::child_end() {
Sebastian Redlba3fdfc2008-12-03 23:17:54 +000029 return isTypeOperand() ? child_iterator() : &Operand.Ex+1;
Sebastian Redlc4704762008-11-11 11:37:55 +000030}
Ted Kremeneke3a0c142007-08-24 20:21:10 +000031
Ted Kremeneke3a0c142007-08-24 20:21:10 +000032// CXXBoolLiteralExpr
Mike Stump11289f42009-09-09 15:08:12 +000033Stmt::child_iterator CXXBoolLiteralExpr::child_begin() {
Ted Kremenek04746ce2007-10-18 23:28:49 +000034 return child_iterator();
35}
36Stmt::child_iterator CXXBoolLiteralExpr::child_end() {
37 return child_iterator();
38}
Chris Lattnerb7e656b2008-02-26 00:51:44 +000039
Sebastian Redl576fd422009-05-10 18:38:11 +000040// CXXNullPtrLiteralExpr
Mike Stump11289f42009-09-09 15:08:12 +000041Stmt::child_iterator CXXNullPtrLiteralExpr::child_begin() {
Sebastian Redl576fd422009-05-10 18:38:11 +000042 return child_iterator();
43}
44Stmt::child_iterator CXXNullPtrLiteralExpr::child_end() {
45 return child_iterator();
46}
47
Douglas Gregor97a9c812008-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 Lattnerb7e656b2008-02-26 00:51:44 +000052// CXXThrowExpr
Ted Kremenekc6501db2008-06-17 03:11:08 +000053Stmt::child_iterator CXXThrowExpr::child_begin() { return &Op; }
Chris Lattnerb7e656b2008-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 Kremenekc6501db2008-06-17 03:11:08 +000056 return Op ? &Op+1 : &Op;
Chris Lattnerb7e656b2008-02-26 00:51:44 +000057}
Chris Lattneraa9c7ae2008-04-08 04:40:51 +000058
59// CXXDefaultArgExpr
60Stmt::child_iterator CXXDefaultArgExpr::child_begin() {
Chris Lattner58258242008-04-10 02:22:51 +000061 return child_iterator();
Chris Lattneraa9c7ae2008-04-08 04:40:51 +000062}
63Stmt::child_iterator CXXDefaultArgExpr::child_end() {
Chris Lattner58258242008-04-10 02:22:51 +000064 return child_iterator();
Chris Lattneraa9c7ae2008-04-08 04:40:51 +000065}
Argyrios Kyrtzidis857fcc22008-08-22 15:38:55 +000066
67// CXXZeroInitValueExpr
Mike Stump11289f42009-09-09 15:08:12 +000068Stmt::child_iterator CXXZeroInitValueExpr::child_begin() {
Argyrios Kyrtzidis857fcc22008-08-22 15:38:55 +000069 return child_iterator();
70}
71Stmt::child_iterator CXXZeroInitValueExpr::child_end() {
72 return child_iterator();
73}
Argyrios Kyrtzidisaa479132008-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 Gregore200adc2008-10-27 19:41:14 +000082
Sebastian Redlbd150f42008-11-21 19:14:01 +000083// CXXNewExpr
84CXXNewExpr::CXXNewExpr(bool globalNew, FunctionDecl *operatorNew,
85 Expr **placementArgs, unsigned numPlaceArgs,
Sebastian Redl351bb782008-12-02 14:43:59 +000086 bool parenTypeId, Expr *arraySize,
Sebastian Redlbd150f42008-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 Redl8d2ccae2009-02-26 14:39:58 +000091 : Expr(CXXNewExprClass, ty, ty->isDependentType(), ty->isDependentType()),
92 GlobalNew(globalNew), ParenTypeId(parenTypeId),
Sebastian Redl351bb782008-12-02 14:43:59 +000093 Initializer(initializer), Array(arraySize), NumPlacementArgs(numPlaceArgs),
Sebastian Redlbd150f42008-11-21 19:14:01 +000094 NumConstructorArgs(numConsArgs), OperatorNew(operatorNew),
Sebastian Redl351bb782008-12-02 14:43:59 +000095 OperatorDelete(operatorDelete), Constructor(constructor),
Mike Stump11289f42009-09-09 15:08:12 +000096 StartLoc(startLoc), EndLoc(endLoc) {
Sebastian Redl351bb782008-12-02 14:43:59 +000097 unsigned TotalSize = Array + NumPlacementArgs + NumConstructorArgs;
Sebastian Redlbd150f42008-11-21 19:14:01 +000098 SubExprs = new Stmt*[TotalSize];
99 unsigned i = 0;
Sebastian Redl351bb782008-12-02 14:43:59 +0000100 if (Array)
101 SubExprs[i++] = arraySize;
102 for (unsigned j = 0; j < NumPlacementArgs; ++j)
Sebastian Redlbd150f42008-11-21 19:14:01 +0000103 SubExprs[i++] = placementArgs[j];
Sebastian Redl351bb782008-12-02 14:43:59 +0000104 for (unsigned j = 0; j < NumConstructorArgs; ++j)
Sebastian Redlbd150f42008-11-21 19:14:01 +0000105 SubExprs[i++] = constructorArgs[j];
106 assert(i == TotalSize);
107}
108
109Stmt::child_iterator CXXNewExpr::child_begin() { return &SubExprs[0]; }
110Stmt::child_iterator CXXNewExpr::child_end() {
Sebastian Redl351bb782008-12-02 14:43:59 +0000111 return &SubExprs[0] + Array + getNumPlacementArgs() + getNumConstructorArgs();
Sebastian Redlbd150f42008-11-21 19:14:01 +0000112}
113
114// CXXDeleteExpr
115Stmt::child_iterator CXXDeleteExpr::child_begin() { return &Argument; }
116Stmt::child_iterator CXXDeleteExpr::child_end() { return &Argument+1; }
117
Douglas Gregorad8a3362009-09-04 17:36:40 +0000118// CXXPseudoDestructorExpr
119Stmt::child_iterator CXXPseudoDestructorExpr::child_begin() { return &Base; }
120Stmt::child_iterator CXXPseudoDestructorExpr::child_end() {
121 return &Base + 1;
122}
123
John McCalld14a8642009-11-21 08:51:07 +0000124// UnresolvedLookupExpr
John McCalle66edc12009-11-24 19:00:30 +0000125UnresolvedLookupExpr *
126UnresolvedLookupExpr::Create(ASTContext &C, bool Dependent,
127 NestedNameSpecifier *Qualifier,
128 SourceRange QualifierRange, DeclarationName Name,
129 SourceLocation NameLoc, bool ADL,
130 const TemplateArgumentListInfo &Args)
131{
132 void *Mem = C.Allocate(sizeof(UnresolvedLookupExpr) +
133 ExplicitTemplateArgumentList::sizeFor(Args));
134 UnresolvedLookupExpr *ULE
135 = new (Mem) UnresolvedLookupExpr(Dependent ? C.DependentTy : C.OverloadTy,
136 Dependent, Qualifier, QualifierRange,
137 Name, NameLoc, ADL,
138 /*Overload*/ true,
139 /*ExplicitTemplateArgs*/ true);
140
141 reinterpret_cast<ExplicitTemplateArgumentList*>(ULE+1)->initializeFrom(Args);
142
143 return ULE;
144}
145
146bool UnresolvedLookupExpr::ComputeDependence(NamedDecl * const *Begin,
147 NamedDecl * const *End,
148 const TemplateArgumentListInfo *Args) {
149 for (NamedDecl * const *I = Begin; I != End; ++I)
150 if ((*I)->getDeclContext()->isDependentContext())
151 return true;
152
153 if (Args && TemplateSpecializationType::anyDependentTemplateArguments(*Args))
154 return true;
155
156 return false;
157}
158
John McCalld14a8642009-11-21 08:51:07 +0000159Stmt::child_iterator UnresolvedLookupExpr::child_begin() {
Mike Stump11289f42009-09-09 15:08:12 +0000160 return child_iterator();
Douglas Gregorb0846b02008-12-06 00:22:45 +0000161}
John McCalld14a8642009-11-21 08:51:07 +0000162Stmt::child_iterator UnresolvedLookupExpr::child_end() {
Douglas Gregorb0846b02008-12-06 00:22:45 +0000163 return child_iterator();
164}
Sebastian Redlbaad4e72009-01-05 20:52:13 +0000165// UnaryTypeTraitExpr
166Stmt::child_iterator UnaryTypeTraitExpr::child_begin() {
167 return child_iterator();
168}
169Stmt::child_iterator UnaryTypeTraitExpr::child_end() {
170 return child_iterator();
171}
172
John McCall8cd78132009-11-19 22:55:06 +0000173// DependentScopeDeclRefExpr
John McCalle66edc12009-11-24 19:00:30 +0000174DependentScopeDeclRefExpr *
175DependentScopeDeclRefExpr::Create(ASTContext &C,
176 NestedNameSpecifier *Qualifier,
177 SourceRange QualifierRange,
178 DeclarationName Name,
179 SourceLocation NameLoc,
180 const TemplateArgumentListInfo *Args) {
181 std::size_t size = sizeof(DependentScopeDeclRefExpr);
182 if (Args) size += ExplicitTemplateArgumentList::sizeFor(*Args);
183 void *Mem = C.Allocate(size);
184
185 DependentScopeDeclRefExpr *DRE
186 = new (Mem) DependentScopeDeclRefExpr(C.DependentTy,
187 Qualifier, QualifierRange,
188 Name, NameLoc,
189 Args != 0);
190
191 if (Args)
192 reinterpret_cast<ExplicitTemplateArgumentList*>(DRE+1)
193 ->initializeFrom(*Args);
194
195 return DRE;
196}
197
John McCall8cd78132009-11-19 22:55:06 +0000198StmtIterator DependentScopeDeclRefExpr::child_begin() {
Douglas Gregor90a1a652009-03-19 17:26:29 +0000199 return child_iterator();
200}
201
John McCall8cd78132009-11-19 22:55:06 +0000202StmtIterator DependentScopeDeclRefExpr::child_end() {
Douglas Gregor90a1a652009-03-19 17:26:29 +0000203 return child_iterator();
204}
205
Douglas Gregor79f83ed2009-07-23 23:49:00 +0000206bool UnaryTypeTraitExpr::EvaluateTrait(ASTContext& C) const {
Sebastian Redlbaad4e72009-01-05 20:52:13 +0000207 switch(UTT) {
208 default: assert(false && "Unknown type trait or not implemented");
209 case UTT_IsPOD: return QueriedType->isPODType();
210 case UTT_IsClass: // Fallthrough
211 case UTT_IsUnion:
Ted Kremenekc23c7e62009-07-29 21:53:49 +0000212 if (const RecordType *Record = QueriedType->getAs<RecordType>()) {
Sebastian Redlbaad4e72009-01-05 20:52:13 +0000213 bool Union = Record->getDecl()->isUnion();
214 return UTT == UTT_IsUnion ? Union : !Union;
215 }
216 return false;
217 case UTT_IsEnum: return QueriedType->isEnumeralType();
218 case UTT_IsPolymorphic:
Ted Kremenekc23c7e62009-07-29 21:53:49 +0000219 if (const RecordType *Record = QueriedType->getAs<RecordType>()) {
Sebastian Redlbaad4e72009-01-05 20:52:13 +0000220 // Type traits are only parsed in C++, so we've got CXXRecords.
221 return cast<CXXRecordDecl>(Record->getDecl())->isPolymorphic();
222 }
223 return false;
Anders Carlsson7cbd8fb2009-03-22 01:52:17 +0000224 case UTT_IsAbstract:
Ted Kremenekc23c7e62009-07-29 21:53:49 +0000225 if (const RecordType *RT = QueriedType->getAs<RecordType>())
Anders Carlsson7cbd8fb2009-03-22 01:52:17 +0000226 return cast<CXXRecordDecl>(RT->getDecl())->isAbstract();
227 return false;
Eli Friedmanc96d4962009-08-15 21:55:26 +0000228 case UTT_IsEmpty:
229 if (const RecordType *Record = QueriedType->getAs<RecordType>()) {
230 return !Record->getDecl()->isUnion()
231 && cast<CXXRecordDecl>(Record->getDecl())->isEmpty();
232 }
233 return false;
Anders Carlssonfe63dc52009-04-16 00:08:20 +0000234 case UTT_HasTrivialConstructor:
Douglas Gregor79f83ed2009-07-23 23:49:00 +0000235 // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
236 // If __is_pod (type) is true then the trait is true, else if type is
237 // a cv class or union type (or array thereof) with a trivial default
238 // constructor ([class.ctor]) then the trait is true, else it is false.
239 if (QueriedType->isPODType())
240 return true;
241 if (const RecordType *RT =
Ted Kremenekc23c7e62009-07-29 21:53:49 +0000242 C.getBaseElementType(QueriedType)->getAs<RecordType>())
Anders Carlssonfe63dc52009-04-16 00:08:20 +0000243 return cast<CXXRecordDecl>(RT->getDecl())->hasTrivialConstructor();
Anders Carlsson6dc35752009-04-17 02:34:54 +0000244 return false;
Douglas Gregor79f83ed2009-07-23 23:49:00 +0000245 case UTT_HasTrivialCopy:
246 // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
247 // If __is_pod (type) is true or type is a reference type then
248 // the trait is true, else if type is a cv class or union type
249 // with a trivial copy constructor ([class.copy]) then the trait
250 // is true, else it is false.
251 if (QueriedType->isPODType() || QueriedType->isReferenceType())
252 return true;
Ted Kremenekc23c7e62009-07-29 21:53:49 +0000253 if (const RecordType *RT = QueriedType->getAs<RecordType>())
Douglas Gregor79f83ed2009-07-23 23:49:00 +0000254 return cast<CXXRecordDecl>(RT->getDecl())->hasTrivialCopyConstructor();
255 return false;
256 case UTT_HasTrivialAssign:
257 // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
258 // If type is const qualified or is a reference type then the
259 // trait is false. Otherwise if __is_pod (type) is true then the
260 // trait is true, else if type is a cv class or union type with
261 // a trivial copy assignment ([class.copy]) then the trait is
262 // true, else it is false.
263 // Note: the const and reference restrictions are interesting,
264 // given that const and reference members don't prevent a class
265 // from having a trivial copy assignment operator (but do cause
266 // errors if the copy assignment operator is actually used, q.v.
267 // [class.copy]p12).
268
269 if (C.getBaseElementType(QueriedType).isConstQualified())
270 return false;
271 if (QueriedType->isPODType())
272 return true;
Ted Kremenekc23c7e62009-07-29 21:53:49 +0000273 if (const RecordType *RT = QueriedType->getAs<RecordType>())
Douglas Gregor79f83ed2009-07-23 23:49:00 +0000274 return cast<CXXRecordDecl>(RT->getDecl())->hasTrivialCopyAssignment();
275 return false;
276 case UTT_HasTrivialDestructor:
277 // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
278 // If __is_pod (type) is true or type is a reference type
279 // then the trait is true, else if type is a cv class or union
280 // type (or array thereof) with a trivial destructor
281 // ([class.dtor]) then the trait is true, else it is
282 // false.
283 if (QueriedType->isPODType() || QueriedType->isReferenceType())
284 return true;
285 if (const RecordType *RT =
Ted Kremenekc23c7e62009-07-29 21:53:49 +0000286 C.getBaseElementType(QueriedType)->getAs<RecordType>())
Anders Carlsson6dc35752009-04-17 02:34:54 +0000287 return cast<CXXRecordDecl>(RT->getDecl())->hasTrivialDestructor();
288 return false;
Sebastian Redlbaad4e72009-01-05 20:52:13 +0000289 }
290}
291
Douglas Gregor993603d2008-11-14 16:09:21 +0000292SourceRange CXXOperatorCallExpr::getSourceRange() const {
293 OverloadedOperatorKind Kind = getOperator();
294 if (Kind == OO_PlusPlus || Kind == OO_MinusMinus) {
295 if (getNumArgs() == 1)
296 // Prefix operator
Mike Stump11289f42009-09-09 15:08:12 +0000297 return SourceRange(getOperatorLoc(),
Douglas Gregor993603d2008-11-14 16:09:21 +0000298 getArg(0)->getSourceRange().getEnd());
299 else
300 // Postfix operator
301 return SourceRange(getArg(0)->getSourceRange().getEnd(),
302 getOperatorLoc());
303 } else if (Kind == OO_Call) {
304 return SourceRange(getArg(0)->getSourceRange().getBegin(), getRParenLoc());
305 } else if (Kind == OO_Subscript) {
306 return SourceRange(getArg(0)->getSourceRange().getBegin(), getRParenLoc());
307 } else if (getNumArgs() == 1) {
308 return SourceRange(getOperatorLoc(), getArg(0)->getSourceRange().getEnd());
309 } else if (getNumArgs() == 2) {
310 return SourceRange(getArg(0)->getSourceRange().getBegin(),
311 getArg(1)->getSourceRange().getEnd());
312 } else {
313 return SourceRange();
314 }
315}
316
Douglas Gregor97fd6e22008-12-22 05:46:06 +0000317Expr *CXXMemberCallExpr::getImplicitObjectArgument() {
318 if (MemberExpr *MemExpr = dyn_cast<MemberExpr>(getCallee()->IgnoreParens()))
319 return MemExpr->getBase();
320
321 // FIXME: Will eventually need to cope with member pointers.
322 return 0;
323}
324
Douglas Gregoref986e82009-11-12 15:31:47 +0000325SourceRange CXXMemberCallExpr::getSourceRange() const {
326 SourceLocation LocStart = getCallee()->getLocStart();
327 if (LocStart.isInvalid() && getNumArgs() > 0)
328 LocStart = getArg(0)->getLocStart();
329 return SourceRange(LocStart, getRParenLoc());
330}
331
332
Douglas Gregore200adc2008-10-27 19:41:14 +0000333//===----------------------------------------------------------------------===//
334// Named casts
335//===----------------------------------------------------------------------===//
336
337/// getCastName - Get the name of the C++ cast being used, e.g.,
338/// "static_cast", "dynamic_cast", "reinterpret_cast", or
339/// "const_cast". The returned pointer must not be freed.
340const char *CXXNamedCastExpr::getCastName() const {
341 switch (getStmtClass()) {
342 case CXXStaticCastExprClass: return "static_cast";
343 case CXXDynamicCastExprClass: return "dynamic_cast";
344 case CXXReinterpretCastExprClass: return "reinterpret_cast";
345 case CXXConstCastExprClass: return "const_cast";
346 default: return "<invalid cast>";
347 }
348}
Douglas Gregordd04d332009-01-16 18:33:17 +0000349
Mike Stump11289f42009-09-09 15:08:12 +0000350CXXTemporary *CXXTemporary::Create(ASTContext &C,
Anders Carlssonffda6062009-05-30 20:34:37 +0000351 const CXXDestructorDecl *Destructor) {
Anders Carlsson73b836b2009-05-30 22:38:53 +0000352 return new (C) CXXTemporary(Destructor);
353}
354
Douglas Gregore26a2852009-08-07 06:08:38 +0000355void CXXTemporary::Destroy(ASTContext &Ctx) {
Anders Carlsson73b836b2009-05-30 22:38:53 +0000356 this->~CXXTemporary();
Douglas Gregore26a2852009-08-07 06:08:38 +0000357 Ctx.Deallocate(this);
Anders Carlssonf337d8c2009-05-30 19:54:15 +0000358}
359
Mike Stump11289f42009-09-09 15:08:12 +0000360CXXBindTemporaryExpr *CXXBindTemporaryExpr::Create(ASTContext &C,
Anders Carlsson993a4b32009-05-30 20:03:25 +0000361 CXXTemporary *Temp,
362 Expr* SubExpr) {
Mike Stump11289f42009-09-09 15:08:12 +0000363 assert(SubExpr->getType()->isRecordType() &&
Anders Carlsson993a4b32009-05-30 20:03:25 +0000364 "Expression bound to a temporary must have record type!");
365
Anders Carlssonffda6062009-05-30 20:34:37 +0000366 return new (C) CXXBindTemporaryExpr(Temp, SubExpr);
Anders Carlsson993a4b32009-05-30 20:03:25 +0000367}
368
Douglas Gregore26a2852009-08-07 06:08:38 +0000369void CXXBindTemporaryExpr::DoDestroy(ASTContext &C) {
Anders Carlsson73b836b2009-05-30 22:38:53 +0000370 Temp->Destroy(C);
371 this->~CXXBindTemporaryExpr();
372 C.Deallocate(this);
373}
374
Anders Carlsson4b2434d2009-05-30 20:56:46 +0000375CXXTemporaryObjectExpr::CXXTemporaryObjectExpr(ASTContext &C,
Anders Carlsson56c5bd82009-04-24 05:23:13 +0000376 CXXConstructorDecl *Cons,
Douglas Gregordd04d332009-01-16 18:33:17 +0000377 QualType writtenTy,
Mike Stump11289f42009-09-09 15:08:12 +0000378 SourceLocation tyBeginLoc,
Douglas Gregordd04d332009-01-16 18:33:17 +0000379 Expr **Args,
Mike Stump11289f42009-09-09 15:08:12 +0000380 unsigned NumArgs,
Douglas Gregordd04d332009-01-16 18:33:17 +0000381 SourceLocation rParenLoc)
Mike Stump11289f42009-09-09 15:08:12 +0000382 : CXXConstructExpr(C, CXXTemporaryObjectExprClass, writtenTy, Cons,
383 false, Args, NumArgs),
Anders Carlsson95c56eb2009-04-24 17:34:38 +0000384 TyBeginLoc(tyBeginLoc), RParenLoc(rParenLoc) {
Douglas Gregordd04d332009-01-16 18:33:17 +0000385}
Anders Carlsson6f287832009-04-21 02:22:11 +0000386
Mike Stump11289f42009-09-09 15:08:12 +0000387CXXConstructExpr *CXXConstructExpr::Create(ASTContext &C, QualType T,
Anders Carlsson4b2434d2009-05-30 20:56:46 +0000388 CXXConstructorDecl *D, bool Elidable,
Anders Carlsson0781ce72009-04-23 02:32:43 +0000389 Expr **Args, unsigned NumArgs) {
Mike Stump11289f42009-09-09 15:08:12 +0000390 return new (C) CXXConstructExpr(C, CXXConstructExprClass, T, D, Elidable,
Anders Carlsson32ebd292009-04-24 05:04:04 +0000391 Args, NumArgs);
Anders Carlsson0781ce72009-04-23 02:32:43 +0000392}
393
Mike Stump11289f42009-09-09 15:08:12 +0000394CXXConstructExpr::CXXConstructExpr(ASTContext &C, StmtClass SC, QualType T,
Anders Carlsson4b2434d2009-05-30 20:56:46 +0000395 CXXConstructorDecl *D, bool elidable,
Mike Stump11289f42009-09-09 15:08:12 +0000396 Expr **args, unsigned numargs)
Anders Carlsson32ebd292009-04-24 05:04:04 +0000397: Expr(SC, T,
Anders Carlsson0781ce72009-04-23 02:32:43 +0000398 T->isDependentType(),
399 (T->isDependentType() ||
400 CallExpr::hasAnyValueDependentArguments(args, numargs))),
Anders Carlsson4b2434d2009-05-30 20:56:46 +0000401 Constructor(D), Elidable(elidable), Args(0), NumArgs(numargs) {
Douglas Gregor5d3507d2009-09-09 23:08:42 +0000402 if (NumArgs) {
403 Args = new (C) Stmt*[NumArgs];
Mike Stump11289f42009-09-09 15:08:12 +0000404
Douglas Gregor5d3507d2009-09-09 23:08:42 +0000405 for (unsigned i = 0; i != NumArgs; ++i) {
406 assert(args[i] && "NULL argument in CXXConstructExpr");
Anders Carlsson0781ce72009-04-23 02:32:43 +0000407 Args[i] = args[i];
Douglas Gregor5d3507d2009-09-09 23:08:42 +0000408 }
Anders Carlsson0781ce72009-04-23 02:32:43 +0000409 }
410}
411
Douglas Gregor5d3507d2009-09-09 23:08:42 +0000412CXXConstructExpr::CXXConstructExpr(EmptyShell Empty, ASTContext &C,
413 unsigned numargs)
414 : Expr(CXXConstructExprClass, Empty), Args(0), NumArgs(numargs)
415{
416 if (NumArgs)
417 Args = new (C) Stmt*[NumArgs];
418}
419
Douglas Gregore26a2852009-08-07 06:08:38 +0000420void CXXConstructExpr::DoDestroy(ASTContext &C) {
Anders Carlsson0781ce72009-04-23 02:32:43 +0000421 DestroyChildren(C);
422 if (Args)
423 C.Deallocate(Args);
424 this->~CXXConstructExpr();
425 C.Deallocate(this);
426}
427
Mike Stump11289f42009-09-09 15:08:12 +0000428CXXExprWithTemporaries::CXXExprWithTemporaries(Expr *subexpr,
429 CXXTemporary **temps,
Anders Carlssonb3d05d62009-06-05 15:38:08 +0000430 unsigned numtemps,
Anders Carlssona42ab8f2009-06-16 03:37:31 +0000431 bool shoulddestroytemps)
Anders Carlssonf58c2432009-05-01 22:18:43 +0000432: Expr(CXXExprWithTemporariesClass, subexpr->getType(),
Mike Stump11289f42009-09-09 15:08:12 +0000433 subexpr->isTypeDependent(), subexpr->isValueDependent()),
434 SubExpr(subexpr), Temps(0), NumTemps(numtemps),
Anders Carlssona42ab8f2009-06-16 03:37:31 +0000435 ShouldDestroyTemps(shoulddestroytemps) {
Anders Carlssona29ded92009-05-30 21:05:25 +0000436 if (NumTemps > 0) {
437 Temps = new CXXTemporary*[NumTemps];
438 for (unsigned i = 0; i < NumTemps; ++i)
439 Temps[i] = temps[i];
Anders Carlssondefc6442009-04-24 22:47:04 +0000440 }
441}
442
Mike Stump11289f42009-09-09 15:08:12 +0000443CXXExprWithTemporaries *CXXExprWithTemporaries::Create(ASTContext &C,
Anders Carlsson73b836b2009-05-30 22:38:53 +0000444 Expr *SubExpr,
Mike Stump11289f42009-09-09 15:08:12 +0000445 CXXTemporary **Temps,
Anders Carlssonb3d05d62009-06-05 15:38:08 +0000446 unsigned NumTemps,
Anders Carlssona42ab8f2009-06-16 03:37:31 +0000447 bool ShouldDestroyTemps){
Mike Stump11289f42009-09-09 15:08:12 +0000448 return new (C) CXXExprWithTemporaries(SubExpr, Temps, NumTemps,
Anders Carlssona42ab8f2009-06-16 03:37:31 +0000449 ShouldDestroyTemps);
Anders Carlsson73b836b2009-05-30 22:38:53 +0000450}
451
Douglas Gregore26a2852009-08-07 06:08:38 +0000452void CXXExprWithTemporaries::DoDestroy(ASTContext &C) {
Anders Carlsson73b836b2009-05-30 22:38:53 +0000453 DestroyChildren(C);
454 this->~CXXExprWithTemporaries();
455 C.Deallocate(this);
456}
457
Anders Carlssonf58c2432009-05-01 22:18:43 +0000458CXXExprWithTemporaries::~CXXExprWithTemporaries() {
Anders Carlssona29ded92009-05-30 21:05:25 +0000459 delete[] Temps;
Anders Carlssondefc6442009-04-24 22:47:04 +0000460}
461
Anders Carlsson993a4b32009-05-30 20:03:25 +0000462// CXXBindTemporaryExpr
463Stmt::child_iterator CXXBindTemporaryExpr::child_begin() {
464 return &SubExpr;
465}
466
Mike Stump11289f42009-09-09 15:08:12 +0000467Stmt::child_iterator CXXBindTemporaryExpr::child_end() {
Anders Carlsson993a4b32009-05-30 20:03:25 +0000468 return &SubExpr + 1;
469}
470
Anders Carlsson0781ce72009-04-23 02:32:43 +0000471// CXXConstructExpr
472Stmt::child_iterator CXXConstructExpr::child_begin() {
473 return &Args[0];
474}
475Stmt::child_iterator CXXConstructExpr::child_end() {
476 return &Args[0]+NumArgs;
477}
478
Anders Carlssonaa10d652009-05-01 22:21:22 +0000479// CXXExprWithTemporaries
480Stmt::child_iterator CXXExprWithTemporaries::child_begin() {
481 return &SubExpr;
Anders Carlsson6f287832009-04-21 02:22:11 +0000482}
Anders Carlssondefc6442009-04-24 22:47:04 +0000483
Mike Stump11289f42009-09-09 15:08:12 +0000484Stmt::child_iterator CXXExprWithTemporaries::child_end() {
Anders Carlssonaa10d652009-05-01 22:21:22 +0000485 return &SubExpr + 1;
486}
Anders Carlssondefc6442009-04-24 22:47:04 +0000487
Douglas Gregorce934142009-05-20 18:46:25 +0000488CXXUnresolvedConstructExpr::CXXUnresolvedConstructExpr(
489 SourceLocation TyBeginLoc,
490 QualType T,
491 SourceLocation LParenLoc,
492 Expr **Args,
493 unsigned NumArgs,
494 SourceLocation RParenLoc)
495 : Expr(CXXUnresolvedConstructExprClass, T.getNonReferenceType(),
496 T->isDependentType(), true),
497 TyBeginLoc(TyBeginLoc),
498 Type(T),
499 LParenLoc(LParenLoc),
500 RParenLoc(RParenLoc),
501 NumArgs(NumArgs) {
502 Stmt **StoredArgs = reinterpret_cast<Stmt **>(this + 1);
503 memcpy(StoredArgs, Args, sizeof(Expr *) * NumArgs);
504}
505
506CXXUnresolvedConstructExpr *
Mike Stump11289f42009-09-09 15:08:12 +0000507CXXUnresolvedConstructExpr::Create(ASTContext &C,
Douglas Gregorce934142009-05-20 18:46:25 +0000508 SourceLocation TyBegin,
509 QualType T,
510 SourceLocation LParenLoc,
511 Expr **Args,
512 unsigned NumArgs,
513 SourceLocation RParenLoc) {
514 void *Mem = C.Allocate(sizeof(CXXUnresolvedConstructExpr) +
515 sizeof(Expr *) * NumArgs);
516 return new (Mem) CXXUnresolvedConstructExpr(TyBegin, T, LParenLoc,
517 Args, NumArgs, RParenLoc);
518}
519
520Stmt::child_iterator CXXUnresolvedConstructExpr::child_begin() {
521 return child_iterator(reinterpret_cast<Stmt **>(this + 1));
522}
523
524Stmt::child_iterator CXXUnresolvedConstructExpr::child_end() {
525 return child_iterator(reinterpret_cast<Stmt **>(this + 1) + NumArgs);
526}
Sebastian Redle769ecf2009-05-16 18:50:46 +0000527
John McCall8cd78132009-11-19 22:55:06 +0000528CXXDependentScopeMemberExpr::CXXDependentScopeMemberExpr(ASTContext &C,
Mike Stump11289f42009-09-09 15:08:12 +0000529 Expr *Base, bool IsArrow,
Douglas Gregor308047d2009-09-09 00:23:06 +0000530 SourceLocation OperatorLoc,
531 NestedNameSpecifier *Qualifier,
532 SourceRange QualifierRange,
533 NamedDecl *FirstQualifierFoundInScope,
534 DeclarationName Member,
535 SourceLocation MemberLoc,
John McCall6b51f282009-11-23 01:53:49 +0000536 const TemplateArgumentListInfo *TemplateArgs)
John McCall8cd78132009-11-19 22:55:06 +0000537 : Expr(CXXDependentScopeMemberExprClass, C.DependentTy, true, true),
Mike Stump11289f42009-09-09 15:08:12 +0000538 Base(Base), IsArrow(IsArrow),
John McCall6b51f282009-11-23 01:53:49 +0000539 HasExplicitTemplateArgumentList(TemplateArgs),
Douglas Gregor308047d2009-09-09 00:23:06 +0000540 OperatorLoc(OperatorLoc),
541 Qualifier(Qualifier), QualifierRange(QualifierRange),
542 FirstQualifierFoundInScope(FirstQualifierFoundInScope),
Mike Stump11289f42009-09-09 15:08:12 +0000543 Member(Member), MemberLoc(MemberLoc) {
John McCall6b51f282009-11-23 01:53:49 +0000544 if (TemplateArgs)
545 getExplicitTemplateArgumentList()->initializeFrom(*TemplateArgs);
Douglas Gregor308047d2009-09-09 00:23:06 +0000546}
547
John McCall8cd78132009-11-19 22:55:06 +0000548CXXDependentScopeMemberExpr *
549CXXDependentScopeMemberExpr::Create(ASTContext &C,
Mike Stump11289f42009-09-09 15:08:12 +0000550 Expr *Base, bool IsArrow,
Douglas Gregor308047d2009-09-09 00:23:06 +0000551 SourceLocation OperatorLoc,
552 NestedNameSpecifier *Qualifier,
553 SourceRange QualifierRange,
554 NamedDecl *FirstQualifierFoundInScope,
555 DeclarationName Member,
556 SourceLocation MemberLoc,
John McCall6b51f282009-11-23 01:53:49 +0000557 const TemplateArgumentListInfo *TemplateArgs) {
558 if (!TemplateArgs)
John McCall8cd78132009-11-19 22:55:06 +0000559 return new (C) CXXDependentScopeMemberExpr(C, Base, IsArrow, OperatorLoc,
Douglas Gregor308047d2009-09-09 00:23:06 +0000560 Qualifier, QualifierRange,
561 FirstQualifierFoundInScope,
562 Member, MemberLoc);
Mike Stump11289f42009-09-09 15:08:12 +0000563
John McCall6b51f282009-11-23 01:53:49 +0000564 std::size_t size = sizeof(CXXDependentScopeMemberExpr);
565 if (TemplateArgs)
566 size += ExplicitTemplateArgumentList::sizeFor(*TemplateArgs);
567
568 void *Mem = C.Allocate(size, llvm::alignof<CXXDependentScopeMemberExpr>());
John McCall8cd78132009-11-19 22:55:06 +0000569 return new (Mem) CXXDependentScopeMemberExpr(C, Base, IsArrow, OperatorLoc,
Douglas Gregor308047d2009-09-09 00:23:06 +0000570 Qualifier, QualifierRange,
571 FirstQualifierFoundInScope,
572 Member,
573 MemberLoc,
John McCall6b51f282009-11-23 01:53:49 +0000574 TemplateArgs);
Douglas Gregor308047d2009-09-09 00:23:06 +0000575}
576
John McCall8cd78132009-11-19 22:55:06 +0000577Stmt::child_iterator CXXDependentScopeMemberExpr::child_begin() {
Douglas Gregora8db9542009-05-22 21:13:27 +0000578 return child_iterator(&Base);
579}
580
John McCall8cd78132009-11-19 22:55:06 +0000581Stmt::child_iterator CXXDependentScopeMemberExpr::child_end() {
Douglas Gregora8db9542009-05-22 21:13:27 +0000582 return child_iterator(&Base + 1);
583}