blob: 11b223646b43a5d59535b3c6b01fc51c30579fa4 [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
Douglas Gregored8abf12010-07-08 06:14:04 +000077// CXXScalarValueInitExpr
78Stmt::child_iterator CXXScalarValueInitExpr::child_begin() {
Argyrios Kyrtzidis987a14b2008-08-22 15:38:55 +000079 return child_iterator();
80}
Douglas Gregored8abf12010-07-08 06:14:04 +000081Stmt::child_iterator CXXScalarValueInitExpr::child_end() {
Argyrios Kyrtzidis987a14b2008-08-22 15:38:55 +000082 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,
Douglas Gregor4bd40312010-07-13 15:54:32 +000088 SourceRange TypeIdParens, Expr *arraySize,
Sebastian Redl4c5d3202008-11-21 19:14:01 +000089 CXXConstructorDecl *constructor, bool initializer,
90 Expr **constructorArgs, unsigned numConsArgs,
91 FunctionDecl *operatorDelete, QualType ty,
Douglas Gregor1bb2a932010-09-07 21:49:58 +000092 TypeSourceInfo *AllocatedTypeInfo,
Sebastian Redl4c5d3202008-11-21 19:14:01 +000093 SourceLocation startLoc, SourceLocation endLoc)
Sebastian Redl28507842009-02-26 14:39:58 +000094 : Expr(CXXNewExprClass, ty, ty->isDependentType(), ty->isDependentType()),
Douglas Gregor4bd40312010-07-13 15:54:32 +000095 GlobalNew(globalNew),
Chris Lattner59218632010-05-10 01:22:27 +000096 Initializer(initializer), SubExprs(0), OperatorNew(operatorNew),
Sebastian Redlcee63fb2008-12-02 14:43:59 +000097 OperatorDelete(operatorDelete), Constructor(constructor),
Douglas Gregor1bb2a932010-09-07 21:49:58 +000098 AllocatedTypeInfo(AllocatedTypeInfo), TypeIdParens(TypeIdParens),
99 StartLoc(startLoc), EndLoc(endLoc) {
Chris Lattner59218632010-05-10 01:22:27 +0000100
101 AllocateArgsArray(C, arraySize != 0, numPlaceArgs, numConsArgs);
Sebastian Redl4c5d3202008-11-21 19:14:01 +0000102 unsigned i = 0;
Sebastian Redlcee63fb2008-12-02 14:43:59 +0000103 if (Array)
104 SubExprs[i++] = arraySize;
105 for (unsigned j = 0; j < NumPlacementArgs; ++j)
Sebastian Redl4c5d3202008-11-21 19:14:01 +0000106 SubExprs[i++] = placementArgs[j];
Sebastian Redlcee63fb2008-12-02 14:43:59 +0000107 for (unsigned j = 0; j < NumConstructorArgs; ++j)
Sebastian Redl4c5d3202008-11-21 19:14:01 +0000108 SubExprs[i++] = constructorArgs[j];
Sebastian Redl4c5d3202008-11-21 19:14:01 +0000109}
110
Chris Lattner59218632010-05-10 01:22:27 +0000111void CXXNewExpr::AllocateArgsArray(ASTContext &C, bool isArray,
112 unsigned numPlaceArgs, unsigned numConsArgs){
113 assert(SubExprs == 0 && "SubExprs already allocated");
114 Array = isArray;
115 NumPlacementArgs = numPlaceArgs;
116 NumConstructorArgs = numConsArgs;
117
118 unsigned TotalSize = Array + NumPlacementArgs + NumConstructorArgs;
119 SubExprs = new (C) Stmt*[TotalSize];
120}
121
122
Sebastian Redl4c5d3202008-11-21 19:14:01 +0000123Stmt::child_iterator CXXNewExpr::child_begin() { return &SubExprs[0]; }
124Stmt::child_iterator CXXNewExpr::child_end() {
Sebastian Redlcee63fb2008-12-02 14:43:59 +0000125 return &SubExprs[0] + Array + getNumPlacementArgs() + getNumConstructorArgs();
Sebastian Redl4c5d3202008-11-21 19:14:01 +0000126}
127
128// CXXDeleteExpr
129Stmt::child_iterator CXXDeleteExpr::child_begin() { return &Argument; }
130Stmt::child_iterator CXXDeleteExpr::child_end() { return &Argument+1; }
131
Douglas Gregora71d8192009-09-04 17:36:40 +0000132// CXXPseudoDestructorExpr
133Stmt::child_iterator CXXPseudoDestructorExpr::child_begin() { return &Base; }
134Stmt::child_iterator CXXPseudoDestructorExpr::child_end() {
135 return &Base + 1;
136}
137
Douglas Gregora2e7dd22010-02-25 01:56:36 +0000138PseudoDestructorTypeStorage::PseudoDestructorTypeStorage(TypeSourceInfo *Info)
139 : Type(Info)
140{
Abramo Bagnarabd054db2010-05-20 10:00:11 +0000141 Location = Info->getTypeLoc().getLocalSourceRange().getBegin();
Douglas Gregora2e7dd22010-02-25 01:56:36 +0000142}
143
144QualType CXXPseudoDestructorExpr::getDestroyedType() const {
145 if (TypeSourceInfo *TInfo = DestroyedType.getTypeSourceInfo())
146 return TInfo->getType();
147
148 return QualType();
149}
150
Douglas Gregor26d4ac92010-02-24 23:40:28 +0000151SourceRange CXXPseudoDestructorExpr::getSourceRange() const {
Douglas Gregora2e7dd22010-02-25 01:56:36 +0000152 SourceLocation End = DestroyedType.getLocation();
153 if (TypeSourceInfo *TInfo = DestroyedType.getTypeSourceInfo())
Abramo Bagnarabd054db2010-05-20 10:00:11 +0000154 End = TInfo->getTypeLoc().getLocalSourceRange().getEnd();
Douglas Gregora2e7dd22010-02-25 01:56:36 +0000155 return SourceRange(Base->getLocStart(), End);
Douglas Gregor26d4ac92010-02-24 23:40:28 +0000156}
157
158
John McCallba135432009-11-21 08:51:07 +0000159// UnresolvedLookupExpr
John McCallf7a1a742009-11-24 19:00:30 +0000160UnresolvedLookupExpr *
161UnresolvedLookupExpr::Create(ASTContext &C, bool Dependent,
John McCallc373d482010-01-27 01:50:18 +0000162 CXXRecordDecl *NamingClass,
John McCallf7a1a742009-11-24 19:00:30 +0000163 NestedNameSpecifier *Qualifier,
Abramo Bagnara25777432010-08-11 22:01:17 +0000164 SourceRange QualifierRange,
165 const DeclarationNameInfo &NameInfo,
166 bool ADL,
Douglas Gregor5a84dec2010-05-23 18:57:34 +0000167 const TemplateArgumentListInfo &Args,
168 UnresolvedSetIterator Begin,
169 UnresolvedSetIterator End)
John McCallf7a1a742009-11-24 19:00:30 +0000170{
171 void *Mem = C.Allocate(sizeof(UnresolvedLookupExpr) +
172 ExplicitTemplateArgumentList::sizeFor(Args));
173 UnresolvedLookupExpr *ULE
Douglas Gregor928e6fc2010-05-23 19:36:40 +0000174 = new (Mem) UnresolvedLookupExpr(C,
175 Dependent ? C.DependentTy : C.OverloadTy,
John McCallc373d482010-01-27 01:50:18 +0000176 Dependent, NamingClass,
Abramo Bagnara25777432010-08-11 22:01:17 +0000177 Qualifier, QualifierRange, NameInfo,
178 ADL,
John McCallf7a1a742009-11-24 19:00:30 +0000179 /*Overload*/ true,
Douglas Gregor5a84dec2010-05-23 18:57:34 +0000180 /*ExplicitTemplateArgs*/ true,
181 Begin, End);
John McCallf7a1a742009-11-24 19:00:30 +0000182
183 reinterpret_cast<ExplicitTemplateArgumentList*>(ULE+1)->initializeFrom(Args);
184
185 return ULE;
186}
187
Argyrios Kyrtzidisbd65bb52010-06-25 09:03:34 +0000188UnresolvedLookupExpr *
189UnresolvedLookupExpr::CreateEmpty(ASTContext &C, unsigned NumTemplateArgs) {
190 std::size_t size = sizeof(UnresolvedLookupExpr);
191 if (NumTemplateArgs != 0)
192 size += ExplicitTemplateArgumentList::sizeFor(NumTemplateArgs);
193
194 void *Mem = C.Allocate(size, llvm::alignof<UnresolvedLookupExpr>());
195 UnresolvedLookupExpr *E = new (Mem) UnresolvedLookupExpr(EmptyShell());
196 E->HasExplicitTemplateArgs = NumTemplateArgs != 0;
197 return E;
198}
199
Douglas Gregor928e6fc2010-05-23 19:36:40 +0000200OverloadExpr::OverloadExpr(StmtClass K, ASTContext &C, QualType T,
201 bool Dependent, NestedNameSpecifier *Qualifier,
Abramo Bagnara25777432010-08-11 22:01:17 +0000202 SourceRange QRange,
203 const DeclarationNameInfo &NameInfo,
204 bool HasTemplateArgs,
Douglas Gregor928e6fc2010-05-23 19:36:40 +0000205 UnresolvedSetIterator Begin,
206 UnresolvedSetIterator End)
207 : Expr(K, T, Dependent, Dependent),
Abramo Bagnara25777432010-08-11 22:01:17 +0000208 Results(0), NumResults(0), NameInfo(NameInfo), Qualifier(Qualifier),
209 QualifierRange(QRange), HasExplicitTemplateArgs(HasTemplateArgs)
Douglas Gregor928e6fc2010-05-23 19:36:40 +0000210{
Argyrios Kyrtzidisa77eb082010-06-25 09:03:26 +0000211 initializeResults(C, Begin, End);
212}
213
214void OverloadExpr::initializeResults(ASTContext &C,
215 UnresolvedSetIterator Begin,
216 UnresolvedSetIterator End) {
217 assert(Results == 0 && "Results already initialized!");
218 NumResults = End - Begin;
Douglas Gregor928e6fc2010-05-23 19:36:40 +0000219 if (NumResults) {
220 Results = static_cast<DeclAccessPair *>(
221 C.Allocate(sizeof(DeclAccessPair) * NumResults,
222 llvm::alignof<DeclAccessPair>()));
223 memcpy(Results, &*Begin.getIterator(),
Argyrios Kyrtzidisa77eb082010-06-25 09:03:26 +0000224 NumResults * sizeof(DeclAccessPair));
Douglas Gregor928e6fc2010-05-23 19:36:40 +0000225 }
226}
227
Argyrios Kyrtzidisa77eb082010-06-25 09:03:26 +0000228
John McCall7bb12da2010-02-02 06:20:04 +0000229bool OverloadExpr::ComputeDependence(UnresolvedSetIterator Begin,
230 UnresolvedSetIterator End,
231 const TemplateArgumentListInfo *Args) {
John McCalleec51cf2010-01-20 00:46:10 +0000232 for (UnresolvedSetImpl::const_iterator I = Begin; I != End; ++I)
John McCallf7a1a742009-11-24 19:00:30 +0000233 if ((*I)->getDeclContext()->isDependentContext())
234 return true;
235
236 if (Args && TemplateSpecializationType::anyDependentTemplateArguments(*Args))
237 return true;
238
239 return false;
240}
241
John McCalle9ee23e2010-04-22 18:44:12 +0000242CXXRecordDecl *OverloadExpr::getNamingClass() const {
243 if (isa<UnresolvedLookupExpr>(this))
244 return cast<UnresolvedLookupExpr>(this)->getNamingClass();
245 else
246 return cast<UnresolvedMemberExpr>(this)->getNamingClass();
247}
248
John McCallba135432009-11-21 08:51:07 +0000249Stmt::child_iterator UnresolvedLookupExpr::child_begin() {
Mike Stump1eb44332009-09-09 15:08:12 +0000250 return child_iterator();
Douglas Gregor5c37de72008-12-06 00:22:45 +0000251}
John McCallba135432009-11-21 08:51:07 +0000252Stmt::child_iterator UnresolvedLookupExpr::child_end() {
Douglas Gregor5c37de72008-12-06 00:22:45 +0000253 return child_iterator();
254}
Sebastian Redl64b45f72009-01-05 20:52:13 +0000255// UnaryTypeTraitExpr
256Stmt::child_iterator UnaryTypeTraitExpr::child_begin() {
257 return child_iterator();
258}
259Stmt::child_iterator UnaryTypeTraitExpr::child_end() {
260 return child_iterator();
261}
262
John McCall865d4472009-11-19 22:55:06 +0000263// DependentScopeDeclRefExpr
John McCallf7a1a742009-11-24 19:00:30 +0000264DependentScopeDeclRefExpr *
265DependentScopeDeclRefExpr::Create(ASTContext &C,
266 NestedNameSpecifier *Qualifier,
267 SourceRange QualifierRange,
Abramo Bagnara25777432010-08-11 22:01:17 +0000268 const DeclarationNameInfo &NameInfo,
John McCallf7a1a742009-11-24 19:00:30 +0000269 const TemplateArgumentListInfo *Args) {
270 std::size_t size = sizeof(DependentScopeDeclRefExpr);
271 if (Args) size += ExplicitTemplateArgumentList::sizeFor(*Args);
272 void *Mem = C.Allocate(size);
273
274 DependentScopeDeclRefExpr *DRE
275 = new (Mem) DependentScopeDeclRefExpr(C.DependentTy,
276 Qualifier, QualifierRange,
Abramo Bagnara25777432010-08-11 22:01:17 +0000277 NameInfo, Args != 0);
John McCallf7a1a742009-11-24 19:00:30 +0000278
279 if (Args)
280 reinterpret_cast<ExplicitTemplateArgumentList*>(DRE+1)
281 ->initializeFrom(*Args);
282
283 return DRE;
284}
285
Argyrios Kyrtzidis12dffcd2010-06-28 09:31:56 +0000286DependentScopeDeclRefExpr *
287DependentScopeDeclRefExpr::CreateEmpty(ASTContext &C,
288 unsigned NumTemplateArgs) {
289 std::size_t size = sizeof(DependentScopeDeclRefExpr);
290 if (NumTemplateArgs)
291 size += ExplicitTemplateArgumentList::sizeFor(NumTemplateArgs);
292 void *Mem = C.Allocate(size);
293
294 return new (Mem) DependentScopeDeclRefExpr(QualType(), 0, SourceRange(),
Abramo Bagnara25777432010-08-11 22:01:17 +0000295 DeclarationNameInfo(),
Argyrios Kyrtzidis12dffcd2010-06-28 09:31:56 +0000296 NumTemplateArgs != 0);
297}
298
John McCall865d4472009-11-19 22:55:06 +0000299StmtIterator DependentScopeDeclRefExpr::child_begin() {
Douglas Gregor5953d8b2009-03-19 17:26:29 +0000300 return child_iterator();
301}
302
John McCall865d4472009-11-19 22:55:06 +0000303StmtIterator DependentScopeDeclRefExpr::child_end() {
Douglas Gregor5953d8b2009-03-19 17:26:29 +0000304 return child_iterator();
305}
306
Douglas Gregor5e03f9e2009-07-23 23:49:00 +0000307bool UnaryTypeTraitExpr::EvaluateTrait(ASTContext& C) const {
Sebastian Redl64b45f72009-01-05 20:52:13 +0000308 switch(UTT) {
309 default: assert(false && "Unknown type trait or not implemented");
310 case UTT_IsPOD: return QueriedType->isPODType();
Sebastian Redlccf43502009-12-03 00:13:20 +0000311 case UTT_IsLiteral: return QueriedType->isLiteralType();
Sebastian Redl64b45f72009-01-05 20:52:13 +0000312 case UTT_IsClass: // Fallthrough
313 case UTT_IsUnion:
Ted Kremenek6217b802009-07-29 21:53:49 +0000314 if (const RecordType *Record = QueriedType->getAs<RecordType>()) {
Sebastian Redl64b45f72009-01-05 20:52:13 +0000315 bool Union = Record->getDecl()->isUnion();
316 return UTT == UTT_IsUnion ? Union : !Union;
317 }
318 return false;
319 case UTT_IsEnum: return QueriedType->isEnumeralType();
320 case UTT_IsPolymorphic:
Ted Kremenek6217b802009-07-29 21:53:49 +0000321 if (const RecordType *Record = QueriedType->getAs<RecordType>()) {
Sebastian Redl64b45f72009-01-05 20:52:13 +0000322 // Type traits are only parsed in C++, so we've got CXXRecords.
323 return cast<CXXRecordDecl>(Record->getDecl())->isPolymorphic();
324 }
325 return false;
Anders Carlsson67e4dd22009-03-22 01:52:17 +0000326 case UTT_IsAbstract:
Ted Kremenek6217b802009-07-29 21:53:49 +0000327 if (const RecordType *RT = QueriedType->getAs<RecordType>())
Anders Carlsson67e4dd22009-03-22 01:52:17 +0000328 return cast<CXXRecordDecl>(RT->getDecl())->isAbstract();
329 return false;
Eli Friedman1d954f62009-08-15 21:55:26 +0000330 case UTT_IsEmpty:
331 if (const RecordType *Record = QueriedType->getAs<RecordType>()) {
332 return !Record->getDecl()->isUnion()
333 && cast<CXXRecordDecl>(Record->getDecl())->isEmpty();
334 }
335 return false;
Anders Carlsson347ba892009-04-16 00:08:20 +0000336 case UTT_HasTrivialConstructor:
Douglas Gregor5e03f9e2009-07-23 23:49:00 +0000337 // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
338 // If __is_pod (type) is true then the trait is true, else if type is
339 // a cv class or union type (or array thereof) with a trivial default
340 // constructor ([class.ctor]) then the trait is true, else it is false.
341 if (QueriedType->isPODType())
342 return true;
343 if (const RecordType *RT =
Ted Kremenek6217b802009-07-29 21:53:49 +0000344 C.getBaseElementType(QueriedType)->getAs<RecordType>())
Anders Carlsson347ba892009-04-16 00:08:20 +0000345 return cast<CXXRecordDecl>(RT->getDecl())->hasTrivialConstructor();
Anders Carlsson072abef2009-04-17 02:34:54 +0000346 return false;
Douglas Gregor5e03f9e2009-07-23 23:49:00 +0000347 case UTT_HasTrivialCopy:
348 // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
349 // If __is_pod (type) is true or type is a reference type then
350 // the trait is true, else if type is a cv class or union type
351 // with a trivial copy constructor ([class.copy]) then the trait
352 // is true, else it is false.
353 if (QueriedType->isPODType() || QueriedType->isReferenceType())
354 return true;
Ted Kremenek6217b802009-07-29 21:53:49 +0000355 if (const RecordType *RT = QueriedType->getAs<RecordType>())
Douglas Gregor5e03f9e2009-07-23 23:49:00 +0000356 return cast<CXXRecordDecl>(RT->getDecl())->hasTrivialCopyConstructor();
357 return false;
358 case UTT_HasTrivialAssign:
359 // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
360 // If type is const qualified or is a reference type then the
361 // trait is false. Otherwise if __is_pod (type) is true then the
362 // trait is true, else if type is a cv class or union type with
363 // a trivial copy assignment ([class.copy]) then the trait is
364 // true, else it is false.
365 // Note: the const and reference restrictions are interesting,
366 // given that const and reference members don't prevent a class
367 // from having a trivial copy assignment operator (but do cause
368 // errors if the copy assignment operator is actually used, q.v.
369 // [class.copy]p12).
370
371 if (C.getBaseElementType(QueriedType).isConstQualified())
372 return false;
373 if (QueriedType->isPODType())
374 return true;
Ted Kremenek6217b802009-07-29 21:53:49 +0000375 if (const RecordType *RT = QueriedType->getAs<RecordType>())
Douglas Gregor5e03f9e2009-07-23 23:49:00 +0000376 return cast<CXXRecordDecl>(RT->getDecl())->hasTrivialCopyAssignment();
377 return false;
378 case UTT_HasTrivialDestructor:
379 // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
380 // If __is_pod (type) is true or type is a reference type
381 // then the trait is true, else if type is a cv class or union
382 // type (or array thereof) with a trivial destructor
383 // ([class.dtor]) then the trait is true, else it is
384 // false.
385 if (QueriedType->isPODType() || QueriedType->isReferenceType())
386 return true;
387 if (const RecordType *RT =
Ted Kremenek6217b802009-07-29 21:53:49 +0000388 C.getBaseElementType(QueriedType)->getAs<RecordType>())
Anders Carlsson072abef2009-04-17 02:34:54 +0000389 return cast<CXXRecordDecl>(RT->getDecl())->hasTrivialDestructor();
390 return false;
Sebastian Redlc238f092010-08-31 04:59:00 +0000391 // TODO: Propagate nothrowness for implicitly declared special members.
392 case UTT_HasNothrowAssign:
393 // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
394 // If type is const qualified or is a reference type then the
395 // trait is false. Otherwise if __has_trivial_assign (type)
396 // is true then the trait is true, else if type is a cv class
397 // or union type with copy assignment operators that are known
398 // not to throw an exception then the trait is true, else it is
399 // false.
400 if (C.getBaseElementType(QueriedType).isConstQualified())
401 return false;
402 if (QueriedType->isReferenceType())
403 return false;
404 if (QueriedType->isPODType())
405 return true;
406 if (const RecordType *RT = QueriedType->getAs<RecordType>()) {
407 CXXRecordDecl* RD = cast<CXXRecordDecl>(RT->getDecl());
408 if (RD->hasTrivialCopyAssignment())
409 return true;
410
411 bool FoundAssign = false;
412 bool AllNoThrow = true;
413 DeclarationName Name = C.DeclarationNames.getCXXOperatorName(OO_Equal);
414 DeclContext::lookup_const_iterator Op, OpEnd;
415 for (llvm::tie(Op, OpEnd) = RD->lookup(Name);
416 Op != OpEnd; ++Op) {
417 CXXMethodDecl *Operator = cast<CXXMethodDecl>(*Op);
418 if (Operator->isCopyAssignmentOperator()) {
419 FoundAssign = true;
420 const FunctionProtoType *CPT
421 = Operator->getType()->getAs<FunctionProtoType>();
422 if (!CPT->hasEmptyExceptionSpec()) {
423 AllNoThrow = false;
424 break;
425 }
426 }
427 }
428
429 return FoundAssign && AllNoThrow;
430 }
431 return false;
432 case UTT_HasNothrowCopy:
433 // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
434 // If __has_trivial_copy (type) is true then the trait is true, else
435 // if type is a cv class or union type with copy constructors that are
436 // known not to throw an exception then the trait is true, else it is
437 // false.
438 if (QueriedType->isPODType() || QueriedType->isReferenceType())
439 return true;
440 if (const RecordType *RT = QueriedType->getAs<RecordType>()) {
441 CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
442 if (RD->hasTrivialCopyConstructor())
443 return true;
444
445 bool FoundConstructor = false;
446 bool AllNoThrow = true;
447 unsigned FoundTQs;
448 DeclarationName ConstructorName
449 = C.DeclarationNames.getCXXConstructorName(
450 C.getCanonicalType(QueriedType));
451 DeclContext::lookup_const_iterator Con, ConEnd;
452 for (llvm::tie(Con, ConEnd) = RD->lookup(ConstructorName);
453 Con != ConEnd; ++Con) {
454 CXXConstructorDecl *Constructor = cast<CXXConstructorDecl>(*Con);
455 if (Constructor->isCopyConstructor(FoundTQs)) {
456 FoundConstructor = true;
457 const FunctionProtoType *CPT
458 = Constructor->getType()->getAs<FunctionProtoType>();
459 if (!CPT->hasEmptyExceptionSpec()) {
460 AllNoThrow = false;
461 break;
462 }
463 }
464 }
465
466 return FoundConstructor && AllNoThrow;
467 }
468 return false;
469 case UTT_HasNothrowConstructor:
470 // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
471 // If __has_trivial_constructor (type) is true then the trait is
472 // true, else if type is a cv class or union type (or array
473 // thereof) with a default constructor that is known not to
474 // throw an exception then the trait is true, else it is false.
475 if (QueriedType->isPODType())
476 return true;
477 if (const RecordType *RT =
478 C.getBaseElementType(QueriedType)->getAs<RecordType>()) {
479 CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
480 if (RD->hasTrivialConstructor())
481 return true;
482
483 if (CXXConstructorDecl *Constructor = RD->getDefaultConstructor()) {
484 const FunctionProtoType *CPT
485 = Constructor->getType()->getAs<FunctionProtoType>();
486 // TODO: check whether evaluating default arguments can throw.
487 // For now, we'll be conservative and assume that they can throw.
488 if (CPT->hasEmptyExceptionSpec() && CPT->getNumArgs() == 0)
489 return true;
490 }
491 }
492 return false;
Sebastian Redld4b25cb2010-09-02 23:19:42 +0000493 case UTT_HasVirtualDestructor:
494 // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
495 // If type is a class type with a virtual destructor ([class.dtor])
496 // then the trait is true, else it is false.
497 if (const RecordType *Record = QueriedType->getAs<RecordType>()) {
498 CXXRecordDecl *RD = cast<CXXRecordDecl>(Record->getDecl());
499 if (CXXDestructorDecl *Destructor = RD->getDestructor())
500 return Destructor->isVirtual();
501 }
502 return false;
Sebastian Redl64b45f72009-01-05 20:52:13 +0000503 }
504}
505
Ted Kremeneke3837682009-12-23 04:00:48 +0000506SourceRange CXXConstructExpr::getSourceRange() const {
507 // FIXME: Should we know where the parentheses are, if there are any?
508 for (std::reverse_iterator<Stmt**> I(&Args[NumArgs]), E(&Args[0]); I!=E;++I) {
509 // Ignore CXXDefaultExprs when computing the range, as they don't
510 // have a range.
511 if (!isa<CXXDefaultArgExpr>(*I))
512 return SourceRange(Loc, (*I)->getLocEnd());
513 }
514
515 return SourceRange(Loc);
516}
517
Douglas Gregorb4609802008-11-14 16:09:21 +0000518SourceRange CXXOperatorCallExpr::getSourceRange() const {
519 OverloadedOperatorKind Kind = getOperator();
520 if (Kind == OO_PlusPlus || Kind == OO_MinusMinus) {
521 if (getNumArgs() == 1)
522 // Prefix operator
Mike Stump1eb44332009-09-09 15:08:12 +0000523 return SourceRange(getOperatorLoc(),
Douglas Gregorb4609802008-11-14 16:09:21 +0000524 getArg(0)->getSourceRange().getEnd());
525 else
526 // Postfix operator
527 return SourceRange(getArg(0)->getSourceRange().getEnd(),
528 getOperatorLoc());
529 } else if (Kind == OO_Call) {
530 return SourceRange(getArg(0)->getSourceRange().getBegin(), getRParenLoc());
531 } else if (Kind == OO_Subscript) {
532 return SourceRange(getArg(0)->getSourceRange().getBegin(), getRParenLoc());
533 } else if (getNumArgs() == 1) {
534 return SourceRange(getOperatorLoc(), getArg(0)->getSourceRange().getEnd());
535 } else if (getNumArgs() == 2) {
536 return SourceRange(getArg(0)->getSourceRange().getBegin(),
537 getArg(1)->getSourceRange().getEnd());
538 } else {
539 return SourceRange();
540 }
541}
542
Douglas Gregor88a35142008-12-22 05:46:06 +0000543Expr *CXXMemberCallExpr::getImplicitObjectArgument() {
544 if (MemberExpr *MemExpr = dyn_cast<MemberExpr>(getCallee()->IgnoreParens()))
545 return MemExpr->getBase();
546
547 // FIXME: Will eventually need to cope with member pointers.
548 return 0;
549}
550
Douglas Gregor00b98c22009-11-12 15:31:47 +0000551SourceRange CXXMemberCallExpr::getSourceRange() const {
552 SourceLocation LocStart = getCallee()->getLocStart();
553 if (LocStart.isInvalid() && getNumArgs() > 0)
554 LocStart = getArg(0)->getLocStart();
555 return SourceRange(LocStart, getRParenLoc());
556}
557
558
Douglas Gregor49badde2008-10-27 19:41:14 +0000559//===----------------------------------------------------------------------===//
560// Named casts
561//===----------------------------------------------------------------------===//
562
563/// getCastName - Get the name of the C++ cast being used, e.g.,
564/// "static_cast", "dynamic_cast", "reinterpret_cast", or
565/// "const_cast". The returned pointer must not be freed.
566const char *CXXNamedCastExpr::getCastName() const {
567 switch (getStmtClass()) {
568 case CXXStaticCastExprClass: return "static_cast";
569 case CXXDynamicCastExprClass: return "dynamic_cast";
570 case CXXReinterpretCastExprClass: return "reinterpret_cast";
571 case CXXConstCastExprClass: return "const_cast";
572 default: return "<invalid cast>";
573 }
574}
Douglas Gregor506ae412009-01-16 18:33:17 +0000575
John McCallf871d0c2010-08-07 06:22:56 +0000576CXXStaticCastExpr *CXXStaticCastExpr::Create(ASTContext &C, QualType T,
577 CastKind K, Expr *Op,
578 const CXXCastPath *BasePath,
579 TypeSourceInfo *WrittenTy,
580 SourceLocation L) {
581 unsigned PathSize = (BasePath ? BasePath->size() : 0);
582 void *Buffer = C.Allocate(sizeof(CXXStaticCastExpr)
583 + PathSize * sizeof(CXXBaseSpecifier*));
584 CXXStaticCastExpr *E =
585 new (Buffer) CXXStaticCastExpr(T, K, Op, PathSize, WrittenTy, L);
586 if (PathSize) E->setCastPath(*BasePath);
587 return E;
588}
589
590CXXStaticCastExpr *CXXStaticCastExpr::CreateEmpty(ASTContext &C,
591 unsigned PathSize) {
592 void *Buffer =
593 C.Allocate(sizeof(CXXStaticCastExpr) + PathSize * sizeof(CXXBaseSpecifier*));
594 return new (Buffer) CXXStaticCastExpr(EmptyShell(), PathSize);
595}
596
597CXXDynamicCastExpr *CXXDynamicCastExpr::Create(ASTContext &C, QualType T,
598 CastKind K, Expr *Op,
599 const CXXCastPath *BasePath,
600 TypeSourceInfo *WrittenTy,
601 SourceLocation L) {
602 unsigned PathSize = (BasePath ? BasePath->size() : 0);
603 void *Buffer = C.Allocate(sizeof(CXXDynamicCastExpr)
604 + PathSize * sizeof(CXXBaseSpecifier*));
605 CXXDynamicCastExpr *E =
606 new (Buffer) CXXDynamicCastExpr(T, K, Op, PathSize, WrittenTy, L);
607 if (PathSize) E->setCastPath(*BasePath);
608 return E;
609}
610
611CXXDynamicCastExpr *CXXDynamicCastExpr::CreateEmpty(ASTContext &C,
612 unsigned PathSize) {
613 void *Buffer =
614 C.Allocate(sizeof(CXXDynamicCastExpr) + PathSize * sizeof(CXXBaseSpecifier*));
615 return new (Buffer) CXXDynamicCastExpr(EmptyShell(), PathSize);
616}
617
618CXXReinterpretCastExpr *
619CXXReinterpretCastExpr::Create(ASTContext &C, QualType T, CastKind K, Expr *Op,
620 const CXXCastPath *BasePath,
621 TypeSourceInfo *WrittenTy, SourceLocation L) {
622 unsigned PathSize = (BasePath ? BasePath->size() : 0);
623 void *Buffer =
624 C.Allocate(sizeof(CXXReinterpretCastExpr) + PathSize * sizeof(CXXBaseSpecifier*));
625 CXXReinterpretCastExpr *E =
626 new (Buffer) CXXReinterpretCastExpr(T, K, Op, PathSize, WrittenTy, L);
627 if (PathSize) E->setCastPath(*BasePath);
628 return E;
629}
630
631CXXReinterpretCastExpr *
632CXXReinterpretCastExpr::CreateEmpty(ASTContext &C, unsigned PathSize) {
633 void *Buffer = C.Allocate(sizeof(CXXReinterpretCastExpr)
634 + PathSize * sizeof(CXXBaseSpecifier*));
635 return new (Buffer) CXXReinterpretCastExpr(EmptyShell(), PathSize);
636}
637
638CXXConstCastExpr *CXXConstCastExpr::Create(ASTContext &C, QualType T, Expr *Op,
639 TypeSourceInfo *WrittenTy,
640 SourceLocation L) {
641 return new (C) CXXConstCastExpr(T, Op, WrittenTy, L);
642}
643
644CXXConstCastExpr *CXXConstCastExpr::CreateEmpty(ASTContext &C) {
645 return new (C) CXXConstCastExpr(EmptyShell());
646}
647
648CXXFunctionalCastExpr *
649CXXFunctionalCastExpr::Create(ASTContext &C, QualType T,
650 TypeSourceInfo *Written, SourceLocation L,
651 CastKind K, Expr *Op, const CXXCastPath *BasePath,
652 SourceLocation R) {
653 unsigned PathSize = (BasePath ? BasePath->size() : 0);
654 void *Buffer = C.Allocate(sizeof(CXXFunctionalCastExpr)
655 + PathSize * sizeof(CXXBaseSpecifier*));
656 CXXFunctionalCastExpr *E =
657 new (Buffer) CXXFunctionalCastExpr(T, Written, L, K, Op, PathSize, R);
658 if (PathSize) E->setCastPath(*BasePath);
659 return E;
660}
661
662CXXFunctionalCastExpr *
663CXXFunctionalCastExpr::CreateEmpty(ASTContext &C, unsigned PathSize) {
664 void *Buffer = C.Allocate(sizeof(CXXFunctionalCastExpr)
665 + PathSize * sizeof(CXXBaseSpecifier*));
666 return new (Buffer) CXXFunctionalCastExpr(EmptyShell(), PathSize);
667}
668
669
Douglas Gregor65222e82009-12-23 18:19:08 +0000670CXXDefaultArgExpr *
Douglas Gregor036aed12009-12-23 23:03:06 +0000671CXXDefaultArgExpr::Create(ASTContext &C, SourceLocation Loc,
672 ParmVarDecl *Param, Expr *SubExpr) {
Douglas Gregor65222e82009-12-23 18:19:08 +0000673 void *Mem = C.Allocate(sizeof(CXXDefaultArgExpr) + sizeof(Stmt *));
Douglas Gregor036aed12009-12-23 23:03:06 +0000674 return new (Mem) CXXDefaultArgExpr(CXXDefaultArgExprClass, Loc, Param,
675 SubExpr);
Douglas Gregor65222e82009-12-23 18:19:08 +0000676}
677
Mike Stump1eb44332009-09-09 15:08:12 +0000678CXXTemporary *CXXTemporary::Create(ASTContext &C,
Anders Carlssonb859f352009-05-30 20:34:37 +0000679 const CXXDestructorDecl *Destructor) {
Anders Carlsson88eaf072009-05-30 22:38:53 +0000680 return new (C) CXXTemporary(Destructor);
681}
682
Mike Stump1eb44332009-09-09 15:08:12 +0000683CXXBindTemporaryExpr *CXXBindTemporaryExpr::Create(ASTContext &C,
Anders Carlssonfceb0a82009-05-30 20:03:25 +0000684 CXXTemporary *Temp,
685 Expr* SubExpr) {
Mike Stump1eb44332009-09-09 15:08:12 +0000686 assert(SubExpr->getType()->isRecordType() &&
Anders Carlssonfceb0a82009-05-30 20:03:25 +0000687 "Expression bound to a temporary must have record type!");
688
Anders Carlssonb859f352009-05-30 20:34:37 +0000689 return new (C) CXXBindTemporaryExpr(Temp, SubExpr);
Anders Carlssonfceb0a82009-05-30 20:03:25 +0000690}
691
Anders Carlsson8e587a12009-05-30 20:56:46 +0000692CXXTemporaryObjectExpr::CXXTemporaryObjectExpr(ASTContext &C,
Anders Carlsson26de5492009-04-24 05:23:13 +0000693 CXXConstructorDecl *Cons,
Douglas Gregor506ae412009-01-16 18:33:17 +0000694 QualType writtenTy,
Mike Stump1eb44332009-09-09 15:08:12 +0000695 SourceLocation tyBeginLoc,
Douglas Gregor506ae412009-01-16 18:33:17 +0000696 Expr **Args,
Mike Stump1eb44332009-09-09 15:08:12 +0000697 unsigned NumArgs,
Douglas Gregor1c63b9c2010-04-27 20:36:09 +0000698 SourceLocation rParenLoc,
699 bool ZeroInitialization)
Douglas Gregor99a2e602009-12-16 01:38:02 +0000700 : CXXConstructExpr(C, CXXTemporaryObjectExprClass, writtenTy, tyBeginLoc,
Douglas Gregor1c63b9c2010-04-27 20:36:09 +0000701 Cons, false, Args, NumArgs, ZeroInitialization),
Anders Carlsson524fa132009-04-24 17:34:38 +0000702 TyBeginLoc(tyBeginLoc), RParenLoc(rParenLoc) {
Douglas Gregor506ae412009-01-16 18:33:17 +0000703}
Anders Carlsson19d28a62009-04-21 02:22:11 +0000704
Mike Stump1eb44332009-09-09 15:08:12 +0000705CXXConstructExpr *CXXConstructExpr::Create(ASTContext &C, QualType T,
Douglas Gregor99a2e602009-12-16 01:38:02 +0000706 SourceLocation Loc,
Anders Carlsson8e587a12009-05-30 20:56:46 +0000707 CXXConstructorDecl *D, bool Elidable,
Douglas Gregor16006c92009-12-16 18:50:27 +0000708 Expr **Args, unsigned NumArgs,
Douglas Gregor9db7dbb2010-01-31 09:12:51 +0000709 bool ZeroInitialization,
Anders Carlssonfcaeef22010-05-02 23:53:04 +0000710 ConstructionKind ConstructKind) {
Douglas Gregor99a2e602009-12-16 01:38:02 +0000711 return new (C) CXXConstructExpr(C, CXXConstructExprClass, T, Loc, D,
Douglas Gregor9db7dbb2010-01-31 09:12:51 +0000712 Elidable, Args, NumArgs, ZeroInitialization,
Anders Carlssonfcaeef22010-05-02 23:53:04 +0000713 ConstructKind);
Anders Carlssone349bea2009-04-23 02:32:43 +0000714}
715
Mike Stump1eb44332009-09-09 15:08:12 +0000716CXXConstructExpr::CXXConstructExpr(ASTContext &C, StmtClass SC, QualType T,
Douglas Gregor99a2e602009-12-16 01:38:02 +0000717 SourceLocation Loc,
Anders Carlsson8e587a12009-05-30 20:56:46 +0000718 CXXConstructorDecl *D, bool elidable,
Douglas Gregor16006c92009-12-16 18:50:27 +0000719 Expr **args, unsigned numargs,
Anders Carlsson72e96fd2010-05-02 22:54:08 +0000720 bool ZeroInitialization,
721 ConstructionKind ConstructKind)
Anders Carlssonbd6734e2009-04-24 05:04:04 +0000722: Expr(SC, T,
Anders Carlssone349bea2009-04-23 02:32:43 +0000723 T->isDependentType(),
724 (T->isDependentType() ||
725 CallExpr::hasAnyValueDependentArguments(args, numargs))),
Douglas Gregor16006c92009-12-16 18:50:27 +0000726 Constructor(D), Loc(Loc), Elidable(elidable),
Anders Carlsson72e96fd2010-05-02 22:54:08 +0000727 ZeroInitialization(ZeroInitialization), ConstructKind(ConstructKind),
728 Args(0), NumArgs(numargs)
Douglas Gregor16006c92009-12-16 18:50:27 +0000729{
730 if (NumArgs) {
731 Args = new (C) Stmt*[NumArgs];
732
733 for (unsigned i = 0; i != NumArgs; ++i) {
734 assert(args[i] && "NULL argument in CXXConstructExpr");
735 Args[i] = args[i];
Anders Carlssone349bea2009-04-23 02:32:43 +0000736 }
Douglas Gregor16006c92009-12-16 18:50:27 +0000737 }
Anders Carlssone349bea2009-04-23 02:32:43 +0000738}
739
Ted Kremenekd04ed412010-05-10 20:06:30 +0000740CXXExprWithTemporaries::CXXExprWithTemporaries(ASTContext &C,
741 Expr *subexpr,
Mike Stump1eb44332009-09-09 15:08:12 +0000742 CXXTemporary **temps,
Anders Carlsson0ece4912009-12-15 20:51:39 +0000743 unsigned numtemps)
Chris Lattnerd2598362010-05-10 00:25:06 +0000744 : Expr(CXXExprWithTemporariesClass, subexpr->getType(),
Mike Stump1eb44332009-09-09 15:08:12 +0000745 subexpr->isTypeDependent(), subexpr->isValueDependent()),
Chris Lattnerd2598362010-05-10 00:25:06 +0000746 SubExpr(subexpr), Temps(0), NumTemps(0) {
Chris Lattneraff32cb2010-05-10 00:45:12 +0000747 if (numtemps) {
Ted Kremenekd04ed412010-05-10 20:06:30 +0000748 setNumTemporaries(C, numtemps);
Chris Lattnerd2598362010-05-10 00:25:06 +0000749 for (unsigned i = 0; i != numtemps; ++i)
Anders Carlssonff6b3d62009-05-30 21:05:25 +0000750 Temps[i] = temps[i];
Anders Carlsson02bbfa32009-04-24 22:47:04 +0000751 }
752}
753
Ted Kremenekd04ed412010-05-10 20:06:30 +0000754void CXXExprWithTemporaries::setNumTemporaries(ASTContext &C, unsigned N) {
Chris Lattnerd2598362010-05-10 00:25:06 +0000755 assert(Temps == 0 && "Cannot resize with this");
Daniel Dunbar90556d42010-05-10 15:59:37 +0000756 NumTemps = N;
Ted Kremenekd04ed412010-05-10 20:06:30 +0000757 Temps = new (C) CXXTemporary*[NumTemps];
Chris Lattnerd2598362010-05-10 00:25:06 +0000758}
759
760
Mike Stump1eb44332009-09-09 15:08:12 +0000761CXXExprWithTemporaries *CXXExprWithTemporaries::Create(ASTContext &C,
Anders Carlsson88eaf072009-05-30 22:38:53 +0000762 Expr *SubExpr,
Mike Stump1eb44332009-09-09 15:08:12 +0000763 CXXTemporary **Temps,
Anders Carlsson0ece4912009-12-15 20:51:39 +0000764 unsigned NumTemps) {
Ted Kremenekd04ed412010-05-10 20:06:30 +0000765 return new (C) CXXExprWithTemporaries(C, SubExpr, Temps, NumTemps);
Anders Carlsson88eaf072009-05-30 22:38:53 +0000766}
767
Anders Carlssonfceb0a82009-05-30 20:03:25 +0000768// CXXBindTemporaryExpr
769Stmt::child_iterator CXXBindTemporaryExpr::child_begin() {
770 return &SubExpr;
771}
772
Mike Stump1eb44332009-09-09 15:08:12 +0000773Stmt::child_iterator CXXBindTemporaryExpr::child_end() {
Anders Carlssonfceb0a82009-05-30 20:03:25 +0000774 return &SubExpr + 1;
775}
776
Anders Carlssone349bea2009-04-23 02:32:43 +0000777// CXXConstructExpr
778Stmt::child_iterator CXXConstructExpr::child_begin() {
779 return &Args[0];
780}
781Stmt::child_iterator CXXConstructExpr::child_end() {
782 return &Args[0]+NumArgs;
783}
784
Anders Carlsson55674ac2009-05-01 22:21:22 +0000785// CXXExprWithTemporaries
786Stmt::child_iterator CXXExprWithTemporaries::child_begin() {
787 return &SubExpr;
Anders Carlsson19d28a62009-04-21 02:22:11 +0000788}
Anders Carlsson02bbfa32009-04-24 22:47:04 +0000789
Mike Stump1eb44332009-09-09 15:08:12 +0000790Stmt::child_iterator CXXExprWithTemporaries::child_end() {
Anders Carlsson55674ac2009-05-01 22:21:22 +0000791 return &SubExpr + 1;
792}
Anders Carlsson02bbfa32009-04-24 22:47:04 +0000793
Douglas Gregord81e6ca2009-05-20 18:46:25 +0000794CXXUnresolvedConstructExpr::CXXUnresolvedConstructExpr(
795 SourceLocation TyBeginLoc,
796 QualType T,
797 SourceLocation LParenLoc,
798 Expr **Args,
799 unsigned NumArgs,
800 SourceLocation RParenLoc)
801 : Expr(CXXUnresolvedConstructExprClass, T.getNonReferenceType(),
802 T->isDependentType(), true),
803 TyBeginLoc(TyBeginLoc),
804 Type(T),
805 LParenLoc(LParenLoc),
806 RParenLoc(RParenLoc),
807 NumArgs(NumArgs) {
808 Stmt **StoredArgs = reinterpret_cast<Stmt **>(this + 1);
809 memcpy(StoredArgs, Args, sizeof(Expr *) * NumArgs);
810}
811
812CXXUnresolvedConstructExpr *
Mike Stump1eb44332009-09-09 15:08:12 +0000813CXXUnresolvedConstructExpr::Create(ASTContext &C,
Douglas Gregord81e6ca2009-05-20 18:46:25 +0000814 SourceLocation TyBegin,
815 QualType T,
816 SourceLocation LParenLoc,
817 Expr **Args,
818 unsigned NumArgs,
819 SourceLocation RParenLoc) {
820 void *Mem = C.Allocate(sizeof(CXXUnresolvedConstructExpr) +
821 sizeof(Expr *) * NumArgs);
822 return new (Mem) CXXUnresolvedConstructExpr(TyBegin, T, LParenLoc,
823 Args, NumArgs, RParenLoc);
824}
825
Argyrios Kyrtzidis8dfbd8b2010-06-24 08:57:31 +0000826CXXUnresolvedConstructExpr *
827CXXUnresolvedConstructExpr::CreateEmpty(ASTContext &C, unsigned NumArgs) {
828 Stmt::EmptyShell Empty;
829 void *Mem = C.Allocate(sizeof(CXXUnresolvedConstructExpr) +
830 sizeof(Expr *) * NumArgs);
831 return new (Mem) CXXUnresolvedConstructExpr(Empty, NumArgs);
832}
833
Douglas Gregord81e6ca2009-05-20 18:46:25 +0000834Stmt::child_iterator CXXUnresolvedConstructExpr::child_begin() {
835 return child_iterator(reinterpret_cast<Stmt **>(this + 1));
836}
837
838Stmt::child_iterator CXXUnresolvedConstructExpr::child_end() {
839 return child_iterator(reinterpret_cast<Stmt **>(this + 1) + NumArgs);
840}
Sebastian Redl8b0b4752009-05-16 18:50:46 +0000841
John McCall865d4472009-11-19 22:55:06 +0000842CXXDependentScopeMemberExpr::CXXDependentScopeMemberExpr(ASTContext &C,
John McCallaa81e162009-12-01 22:10:20 +0000843 Expr *Base, QualType BaseType,
844 bool IsArrow,
Douglas Gregor3b6afbb2009-09-09 00:23:06 +0000845 SourceLocation OperatorLoc,
846 NestedNameSpecifier *Qualifier,
847 SourceRange QualifierRange,
848 NamedDecl *FirstQualifierFoundInScope,
Abramo Bagnara25777432010-08-11 22:01:17 +0000849 DeclarationNameInfo MemberNameInfo,
John McCalld5532b62009-11-23 01:53:49 +0000850 const TemplateArgumentListInfo *TemplateArgs)
John McCall865d4472009-11-19 22:55:06 +0000851 : Expr(CXXDependentScopeMemberExprClass, C.DependentTy, true, true),
John McCallaa81e162009-12-01 22:10:20 +0000852 Base(Base), BaseType(BaseType), IsArrow(IsArrow),
853 HasExplicitTemplateArgs(TemplateArgs != 0),
Douglas Gregor3b6afbb2009-09-09 00:23:06 +0000854 OperatorLoc(OperatorLoc),
855 Qualifier(Qualifier), QualifierRange(QualifierRange),
856 FirstQualifierFoundInScope(FirstQualifierFoundInScope),
Abramo Bagnara25777432010-08-11 22:01:17 +0000857 MemberNameInfo(MemberNameInfo) {
John McCalld5532b62009-11-23 01:53:49 +0000858 if (TemplateArgs)
John McCall096832c2010-08-19 23:49:38 +0000859 getExplicitTemplateArgs().initializeFrom(*TemplateArgs);
Douglas Gregor3b6afbb2009-09-09 00:23:06 +0000860}
861
John McCall865d4472009-11-19 22:55:06 +0000862CXXDependentScopeMemberExpr *
863CXXDependentScopeMemberExpr::Create(ASTContext &C,
John McCallaa81e162009-12-01 22:10:20 +0000864 Expr *Base, QualType BaseType, bool IsArrow,
Douglas Gregor3b6afbb2009-09-09 00:23:06 +0000865 SourceLocation OperatorLoc,
866 NestedNameSpecifier *Qualifier,
867 SourceRange QualifierRange,
868 NamedDecl *FirstQualifierFoundInScope,
Abramo Bagnara25777432010-08-11 22:01:17 +0000869 DeclarationNameInfo MemberNameInfo,
John McCalld5532b62009-11-23 01:53:49 +0000870 const TemplateArgumentListInfo *TemplateArgs) {
871 if (!TemplateArgs)
John McCallaa81e162009-12-01 22:10:20 +0000872 return new (C) CXXDependentScopeMemberExpr(C, Base, BaseType,
873 IsArrow, OperatorLoc,
874 Qualifier, QualifierRange,
875 FirstQualifierFoundInScope,
Abramo Bagnara25777432010-08-11 22:01:17 +0000876 MemberNameInfo);
Mike Stump1eb44332009-09-09 15:08:12 +0000877
John McCalld5532b62009-11-23 01:53:49 +0000878 std::size_t size = sizeof(CXXDependentScopeMemberExpr);
879 if (TemplateArgs)
880 size += ExplicitTemplateArgumentList::sizeFor(*TemplateArgs);
881
882 void *Mem = C.Allocate(size, llvm::alignof<CXXDependentScopeMemberExpr>());
John McCallaa81e162009-12-01 22:10:20 +0000883 return new (Mem) CXXDependentScopeMemberExpr(C, Base, BaseType,
884 IsArrow, OperatorLoc,
885 Qualifier, QualifierRange,
886 FirstQualifierFoundInScope,
Abramo Bagnara25777432010-08-11 22:01:17 +0000887 MemberNameInfo, TemplateArgs);
Douglas Gregor3b6afbb2009-09-09 00:23:06 +0000888}
889
Argyrios Kyrtzidis8dfbd8b2010-06-24 08:57:31 +0000890CXXDependentScopeMemberExpr *
891CXXDependentScopeMemberExpr::CreateEmpty(ASTContext &C,
892 unsigned NumTemplateArgs) {
893 if (NumTemplateArgs == 0)
894 return new (C) CXXDependentScopeMemberExpr(C, 0, QualType(),
895 0, SourceLocation(), 0,
896 SourceRange(), 0,
Abramo Bagnara25777432010-08-11 22:01:17 +0000897 DeclarationNameInfo());
Argyrios Kyrtzidis8dfbd8b2010-06-24 08:57:31 +0000898
899 std::size_t size = sizeof(CXXDependentScopeMemberExpr) +
900 ExplicitTemplateArgumentList::sizeFor(NumTemplateArgs);
901 void *Mem = C.Allocate(size, llvm::alignof<CXXDependentScopeMemberExpr>());
902 CXXDependentScopeMemberExpr *E
903 = new (Mem) CXXDependentScopeMemberExpr(C, 0, QualType(),
904 0, SourceLocation(), 0,
905 SourceRange(), 0,
Abramo Bagnara25777432010-08-11 22:01:17 +0000906 DeclarationNameInfo(), 0);
Argyrios Kyrtzidis8dfbd8b2010-06-24 08:57:31 +0000907 E->HasExplicitTemplateArgs = true;
908 return E;
909}
910
John McCall865d4472009-11-19 22:55:06 +0000911Stmt::child_iterator CXXDependentScopeMemberExpr::child_begin() {
Douglas Gregor1c0ca592009-05-22 21:13:27 +0000912 return child_iterator(&Base);
913}
914
John McCall865d4472009-11-19 22:55:06 +0000915Stmt::child_iterator CXXDependentScopeMemberExpr::child_end() {
John McCallaa81e162009-12-01 22:10:20 +0000916 if (isImplicitAccess())
917 return child_iterator(&Base);
Douglas Gregor1c0ca592009-05-22 21:13:27 +0000918 return child_iterator(&Base + 1);
919}
John McCall129e2df2009-11-30 22:42:35 +0000920
Douglas Gregor928e6fc2010-05-23 19:36:40 +0000921UnresolvedMemberExpr::UnresolvedMemberExpr(ASTContext &C, QualType T,
922 bool Dependent,
John McCall129e2df2009-11-30 22:42:35 +0000923 bool HasUnresolvedUsing,
John McCallaa81e162009-12-01 22:10:20 +0000924 Expr *Base, QualType BaseType,
925 bool IsArrow,
John McCall129e2df2009-11-30 22:42:35 +0000926 SourceLocation OperatorLoc,
927 NestedNameSpecifier *Qualifier,
928 SourceRange QualifierRange,
Abramo Bagnara25777432010-08-11 22:01:17 +0000929 const DeclarationNameInfo &MemberNameInfo,
Douglas Gregor5a84dec2010-05-23 18:57:34 +0000930 const TemplateArgumentListInfo *TemplateArgs,
931 UnresolvedSetIterator Begin,
932 UnresolvedSetIterator End)
Douglas Gregor928e6fc2010-05-23 19:36:40 +0000933 : OverloadExpr(UnresolvedMemberExprClass, C, T, Dependent,
Abramo Bagnara25777432010-08-11 22:01:17 +0000934 Qualifier, QualifierRange, MemberNameInfo,
Douglas Gregor5a84dec2010-05-23 18:57:34 +0000935 TemplateArgs != 0, Begin, End),
John McCall7bb12da2010-02-02 06:20:04 +0000936 IsArrow(IsArrow), HasUnresolvedUsing(HasUnresolvedUsing),
937 Base(Base), BaseType(BaseType), OperatorLoc(OperatorLoc) {
John McCall129e2df2009-11-30 22:42:35 +0000938 if (TemplateArgs)
John McCall7bb12da2010-02-02 06:20:04 +0000939 getExplicitTemplateArgs().initializeFrom(*TemplateArgs);
John McCall129e2df2009-11-30 22:42:35 +0000940}
941
942UnresolvedMemberExpr *
943UnresolvedMemberExpr::Create(ASTContext &C, bool Dependent,
944 bool HasUnresolvedUsing,
John McCallaa81e162009-12-01 22:10:20 +0000945 Expr *Base, QualType BaseType, bool IsArrow,
John McCall129e2df2009-11-30 22:42:35 +0000946 SourceLocation OperatorLoc,
947 NestedNameSpecifier *Qualifier,
948 SourceRange QualifierRange,
Abramo Bagnara25777432010-08-11 22:01:17 +0000949 const DeclarationNameInfo &MemberNameInfo,
Douglas Gregor5a84dec2010-05-23 18:57:34 +0000950 const TemplateArgumentListInfo *TemplateArgs,
951 UnresolvedSetIterator Begin,
952 UnresolvedSetIterator End) {
John McCall129e2df2009-11-30 22:42:35 +0000953 std::size_t size = sizeof(UnresolvedMemberExpr);
954 if (TemplateArgs)
955 size += ExplicitTemplateArgumentList::sizeFor(*TemplateArgs);
956
957 void *Mem = C.Allocate(size, llvm::alignof<UnresolvedMemberExpr>());
Douglas Gregor928e6fc2010-05-23 19:36:40 +0000958 return new (Mem) UnresolvedMemberExpr(C,
John McCall129e2df2009-11-30 22:42:35 +0000959 Dependent ? C.DependentTy : C.OverloadTy,
John McCallaa81e162009-12-01 22:10:20 +0000960 Dependent, HasUnresolvedUsing, Base, BaseType,
961 IsArrow, OperatorLoc, Qualifier, QualifierRange,
Abramo Bagnara25777432010-08-11 22:01:17 +0000962 MemberNameInfo, TemplateArgs, Begin, End);
John McCall129e2df2009-11-30 22:42:35 +0000963}
964
Argyrios Kyrtzidisa77eb082010-06-25 09:03:26 +0000965UnresolvedMemberExpr *
966UnresolvedMemberExpr::CreateEmpty(ASTContext &C, unsigned NumTemplateArgs) {
967 std::size_t size = sizeof(UnresolvedMemberExpr);
968 if (NumTemplateArgs != 0)
969 size += ExplicitTemplateArgumentList::sizeFor(NumTemplateArgs);
970
971 void *Mem = C.Allocate(size, llvm::alignof<UnresolvedMemberExpr>());
972 UnresolvedMemberExpr *E = new (Mem) UnresolvedMemberExpr(EmptyShell());
973 E->HasExplicitTemplateArgs = NumTemplateArgs != 0;
974 return E;
975}
976
John McCallc373d482010-01-27 01:50:18 +0000977CXXRecordDecl *UnresolvedMemberExpr::getNamingClass() const {
978 // Unlike for UnresolvedLookupExpr, it is very easy to re-derive this.
979
980 // If there was a nested name specifier, it names the naming class.
981 // It can't be dependent: after all, we were actually able to do the
982 // lookup.
Douglas Gregorc96be1e2010-04-27 18:19:34 +0000983 CXXRecordDecl *Record = 0;
John McCall7bb12da2010-02-02 06:20:04 +0000984 if (getQualifier()) {
985 Type *T = getQualifier()->getAsType();
John McCallc373d482010-01-27 01:50:18 +0000986 assert(T && "qualifier in member expression does not name type");
Douglas Gregorc96be1e2010-04-27 18:19:34 +0000987 Record = T->getAsCXXRecordDecl();
988 assert(Record && "qualifier in member expression does not name record");
989 }
John McCallc373d482010-01-27 01:50:18 +0000990 // Otherwise the naming class must have been the base class.
Douglas Gregorc96be1e2010-04-27 18:19:34 +0000991 else {
John McCallc373d482010-01-27 01:50:18 +0000992 QualType BaseType = getBaseType().getNonReferenceType();
993 if (isArrow()) {
994 const PointerType *PT = BaseType->getAs<PointerType>();
995 assert(PT && "base of arrow member access is not pointer");
996 BaseType = PT->getPointeeType();
997 }
998
Douglas Gregorc96be1e2010-04-27 18:19:34 +0000999 Record = BaseType->getAsCXXRecordDecl();
1000 assert(Record && "base of member expression does not name record");
John McCallc373d482010-01-27 01:50:18 +00001001 }
1002
Douglas Gregorc96be1e2010-04-27 18:19:34 +00001003 return Record;
John McCallc373d482010-01-27 01:50:18 +00001004}
1005
John McCall129e2df2009-11-30 22:42:35 +00001006Stmt::child_iterator UnresolvedMemberExpr::child_begin() {
1007 return child_iterator(&Base);
1008}
1009
1010Stmt::child_iterator UnresolvedMemberExpr::child_end() {
John McCallaa81e162009-12-01 22:10:20 +00001011 if (isImplicitAccess())
1012 return child_iterator(&Base);
John McCall129e2df2009-11-30 22:42:35 +00001013 return child_iterator(&Base + 1);
1014}