blob: fd22db277b45759bb1ee5ad20187e45f57216c50 [file] [log] [blame]
Ted Kremeneke3a0c142007-08-24 20:21:10 +00001//===--- ExprCXX.cpp - (C++) Expression AST Node Implementation -----------===//
2//
3// The LLVM Compiler Infrastructure
4//
Chris Lattner5b12ab82007-12-29 19:59:25 +00005// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Ted Kremeneke3a0c142007-08-24 20:21:10 +00007//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the subclesses of Expr class declared in ExprCXX.h
11//
12//===----------------------------------------------------------------------===//
13
Douglas Gregor993603d2008-11-14 16:09:21 +000014#include "clang/Basic/IdentifierTable.h"
15#include "clang/AST/DeclCXX.h"
Douglas Gregora727cb92009-06-30 22:34:41 +000016#include "clang/AST/DeclTemplate.h"
Ted Kremeneke3a0c142007-08-24 20:21:10 +000017#include "clang/AST/ExprCXX.h"
Douglas Gregor651fe5e2010-02-24 23:40:28 +000018#include "clang/AST/TypeLoc.h"
Ted Kremeneke3a0c142007-08-24 20:21:10 +000019using namespace clang;
20
Douglas Gregor9da64192010-04-26 22:37:10 +000021
Ted Kremeneke3a0c142007-08-24 20:21:10 +000022//===----------------------------------------------------------------------===//
23// Child Iterators for iterating over subexpressions/substatements
24//===----------------------------------------------------------------------===//
25
Douglas Gregor9da64192010-04-26 22:37:10 +000026QualType CXXTypeidExpr::getTypeOperand() const {
27 assert(isTypeOperand() && "Cannot call getTypeOperand for typeid(expr)");
28 return Operand.get<TypeSourceInfo *>()->getType().getNonReferenceType()
29 .getUnqualifiedType();
30}
31
Sebastian Redlc4704762008-11-11 11:37:55 +000032// CXXTypeidExpr - has child iterators if the operand is an expression
33Stmt::child_iterator CXXTypeidExpr::child_begin() {
Douglas Gregor9da64192010-04-26 22:37:10 +000034 return isTypeOperand() ? child_iterator()
35 : reinterpret_cast<Stmt **>(&Operand);
Sebastian Redlc4704762008-11-11 11:37:55 +000036}
37Stmt::child_iterator CXXTypeidExpr::child_end() {
Douglas Gregor9da64192010-04-26 22:37:10 +000038 return isTypeOperand() ? child_iterator()
39 : reinterpret_cast<Stmt **>(&Operand) + 1;
Sebastian Redlc4704762008-11-11 11:37:55 +000040}
Ted Kremeneke3a0c142007-08-24 20:21:10 +000041
Francois Pichet9f4f2072010-09-08 12:20:18 +000042QualType CXXUuidofExpr::getTypeOperand() const {
43 assert(isTypeOperand() && "Cannot call getTypeOperand for __uuidof(expr)");
44 return Operand.get<TypeSourceInfo *>()->getType().getNonReferenceType()
45 .getUnqualifiedType();
46}
47
48// CXXUuidofExpr - has child iterators if the operand is an expression
49Stmt::child_iterator CXXUuidofExpr::child_begin() {
50 return isTypeOperand() ? child_iterator()
51 : reinterpret_cast<Stmt **>(&Operand);
52}
53Stmt::child_iterator CXXUuidofExpr::child_end() {
54 return isTypeOperand() ? child_iterator()
55 : reinterpret_cast<Stmt **>(&Operand) + 1;
56}
57
Ted Kremeneke3a0c142007-08-24 20:21:10 +000058// CXXBoolLiteralExpr
Mike Stump11289f42009-09-09 15:08:12 +000059Stmt::child_iterator CXXBoolLiteralExpr::child_begin() {
Ted Kremenek04746ce2007-10-18 23:28:49 +000060 return child_iterator();
61}
62Stmt::child_iterator CXXBoolLiteralExpr::child_end() {
63 return child_iterator();
64}
Chris Lattnerb7e656b2008-02-26 00:51:44 +000065
Sebastian Redl576fd422009-05-10 18:38:11 +000066// CXXNullPtrLiteralExpr
Mike Stump11289f42009-09-09 15:08:12 +000067Stmt::child_iterator CXXNullPtrLiteralExpr::child_begin() {
Sebastian Redl576fd422009-05-10 18:38:11 +000068 return child_iterator();
69}
70Stmt::child_iterator CXXNullPtrLiteralExpr::child_end() {
71 return child_iterator();
72}
73
Douglas Gregor97a9c812008-11-04 14:32:21 +000074// CXXThisExpr
75Stmt::child_iterator CXXThisExpr::child_begin() { return child_iterator(); }
76Stmt::child_iterator CXXThisExpr::child_end() { return child_iterator(); }
77
Chris Lattnerb7e656b2008-02-26 00:51:44 +000078// CXXThrowExpr
Ted Kremenekc6501db2008-06-17 03:11:08 +000079Stmt::child_iterator CXXThrowExpr::child_begin() { return &Op; }
Chris Lattnerb7e656b2008-02-26 00:51:44 +000080Stmt::child_iterator CXXThrowExpr::child_end() {
81 // If Op is 0, we are processing throw; which has no children.
Ted Kremenekc6501db2008-06-17 03:11:08 +000082 return Op ? &Op+1 : &Op;
Chris Lattnerb7e656b2008-02-26 00:51:44 +000083}
Chris Lattneraa9c7ae2008-04-08 04:40:51 +000084
85// CXXDefaultArgExpr
86Stmt::child_iterator CXXDefaultArgExpr::child_begin() {
Chris Lattner58258242008-04-10 02:22:51 +000087 return child_iterator();
Chris Lattneraa9c7ae2008-04-08 04:40:51 +000088}
89Stmt::child_iterator CXXDefaultArgExpr::child_end() {
Chris Lattner58258242008-04-10 02:22:51 +000090 return child_iterator();
Chris Lattneraa9c7ae2008-04-08 04:40:51 +000091}
Argyrios Kyrtzidis857fcc22008-08-22 15:38:55 +000092
Douglas Gregor747eb782010-07-08 06:14:04 +000093// CXXScalarValueInitExpr
Douglas Gregor2b88c112010-09-08 00:15:04 +000094SourceRange CXXScalarValueInitExpr::getSourceRange() const {
95 SourceLocation Start = RParenLoc;
96 if (TypeInfo)
97 Start = TypeInfo->getTypeLoc().getBeginLoc();
98 return SourceRange(Start, RParenLoc);
99}
100
Douglas Gregor747eb782010-07-08 06:14:04 +0000101Stmt::child_iterator CXXScalarValueInitExpr::child_begin() {
Argyrios Kyrtzidis857fcc22008-08-22 15:38:55 +0000102 return child_iterator();
103}
Douglas Gregor747eb782010-07-08 06:14:04 +0000104Stmt::child_iterator CXXScalarValueInitExpr::child_end() {
Argyrios Kyrtzidis857fcc22008-08-22 15:38:55 +0000105 return child_iterator();
106}
Argyrios Kyrtzidisaa479132008-09-09 23:47:53 +0000107
Sebastian Redlbd150f42008-11-21 19:14:01 +0000108// CXXNewExpr
Ted Kremenek9d6eb402010-02-11 22:51:03 +0000109CXXNewExpr::CXXNewExpr(ASTContext &C, bool globalNew, FunctionDecl *operatorNew,
Sebastian Redlbd150f42008-11-21 19:14:01 +0000110 Expr **placementArgs, unsigned numPlaceArgs,
Douglas Gregorf2753b32010-07-13 15:54:32 +0000111 SourceRange TypeIdParens, Expr *arraySize,
Sebastian Redlbd150f42008-11-21 19:14:01 +0000112 CXXConstructorDecl *constructor, bool initializer,
113 Expr **constructorArgs, unsigned numConsArgs,
114 FunctionDecl *operatorDelete, QualType ty,
Douglas Gregor0744ef62010-09-07 21:49:58 +0000115 TypeSourceInfo *AllocatedTypeInfo,
Sebastian Redlbd150f42008-11-21 19:14:01 +0000116 SourceLocation startLoc, SourceLocation endLoc)
Sebastian Redl8d2ccae2009-02-26 14:39:58 +0000117 : Expr(CXXNewExprClass, ty, ty->isDependentType(), ty->isDependentType()),
Douglas Gregorf2753b32010-07-13 15:54:32 +0000118 GlobalNew(globalNew),
Chris Lattnerabfb58d2010-05-10 01:22:27 +0000119 Initializer(initializer), SubExprs(0), OperatorNew(operatorNew),
Sebastian Redl351bb782008-12-02 14:43:59 +0000120 OperatorDelete(operatorDelete), Constructor(constructor),
Douglas Gregor0744ef62010-09-07 21:49:58 +0000121 AllocatedTypeInfo(AllocatedTypeInfo), TypeIdParens(TypeIdParens),
122 StartLoc(startLoc), EndLoc(endLoc) {
Chris Lattnerabfb58d2010-05-10 01:22:27 +0000123
124 AllocateArgsArray(C, arraySize != 0, numPlaceArgs, numConsArgs);
Sebastian Redlbd150f42008-11-21 19:14:01 +0000125 unsigned i = 0;
Sebastian Redl351bb782008-12-02 14:43:59 +0000126 if (Array)
127 SubExprs[i++] = arraySize;
128 for (unsigned j = 0; j < NumPlacementArgs; ++j)
Sebastian Redlbd150f42008-11-21 19:14:01 +0000129 SubExprs[i++] = placementArgs[j];
Sebastian Redl351bb782008-12-02 14:43:59 +0000130 for (unsigned j = 0; j < NumConstructorArgs; ++j)
Sebastian Redlbd150f42008-11-21 19:14:01 +0000131 SubExprs[i++] = constructorArgs[j];
Sebastian Redlbd150f42008-11-21 19:14:01 +0000132}
133
Chris Lattnerabfb58d2010-05-10 01:22:27 +0000134void CXXNewExpr::AllocateArgsArray(ASTContext &C, bool isArray,
135 unsigned numPlaceArgs, unsigned numConsArgs){
136 assert(SubExprs == 0 && "SubExprs already allocated");
137 Array = isArray;
138 NumPlacementArgs = numPlaceArgs;
139 NumConstructorArgs = numConsArgs;
140
141 unsigned TotalSize = Array + NumPlacementArgs + NumConstructorArgs;
142 SubExprs = new (C) Stmt*[TotalSize];
143}
144
145
Sebastian Redlbd150f42008-11-21 19:14:01 +0000146Stmt::child_iterator CXXNewExpr::child_begin() { return &SubExprs[0]; }
147Stmt::child_iterator CXXNewExpr::child_end() {
Sebastian Redl351bb782008-12-02 14:43:59 +0000148 return &SubExprs[0] + Array + getNumPlacementArgs() + getNumConstructorArgs();
Sebastian Redlbd150f42008-11-21 19:14:01 +0000149}
150
151// CXXDeleteExpr
152Stmt::child_iterator CXXDeleteExpr::child_begin() { return &Argument; }
153Stmt::child_iterator CXXDeleteExpr::child_end() { return &Argument+1; }
154
Douglas Gregorad8a3362009-09-04 17:36:40 +0000155// CXXPseudoDestructorExpr
156Stmt::child_iterator CXXPseudoDestructorExpr::child_begin() { return &Base; }
157Stmt::child_iterator CXXPseudoDestructorExpr::child_end() {
158 return &Base + 1;
159}
160
Douglas Gregor678f90d2010-02-25 01:56:36 +0000161PseudoDestructorTypeStorage::PseudoDestructorTypeStorage(TypeSourceInfo *Info)
162 : Type(Info)
163{
Abramo Bagnara1108e7b2010-05-20 10:00:11 +0000164 Location = Info->getTypeLoc().getLocalSourceRange().getBegin();
Douglas Gregor678f90d2010-02-25 01:56:36 +0000165}
166
167QualType CXXPseudoDestructorExpr::getDestroyedType() const {
168 if (TypeSourceInfo *TInfo = DestroyedType.getTypeSourceInfo())
169 return TInfo->getType();
170
171 return QualType();
172}
173
Douglas Gregor651fe5e2010-02-24 23:40:28 +0000174SourceRange CXXPseudoDestructorExpr::getSourceRange() const {
Douglas Gregor678f90d2010-02-25 01:56:36 +0000175 SourceLocation End = DestroyedType.getLocation();
176 if (TypeSourceInfo *TInfo = DestroyedType.getTypeSourceInfo())
Abramo Bagnara1108e7b2010-05-20 10:00:11 +0000177 End = TInfo->getTypeLoc().getLocalSourceRange().getEnd();
Douglas Gregor678f90d2010-02-25 01:56:36 +0000178 return SourceRange(Base->getLocStart(), End);
Douglas Gregor651fe5e2010-02-24 23:40:28 +0000179}
180
181
John McCalld14a8642009-11-21 08:51:07 +0000182// UnresolvedLookupExpr
John McCalle66edc12009-11-24 19:00:30 +0000183UnresolvedLookupExpr *
184UnresolvedLookupExpr::Create(ASTContext &C, bool Dependent,
John McCall58cc69d2010-01-27 01:50:18 +0000185 CXXRecordDecl *NamingClass,
John McCalle66edc12009-11-24 19:00:30 +0000186 NestedNameSpecifier *Qualifier,
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000187 SourceRange QualifierRange,
188 const DeclarationNameInfo &NameInfo,
189 bool ADL,
Douglas Gregor30a4f4c2010-05-23 18:57:34 +0000190 const TemplateArgumentListInfo &Args,
191 UnresolvedSetIterator Begin,
192 UnresolvedSetIterator End)
John McCalle66edc12009-11-24 19:00:30 +0000193{
194 void *Mem = C.Allocate(sizeof(UnresolvedLookupExpr) +
195 ExplicitTemplateArgumentList::sizeFor(Args));
196 UnresolvedLookupExpr *ULE
Douglas Gregorc69978f2010-05-23 19:36:40 +0000197 = new (Mem) UnresolvedLookupExpr(C,
198 Dependent ? C.DependentTy : C.OverloadTy,
John McCall58cc69d2010-01-27 01:50:18 +0000199 Dependent, NamingClass,
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000200 Qualifier, QualifierRange, NameInfo,
201 ADL,
John McCalle66edc12009-11-24 19:00:30 +0000202 /*Overload*/ true,
Douglas Gregor30a4f4c2010-05-23 18:57:34 +0000203 /*ExplicitTemplateArgs*/ true,
204 Begin, End);
John McCalle66edc12009-11-24 19:00:30 +0000205
206 reinterpret_cast<ExplicitTemplateArgumentList*>(ULE+1)->initializeFrom(Args);
207
208 return ULE;
209}
210
Argyrios Kyrtzidis58e01ad2010-06-25 09:03:34 +0000211UnresolvedLookupExpr *
212UnresolvedLookupExpr::CreateEmpty(ASTContext &C, unsigned NumTemplateArgs) {
213 std::size_t size = sizeof(UnresolvedLookupExpr);
214 if (NumTemplateArgs != 0)
215 size += ExplicitTemplateArgumentList::sizeFor(NumTemplateArgs);
216
217 void *Mem = C.Allocate(size, llvm::alignof<UnresolvedLookupExpr>());
218 UnresolvedLookupExpr *E = new (Mem) UnresolvedLookupExpr(EmptyShell());
219 E->HasExplicitTemplateArgs = NumTemplateArgs != 0;
220 return E;
221}
222
Douglas Gregorc69978f2010-05-23 19:36:40 +0000223OverloadExpr::OverloadExpr(StmtClass K, ASTContext &C, QualType T,
224 bool Dependent, NestedNameSpecifier *Qualifier,
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000225 SourceRange QRange,
226 const DeclarationNameInfo &NameInfo,
227 bool HasTemplateArgs,
Douglas Gregorc69978f2010-05-23 19:36:40 +0000228 UnresolvedSetIterator Begin,
229 UnresolvedSetIterator End)
230 : Expr(K, T, Dependent, Dependent),
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000231 Results(0), NumResults(0), NameInfo(NameInfo), Qualifier(Qualifier),
232 QualifierRange(QRange), HasExplicitTemplateArgs(HasTemplateArgs)
Douglas Gregorc69978f2010-05-23 19:36:40 +0000233{
Argyrios Kyrtzidisb8d3c632010-06-25 09:03:26 +0000234 initializeResults(C, Begin, End);
235}
236
237void OverloadExpr::initializeResults(ASTContext &C,
238 UnresolvedSetIterator Begin,
239 UnresolvedSetIterator End) {
240 assert(Results == 0 && "Results already initialized!");
241 NumResults = End - Begin;
Douglas Gregorc69978f2010-05-23 19:36:40 +0000242 if (NumResults) {
243 Results = static_cast<DeclAccessPair *>(
244 C.Allocate(sizeof(DeclAccessPair) * NumResults,
245 llvm::alignof<DeclAccessPair>()));
246 memcpy(Results, &*Begin.getIterator(),
Argyrios Kyrtzidisb8d3c632010-06-25 09:03:26 +0000247 NumResults * sizeof(DeclAccessPair));
Douglas Gregorc69978f2010-05-23 19:36:40 +0000248 }
249}
250
Argyrios Kyrtzidisb8d3c632010-06-25 09:03:26 +0000251
John McCall1acbbb52010-02-02 06:20:04 +0000252bool OverloadExpr::ComputeDependence(UnresolvedSetIterator Begin,
253 UnresolvedSetIterator End,
254 const TemplateArgumentListInfo *Args) {
John McCallad371252010-01-20 00:46:10 +0000255 for (UnresolvedSetImpl::const_iterator I = Begin; I != End; ++I)
John McCalle66edc12009-11-24 19:00:30 +0000256 if ((*I)->getDeclContext()->isDependentContext())
257 return true;
258
259 if (Args && TemplateSpecializationType::anyDependentTemplateArguments(*Args))
260 return true;
261
262 return false;
263}
264
John McCall8c12dc42010-04-22 18:44:12 +0000265CXXRecordDecl *OverloadExpr::getNamingClass() const {
266 if (isa<UnresolvedLookupExpr>(this))
267 return cast<UnresolvedLookupExpr>(this)->getNamingClass();
268 else
269 return cast<UnresolvedMemberExpr>(this)->getNamingClass();
270}
271
John McCalld14a8642009-11-21 08:51:07 +0000272Stmt::child_iterator UnresolvedLookupExpr::child_begin() {
Mike Stump11289f42009-09-09 15:08:12 +0000273 return child_iterator();
Douglas Gregorb0846b02008-12-06 00:22:45 +0000274}
John McCalld14a8642009-11-21 08:51:07 +0000275Stmt::child_iterator UnresolvedLookupExpr::child_end() {
Douglas Gregorb0846b02008-12-06 00:22:45 +0000276 return child_iterator();
277}
Sebastian Redlbaad4e72009-01-05 20:52:13 +0000278// UnaryTypeTraitExpr
279Stmt::child_iterator UnaryTypeTraitExpr::child_begin() {
280 return child_iterator();
281}
282Stmt::child_iterator UnaryTypeTraitExpr::child_end() {
283 return child_iterator();
284}
285
John McCall8cd78132009-11-19 22:55:06 +0000286// DependentScopeDeclRefExpr
John McCalle66edc12009-11-24 19:00:30 +0000287DependentScopeDeclRefExpr *
288DependentScopeDeclRefExpr::Create(ASTContext &C,
289 NestedNameSpecifier *Qualifier,
290 SourceRange QualifierRange,
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000291 const DeclarationNameInfo &NameInfo,
John McCalle66edc12009-11-24 19:00:30 +0000292 const TemplateArgumentListInfo *Args) {
293 std::size_t size = sizeof(DependentScopeDeclRefExpr);
294 if (Args) size += ExplicitTemplateArgumentList::sizeFor(*Args);
295 void *Mem = C.Allocate(size);
296
297 DependentScopeDeclRefExpr *DRE
298 = new (Mem) DependentScopeDeclRefExpr(C.DependentTy,
299 Qualifier, QualifierRange,
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000300 NameInfo, Args != 0);
John McCalle66edc12009-11-24 19:00:30 +0000301
302 if (Args)
303 reinterpret_cast<ExplicitTemplateArgumentList*>(DRE+1)
304 ->initializeFrom(*Args);
305
306 return DRE;
307}
308
Argyrios Kyrtzidiscd444d1a2010-06-28 09:31:56 +0000309DependentScopeDeclRefExpr *
310DependentScopeDeclRefExpr::CreateEmpty(ASTContext &C,
311 unsigned NumTemplateArgs) {
312 std::size_t size = sizeof(DependentScopeDeclRefExpr);
313 if (NumTemplateArgs)
314 size += ExplicitTemplateArgumentList::sizeFor(NumTemplateArgs);
315 void *Mem = C.Allocate(size);
316
317 return new (Mem) DependentScopeDeclRefExpr(QualType(), 0, SourceRange(),
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000318 DeclarationNameInfo(),
Argyrios Kyrtzidiscd444d1a2010-06-28 09:31:56 +0000319 NumTemplateArgs != 0);
320}
321
John McCall8cd78132009-11-19 22:55:06 +0000322StmtIterator DependentScopeDeclRefExpr::child_begin() {
Douglas Gregor90a1a652009-03-19 17:26:29 +0000323 return child_iterator();
324}
325
John McCall8cd78132009-11-19 22:55:06 +0000326StmtIterator DependentScopeDeclRefExpr::child_end() {
Douglas Gregor90a1a652009-03-19 17:26:29 +0000327 return child_iterator();
328}
329
Douglas Gregor79f83ed2009-07-23 23:49:00 +0000330bool UnaryTypeTraitExpr::EvaluateTrait(ASTContext& C) const {
Douglas Gregor54e5b132010-09-09 16:14:44 +0000331 QualType T = getQueriedType();
Sebastian Redlbaad4e72009-01-05 20:52:13 +0000332 switch(UTT) {
333 default: assert(false && "Unknown type trait or not implemented");
Douglas Gregor54e5b132010-09-09 16:14:44 +0000334 case UTT_IsPOD: return T->isPODType();
335 case UTT_IsLiteral: return T->isLiteralType();
Sebastian Redlbaad4e72009-01-05 20:52:13 +0000336 case UTT_IsClass: // Fallthrough
337 case UTT_IsUnion:
Douglas Gregor54e5b132010-09-09 16:14:44 +0000338 if (const RecordType *Record = T->getAs<RecordType>()) {
Sebastian Redlbaad4e72009-01-05 20:52:13 +0000339 bool Union = Record->getDecl()->isUnion();
340 return UTT == UTT_IsUnion ? Union : !Union;
341 }
342 return false;
Douglas Gregor54e5b132010-09-09 16:14:44 +0000343 case UTT_IsEnum: return T->isEnumeralType();
Sebastian Redlbaad4e72009-01-05 20:52:13 +0000344 case UTT_IsPolymorphic:
Douglas Gregor54e5b132010-09-09 16:14:44 +0000345 if (const RecordType *Record = T->getAs<RecordType>()) {
Sebastian Redlbaad4e72009-01-05 20:52:13 +0000346 // Type traits are only parsed in C++, so we've got CXXRecords.
347 return cast<CXXRecordDecl>(Record->getDecl())->isPolymorphic();
348 }
349 return false;
Anders Carlsson7cbd8fb2009-03-22 01:52:17 +0000350 case UTT_IsAbstract:
Douglas Gregor54e5b132010-09-09 16:14:44 +0000351 if (const RecordType *RT = T->getAs<RecordType>())
Anders Carlsson7cbd8fb2009-03-22 01:52:17 +0000352 return cast<CXXRecordDecl>(RT->getDecl())->isAbstract();
353 return false;
Eli Friedmanc96d4962009-08-15 21:55:26 +0000354 case UTT_IsEmpty:
Douglas Gregor54e5b132010-09-09 16:14:44 +0000355 if (const RecordType *Record = T->getAs<RecordType>()) {
Eli Friedmanc96d4962009-08-15 21:55:26 +0000356 return !Record->getDecl()->isUnion()
357 && cast<CXXRecordDecl>(Record->getDecl())->isEmpty();
358 }
359 return false;
Anders Carlssonfe63dc52009-04-16 00:08:20 +0000360 case UTT_HasTrivialConstructor:
Douglas Gregor79f83ed2009-07-23 23:49:00 +0000361 // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
362 // If __is_pod (type) is true then the trait is true, else if type is
363 // a cv class or union type (or array thereof) with a trivial default
364 // constructor ([class.ctor]) then the trait is true, else it is false.
Douglas Gregor54e5b132010-09-09 16:14:44 +0000365 if (T->isPODType())
Douglas Gregor79f83ed2009-07-23 23:49:00 +0000366 return true;
367 if (const RecordType *RT =
Douglas Gregor54e5b132010-09-09 16:14:44 +0000368 C.getBaseElementType(T)->getAs<RecordType>())
Anders Carlssonfe63dc52009-04-16 00:08:20 +0000369 return cast<CXXRecordDecl>(RT->getDecl())->hasTrivialConstructor();
Anders Carlsson6dc35752009-04-17 02:34:54 +0000370 return false;
Douglas Gregor79f83ed2009-07-23 23:49:00 +0000371 case UTT_HasTrivialCopy:
372 // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
373 // If __is_pod (type) is true or type is a reference type then
374 // the trait is true, else if type is a cv class or union type
375 // with a trivial copy constructor ([class.copy]) then the trait
376 // is true, else it is false.
Douglas Gregor54e5b132010-09-09 16:14:44 +0000377 if (T->isPODType() || T->isReferenceType())
Douglas Gregor79f83ed2009-07-23 23:49:00 +0000378 return true;
Douglas Gregor54e5b132010-09-09 16:14:44 +0000379 if (const RecordType *RT = T->getAs<RecordType>())
Douglas Gregor79f83ed2009-07-23 23:49:00 +0000380 return cast<CXXRecordDecl>(RT->getDecl())->hasTrivialCopyConstructor();
381 return false;
382 case UTT_HasTrivialAssign:
383 // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
384 // If type is const qualified or is a reference type then the
385 // trait is false. Otherwise if __is_pod (type) is true then the
386 // trait is true, else if type is a cv class or union type with
387 // a trivial copy assignment ([class.copy]) then the trait is
388 // true, else it is false.
389 // Note: the const and reference restrictions are interesting,
390 // given that const and reference members don't prevent a class
391 // from having a trivial copy assignment operator (but do cause
392 // errors if the copy assignment operator is actually used, q.v.
393 // [class.copy]p12).
394
Douglas Gregor54e5b132010-09-09 16:14:44 +0000395 if (C.getBaseElementType(T).isConstQualified())
Douglas Gregor79f83ed2009-07-23 23:49:00 +0000396 return false;
Douglas Gregor54e5b132010-09-09 16:14:44 +0000397 if (T->isPODType())
Douglas Gregor79f83ed2009-07-23 23:49:00 +0000398 return true;
Douglas Gregor54e5b132010-09-09 16:14:44 +0000399 if (const RecordType *RT = T->getAs<RecordType>())
Douglas Gregor79f83ed2009-07-23 23:49:00 +0000400 return cast<CXXRecordDecl>(RT->getDecl())->hasTrivialCopyAssignment();
401 return false;
402 case UTT_HasTrivialDestructor:
403 // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
404 // If __is_pod (type) is true or type is a reference type
405 // then the trait is true, else if type is a cv class or union
406 // type (or array thereof) with a trivial destructor
407 // ([class.dtor]) then the trait is true, else it is
408 // false.
Douglas Gregor54e5b132010-09-09 16:14:44 +0000409 if (T->isPODType() || T->isReferenceType())
Douglas Gregor79f83ed2009-07-23 23:49:00 +0000410 return true;
411 if (const RecordType *RT =
Douglas Gregor54e5b132010-09-09 16:14:44 +0000412 C.getBaseElementType(T)->getAs<RecordType>())
Anders Carlsson6dc35752009-04-17 02:34:54 +0000413 return cast<CXXRecordDecl>(RT->getDecl())->hasTrivialDestructor();
414 return false;
Sebastian Redl7dcb1552010-08-31 04:59:00 +0000415 // TODO: Propagate nothrowness for implicitly declared special members.
416 case UTT_HasNothrowAssign:
417 // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
418 // If type is const qualified or is a reference type then the
419 // trait is false. Otherwise if __has_trivial_assign (type)
420 // is true then the trait is true, else if type is a cv class
421 // or union type with copy assignment operators that are known
422 // not to throw an exception then the trait is true, else it is
423 // false.
Douglas Gregor54e5b132010-09-09 16:14:44 +0000424 if (C.getBaseElementType(T).isConstQualified())
Sebastian Redl7dcb1552010-08-31 04:59:00 +0000425 return false;
Douglas Gregor54e5b132010-09-09 16:14:44 +0000426 if (T->isReferenceType())
Sebastian Redl7dcb1552010-08-31 04:59:00 +0000427 return false;
Douglas Gregor54e5b132010-09-09 16:14:44 +0000428 if (T->isPODType())
Sebastian Redl7dcb1552010-08-31 04:59:00 +0000429 return true;
Douglas Gregor54e5b132010-09-09 16:14:44 +0000430 if (const RecordType *RT = T->getAs<RecordType>()) {
Sebastian Redl7dcb1552010-08-31 04:59:00 +0000431 CXXRecordDecl* RD = cast<CXXRecordDecl>(RT->getDecl());
432 if (RD->hasTrivialCopyAssignment())
433 return true;
434
435 bool FoundAssign = false;
436 bool AllNoThrow = true;
437 DeclarationName Name = C.DeclarationNames.getCXXOperatorName(OO_Equal);
438 DeclContext::lookup_const_iterator Op, OpEnd;
439 for (llvm::tie(Op, OpEnd) = RD->lookup(Name);
440 Op != OpEnd; ++Op) {
441 CXXMethodDecl *Operator = cast<CXXMethodDecl>(*Op);
442 if (Operator->isCopyAssignmentOperator()) {
443 FoundAssign = true;
444 const FunctionProtoType *CPT
445 = Operator->getType()->getAs<FunctionProtoType>();
446 if (!CPT->hasEmptyExceptionSpec()) {
447 AllNoThrow = false;
448 break;
449 }
450 }
451 }
452
453 return FoundAssign && AllNoThrow;
454 }
455 return false;
456 case UTT_HasNothrowCopy:
457 // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
458 // If __has_trivial_copy (type) is true then the trait is true, else
459 // if type is a cv class or union type with copy constructors that are
460 // known not to throw an exception then the trait is true, else it is
461 // false.
Douglas Gregor54e5b132010-09-09 16:14:44 +0000462 if (T->isPODType() || T->isReferenceType())
Sebastian Redl7dcb1552010-08-31 04:59:00 +0000463 return true;
Douglas Gregor54e5b132010-09-09 16:14:44 +0000464 if (const RecordType *RT = T->getAs<RecordType>()) {
Sebastian Redl7dcb1552010-08-31 04:59:00 +0000465 CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
466 if (RD->hasTrivialCopyConstructor())
467 return true;
468
469 bool FoundConstructor = false;
470 bool AllNoThrow = true;
471 unsigned FoundTQs;
472 DeclarationName ConstructorName
Douglas Gregor54e5b132010-09-09 16:14:44 +0000473 = C.DeclarationNames.getCXXConstructorName(C.getCanonicalType(T));
Sebastian Redl7dcb1552010-08-31 04:59:00 +0000474 DeclContext::lookup_const_iterator Con, ConEnd;
475 for (llvm::tie(Con, ConEnd) = RD->lookup(ConstructorName);
476 Con != ConEnd; ++Con) {
477 CXXConstructorDecl *Constructor = cast<CXXConstructorDecl>(*Con);
478 if (Constructor->isCopyConstructor(FoundTQs)) {
479 FoundConstructor = true;
480 const FunctionProtoType *CPT
481 = Constructor->getType()->getAs<FunctionProtoType>();
482 if (!CPT->hasEmptyExceptionSpec()) {
483 AllNoThrow = false;
484 break;
485 }
486 }
487 }
488
489 return FoundConstructor && AllNoThrow;
490 }
491 return false;
492 case UTT_HasNothrowConstructor:
493 // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
494 // If __has_trivial_constructor (type) is true then the trait is
495 // true, else if type is a cv class or union type (or array
496 // thereof) with a default constructor that is known not to
497 // throw an exception then the trait is true, else it is false.
Douglas Gregor54e5b132010-09-09 16:14:44 +0000498 if (T->isPODType())
Sebastian Redl7dcb1552010-08-31 04:59:00 +0000499 return true;
Douglas Gregor54e5b132010-09-09 16:14:44 +0000500 if (const RecordType *RT = C.getBaseElementType(T)->getAs<RecordType>()) {
Sebastian Redl7dcb1552010-08-31 04:59:00 +0000501 CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
502 if (RD->hasTrivialConstructor())
503 return true;
504
505 if (CXXConstructorDecl *Constructor = RD->getDefaultConstructor()) {
506 const FunctionProtoType *CPT
507 = Constructor->getType()->getAs<FunctionProtoType>();
508 // TODO: check whether evaluating default arguments can throw.
509 // For now, we'll be conservative and assume that they can throw.
510 if (CPT->hasEmptyExceptionSpec() && CPT->getNumArgs() == 0)
511 return true;
512 }
513 }
514 return false;
Sebastian Redlb469afb2010-09-02 23:19:42 +0000515 case UTT_HasVirtualDestructor:
516 // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
517 // If type is a class type with a virtual destructor ([class.dtor])
518 // then the trait is true, else it is false.
Douglas Gregor54e5b132010-09-09 16:14:44 +0000519 if (const RecordType *Record = T->getAs<RecordType>()) {
Sebastian Redlb469afb2010-09-02 23:19:42 +0000520 CXXRecordDecl *RD = cast<CXXRecordDecl>(Record->getDecl());
521 if (CXXDestructorDecl *Destructor = RD->getDestructor())
522 return Destructor->isVirtual();
523 }
524 return false;
Sebastian Redlbaad4e72009-01-05 20:52:13 +0000525 }
526}
527
Ted Kremenek49ace5c2009-12-23 04:00:48 +0000528SourceRange CXXConstructExpr::getSourceRange() const {
529 // FIXME: Should we know where the parentheses are, if there are any?
530 for (std::reverse_iterator<Stmt**> I(&Args[NumArgs]), E(&Args[0]); I!=E;++I) {
531 // Ignore CXXDefaultExprs when computing the range, as they don't
532 // have a range.
533 if (!isa<CXXDefaultArgExpr>(*I))
534 return SourceRange(Loc, (*I)->getLocEnd());
535 }
536
537 return SourceRange(Loc);
538}
539
Douglas Gregor993603d2008-11-14 16:09:21 +0000540SourceRange CXXOperatorCallExpr::getSourceRange() const {
541 OverloadedOperatorKind Kind = getOperator();
542 if (Kind == OO_PlusPlus || Kind == OO_MinusMinus) {
543 if (getNumArgs() == 1)
544 // Prefix operator
Mike Stump11289f42009-09-09 15:08:12 +0000545 return SourceRange(getOperatorLoc(),
Douglas Gregor993603d2008-11-14 16:09:21 +0000546 getArg(0)->getSourceRange().getEnd());
547 else
548 // Postfix operator
549 return SourceRange(getArg(0)->getSourceRange().getEnd(),
550 getOperatorLoc());
551 } else if (Kind == OO_Call) {
552 return SourceRange(getArg(0)->getSourceRange().getBegin(), getRParenLoc());
553 } else if (Kind == OO_Subscript) {
554 return SourceRange(getArg(0)->getSourceRange().getBegin(), getRParenLoc());
555 } else if (getNumArgs() == 1) {
556 return SourceRange(getOperatorLoc(), getArg(0)->getSourceRange().getEnd());
557 } else if (getNumArgs() == 2) {
558 return SourceRange(getArg(0)->getSourceRange().getBegin(),
559 getArg(1)->getSourceRange().getEnd());
560 } else {
561 return SourceRange();
562 }
563}
564
Douglas Gregor97fd6e22008-12-22 05:46:06 +0000565Expr *CXXMemberCallExpr::getImplicitObjectArgument() {
566 if (MemberExpr *MemExpr = dyn_cast<MemberExpr>(getCallee()->IgnoreParens()))
567 return MemExpr->getBase();
568
569 // FIXME: Will eventually need to cope with member pointers.
570 return 0;
571}
572
Douglas Gregoref986e82009-11-12 15:31:47 +0000573SourceRange CXXMemberCallExpr::getSourceRange() const {
574 SourceLocation LocStart = getCallee()->getLocStart();
575 if (LocStart.isInvalid() && getNumArgs() > 0)
576 LocStart = getArg(0)->getLocStart();
577 return SourceRange(LocStart, getRParenLoc());
578}
579
580
Douglas Gregore200adc2008-10-27 19:41:14 +0000581//===----------------------------------------------------------------------===//
582// Named casts
583//===----------------------------------------------------------------------===//
584
585/// getCastName - Get the name of the C++ cast being used, e.g.,
586/// "static_cast", "dynamic_cast", "reinterpret_cast", or
587/// "const_cast". The returned pointer must not be freed.
588const char *CXXNamedCastExpr::getCastName() const {
589 switch (getStmtClass()) {
590 case CXXStaticCastExprClass: return "static_cast";
591 case CXXDynamicCastExprClass: return "dynamic_cast";
592 case CXXReinterpretCastExprClass: return "reinterpret_cast";
593 case CXXConstCastExprClass: return "const_cast";
594 default: return "<invalid cast>";
595 }
596}
Douglas Gregordd04d332009-01-16 18:33:17 +0000597
John McCallcf142162010-08-07 06:22:56 +0000598CXXStaticCastExpr *CXXStaticCastExpr::Create(ASTContext &C, QualType T,
599 CastKind K, Expr *Op,
600 const CXXCastPath *BasePath,
601 TypeSourceInfo *WrittenTy,
602 SourceLocation L) {
603 unsigned PathSize = (BasePath ? BasePath->size() : 0);
604 void *Buffer = C.Allocate(sizeof(CXXStaticCastExpr)
605 + PathSize * sizeof(CXXBaseSpecifier*));
606 CXXStaticCastExpr *E =
607 new (Buffer) CXXStaticCastExpr(T, K, Op, PathSize, WrittenTy, L);
608 if (PathSize) E->setCastPath(*BasePath);
609 return E;
610}
611
612CXXStaticCastExpr *CXXStaticCastExpr::CreateEmpty(ASTContext &C,
613 unsigned PathSize) {
614 void *Buffer =
615 C.Allocate(sizeof(CXXStaticCastExpr) + PathSize * sizeof(CXXBaseSpecifier*));
616 return new (Buffer) CXXStaticCastExpr(EmptyShell(), PathSize);
617}
618
619CXXDynamicCastExpr *CXXDynamicCastExpr::Create(ASTContext &C, QualType T,
620 CastKind K, Expr *Op,
621 const CXXCastPath *BasePath,
622 TypeSourceInfo *WrittenTy,
623 SourceLocation L) {
624 unsigned PathSize = (BasePath ? BasePath->size() : 0);
625 void *Buffer = C.Allocate(sizeof(CXXDynamicCastExpr)
626 + PathSize * sizeof(CXXBaseSpecifier*));
627 CXXDynamicCastExpr *E =
628 new (Buffer) CXXDynamicCastExpr(T, K, Op, PathSize, WrittenTy, L);
629 if (PathSize) E->setCastPath(*BasePath);
630 return E;
631}
632
633CXXDynamicCastExpr *CXXDynamicCastExpr::CreateEmpty(ASTContext &C,
634 unsigned PathSize) {
635 void *Buffer =
636 C.Allocate(sizeof(CXXDynamicCastExpr) + PathSize * sizeof(CXXBaseSpecifier*));
637 return new (Buffer) CXXDynamicCastExpr(EmptyShell(), PathSize);
638}
639
640CXXReinterpretCastExpr *
641CXXReinterpretCastExpr::Create(ASTContext &C, QualType T, CastKind K, Expr *Op,
642 const CXXCastPath *BasePath,
643 TypeSourceInfo *WrittenTy, SourceLocation L) {
644 unsigned PathSize = (BasePath ? BasePath->size() : 0);
645 void *Buffer =
646 C.Allocate(sizeof(CXXReinterpretCastExpr) + PathSize * sizeof(CXXBaseSpecifier*));
647 CXXReinterpretCastExpr *E =
648 new (Buffer) CXXReinterpretCastExpr(T, K, Op, PathSize, WrittenTy, L);
649 if (PathSize) E->setCastPath(*BasePath);
650 return E;
651}
652
653CXXReinterpretCastExpr *
654CXXReinterpretCastExpr::CreateEmpty(ASTContext &C, unsigned PathSize) {
655 void *Buffer = C.Allocate(sizeof(CXXReinterpretCastExpr)
656 + PathSize * sizeof(CXXBaseSpecifier*));
657 return new (Buffer) CXXReinterpretCastExpr(EmptyShell(), PathSize);
658}
659
660CXXConstCastExpr *CXXConstCastExpr::Create(ASTContext &C, QualType T, Expr *Op,
661 TypeSourceInfo *WrittenTy,
662 SourceLocation L) {
663 return new (C) CXXConstCastExpr(T, Op, WrittenTy, L);
664}
665
666CXXConstCastExpr *CXXConstCastExpr::CreateEmpty(ASTContext &C) {
667 return new (C) CXXConstCastExpr(EmptyShell());
668}
669
670CXXFunctionalCastExpr *
671CXXFunctionalCastExpr::Create(ASTContext &C, QualType T,
672 TypeSourceInfo *Written, SourceLocation L,
673 CastKind K, Expr *Op, const CXXCastPath *BasePath,
674 SourceLocation R) {
675 unsigned PathSize = (BasePath ? BasePath->size() : 0);
676 void *Buffer = C.Allocate(sizeof(CXXFunctionalCastExpr)
677 + PathSize * sizeof(CXXBaseSpecifier*));
678 CXXFunctionalCastExpr *E =
679 new (Buffer) CXXFunctionalCastExpr(T, Written, L, K, Op, PathSize, R);
680 if (PathSize) E->setCastPath(*BasePath);
681 return E;
682}
683
684CXXFunctionalCastExpr *
685CXXFunctionalCastExpr::CreateEmpty(ASTContext &C, unsigned PathSize) {
686 void *Buffer = C.Allocate(sizeof(CXXFunctionalCastExpr)
687 + PathSize * sizeof(CXXBaseSpecifier*));
688 return new (Buffer) CXXFunctionalCastExpr(EmptyShell(), PathSize);
689}
690
691
Douglas Gregor25ab25f2009-12-23 18:19:08 +0000692CXXDefaultArgExpr *
Douglas Gregor033f6752009-12-23 23:03:06 +0000693CXXDefaultArgExpr::Create(ASTContext &C, SourceLocation Loc,
694 ParmVarDecl *Param, Expr *SubExpr) {
Douglas Gregor25ab25f2009-12-23 18:19:08 +0000695 void *Mem = C.Allocate(sizeof(CXXDefaultArgExpr) + sizeof(Stmt *));
Douglas Gregor033f6752009-12-23 23:03:06 +0000696 return new (Mem) CXXDefaultArgExpr(CXXDefaultArgExprClass, Loc, Param,
697 SubExpr);
Douglas Gregor25ab25f2009-12-23 18:19:08 +0000698}
699
Mike Stump11289f42009-09-09 15:08:12 +0000700CXXTemporary *CXXTemporary::Create(ASTContext &C,
Anders Carlssonffda6062009-05-30 20:34:37 +0000701 const CXXDestructorDecl *Destructor) {
Anders Carlsson73b836b2009-05-30 22:38:53 +0000702 return new (C) CXXTemporary(Destructor);
703}
704
Mike Stump11289f42009-09-09 15:08:12 +0000705CXXBindTemporaryExpr *CXXBindTemporaryExpr::Create(ASTContext &C,
Anders Carlsson993a4b32009-05-30 20:03:25 +0000706 CXXTemporary *Temp,
707 Expr* SubExpr) {
Mike Stump11289f42009-09-09 15:08:12 +0000708 assert(SubExpr->getType()->isRecordType() &&
Anders Carlsson993a4b32009-05-30 20:03:25 +0000709 "Expression bound to a temporary must have record type!");
710
Anders Carlssonffda6062009-05-30 20:34:37 +0000711 return new (C) CXXBindTemporaryExpr(Temp, SubExpr);
Anders Carlsson993a4b32009-05-30 20:03:25 +0000712}
713
Anders Carlsson4b2434d2009-05-30 20:56:46 +0000714CXXTemporaryObjectExpr::CXXTemporaryObjectExpr(ASTContext &C,
Anders Carlsson56c5bd82009-04-24 05:23:13 +0000715 CXXConstructorDecl *Cons,
Douglas Gregor2b88c112010-09-08 00:15:04 +0000716 TypeSourceInfo *Type,
Douglas Gregordd04d332009-01-16 18:33:17 +0000717 Expr **Args,
Mike Stump11289f42009-09-09 15:08:12 +0000718 unsigned NumArgs,
Douglas Gregor199db362010-04-27 20:36:09 +0000719 SourceLocation rParenLoc,
720 bool ZeroInitialization)
Douglas Gregor2b88c112010-09-08 00:15:04 +0000721 : CXXConstructExpr(C, CXXTemporaryObjectExprClass,
722 Type->getType().getNonReferenceType(),
723 Type->getTypeLoc().getBeginLoc(),
Douglas Gregor199db362010-04-27 20:36:09 +0000724 Cons, false, Args, NumArgs, ZeroInitialization),
Douglas Gregor2b88c112010-09-08 00:15:04 +0000725 RParenLoc(rParenLoc), Type(Type) {
726}
727
728SourceRange CXXTemporaryObjectExpr::getSourceRange() const {
729 return SourceRange(Type->getTypeLoc().getBeginLoc(), RParenLoc);
Douglas Gregordd04d332009-01-16 18:33:17 +0000730}
Anders Carlsson6f287832009-04-21 02:22:11 +0000731
Mike Stump11289f42009-09-09 15:08:12 +0000732CXXConstructExpr *CXXConstructExpr::Create(ASTContext &C, QualType T,
Douglas Gregor85dabae2009-12-16 01:38:02 +0000733 SourceLocation Loc,
Anders Carlsson4b2434d2009-05-30 20:56:46 +0000734 CXXConstructorDecl *D, bool Elidable,
Douglas Gregor4f4b1862009-12-16 18:50:27 +0000735 Expr **Args, unsigned NumArgs,
Douglas Gregor7ae2d772010-01-31 09:12:51 +0000736 bool ZeroInitialization,
Anders Carlssonedea1de2010-05-02 23:53:04 +0000737 ConstructionKind ConstructKind) {
Douglas Gregor85dabae2009-12-16 01:38:02 +0000738 return new (C) CXXConstructExpr(C, CXXConstructExprClass, T, Loc, D,
Douglas Gregor7ae2d772010-01-31 09:12:51 +0000739 Elidable, Args, NumArgs, ZeroInitialization,
Anders Carlssonedea1de2010-05-02 23:53:04 +0000740 ConstructKind);
Anders Carlsson0781ce72009-04-23 02:32:43 +0000741}
742
Mike Stump11289f42009-09-09 15:08:12 +0000743CXXConstructExpr::CXXConstructExpr(ASTContext &C, StmtClass SC, QualType T,
Douglas Gregor85dabae2009-12-16 01:38:02 +0000744 SourceLocation Loc,
Anders Carlsson4b2434d2009-05-30 20:56:46 +0000745 CXXConstructorDecl *D, bool elidable,
Douglas Gregor4f4b1862009-12-16 18:50:27 +0000746 Expr **args, unsigned numargs,
Anders Carlssonbcc066b2010-05-02 22:54:08 +0000747 bool ZeroInitialization,
748 ConstructionKind ConstructKind)
Anders Carlsson32ebd292009-04-24 05:04:04 +0000749: Expr(SC, T,
Anders Carlsson0781ce72009-04-23 02:32:43 +0000750 T->isDependentType(),
751 (T->isDependentType() ||
752 CallExpr::hasAnyValueDependentArguments(args, numargs))),
Douglas Gregor4f4b1862009-12-16 18:50:27 +0000753 Constructor(D), Loc(Loc), Elidable(elidable),
Anders Carlssonbcc066b2010-05-02 22:54:08 +0000754 ZeroInitialization(ZeroInitialization), ConstructKind(ConstructKind),
755 Args(0), NumArgs(numargs)
Douglas Gregor4f4b1862009-12-16 18:50:27 +0000756{
757 if (NumArgs) {
758 Args = new (C) Stmt*[NumArgs];
759
760 for (unsigned i = 0; i != NumArgs; ++i) {
761 assert(args[i] && "NULL argument in CXXConstructExpr");
762 Args[i] = args[i];
Anders Carlsson0781ce72009-04-23 02:32:43 +0000763 }
Douglas Gregor4f4b1862009-12-16 18:50:27 +0000764 }
Anders Carlsson0781ce72009-04-23 02:32:43 +0000765}
766
Ted Kremeneka9084c12010-05-10 20:06:30 +0000767CXXExprWithTemporaries::CXXExprWithTemporaries(ASTContext &C,
768 Expr *subexpr,
Mike Stump11289f42009-09-09 15:08:12 +0000769 CXXTemporary **temps,
Anders Carlsson6e997b22009-12-15 20:51:39 +0000770 unsigned numtemps)
Chris Lattnercba86142010-05-10 00:25:06 +0000771 : Expr(CXXExprWithTemporariesClass, subexpr->getType(),
Mike Stump11289f42009-09-09 15:08:12 +0000772 subexpr->isTypeDependent(), subexpr->isValueDependent()),
Chris Lattnercba86142010-05-10 00:25:06 +0000773 SubExpr(subexpr), Temps(0), NumTemps(0) {
Chris Lattnerbc7d55d2010-05-10 00:45:12 +0000774 if (numtemps) {
Ted Kremeneka9084c12010-05-10 20:06:30 +0000775 setNumTemporaries(C, numtemps);
Chris Lattnercba86142010-05-10 00:25:06 +0000776 for (unsigned i = 0; i != numtemps; ++i)
Anders Carlssona29ded92009-05-30 21:05:25 +0000777 Temps[i] = temps[i];
Anders Carlssondefc6442009-04-24 22:47:04 +0000778 }
779}
780
Ted Kremeneka9084c12010-05-10 20:06:30 +0000781void CXXExprWithTemporaries::setNumTemporaries(ASTContext &C, unsigned N) {
Chris Lattnercba86142010-05-10 00:25:06 +0000782 assert(Temps == 0 && "Cannot resize with this");
Daniel Dunbarc8a7bdb2010-05-10 15:59:37 +0000783 NumTemps = N;
Ted Kremeneka9084c12010-05-10 20:06:30 +0000784 Temps = new (C) CXXTemporary*[NumTemps];
Chris Lattnercba86142010-05-10 00:25:06 +0000785}
786
787
Mike Stump11289f42009-09-09 15:08:12 +0000788CXXExprWithTemporaries *CXXExprWithTemporaries::Create(ASTContext &C,
Anders Carlsson73b836b2009-05-30 22:38:53 +0000789 Expr *SubExpr,
Mike Stump11289f42009-09-09 15:08:12 +0000790 CXXTemporary **Temps,
Anders Carlsson6e997b22009-12-15 20:51:39 +0000791 unsigned NumTemps) {
Ted Kremeneka9084c12010-05-10 20:06:30 +0000792 return new (C) CXXExprWithTemporaries(C, SubExpr, Temps, NumTemps);
Anders Carlsson73b836b2009-05-30 22:38:53 +0000793}
794
Anders Carlsson993a4b32009-05-30 20:03:25 +0000795// CXXBindTemporaryExpr
796Stmt::child_iterator CXXBindTemporaryExpr::child_begin() {
797 return &SubExpr;
798}
799
Mike Stump11289f42009-09-09 15:08:12 +0000800Stmt::child_iterator CXXBindTemporaryExpr::child_end() {
Anders Carlsson993a4b32009-05-30 20:03:25 +0000801 return &SubExpr + 1;
802}
803
Anders Carlsson0781ce72009-04-23 02:32:43 +0000804// CXXConstructExpr
805Stmt::child_iterator CXXConstructExpr::child_begin() {
806 return &Args[0];
807}
808Stmt::child_iterator CXXConstructExpr::child_end() {
809 return &Args[0]+NumArgs;
810}
811
Anders Carlssonaa10d652009-05-01 22:21:22 +0000812// CXXExprWithTemporaries
813Stmt::child_iterator CXXExprWithTemporaries::child_begin() {
814 return &SubExpr;
Anders Carlsson6f287832009-04-21 02:22:11 +0000815}
Anders Carlssondefc6442009-04-24 22:47:04 +0000816
Mike Stump11289f42009-09-09 15:08:12 +0000817Stmt::child_iterator CXXExprWithTemporaries::child_end() {
Anders Carlssonaa10d652009-05-01 22:21:22 +0000818 return &SubExpr + 1;
819}
Anders Carlssondefc6442009-04-24 22:47:04 +0000820
Douglas Gregor2b88c112010-09-08 00:15:04 +0000821CXXUnresolvedConstructExpr::CXXUnresolvedConstructExpr(TypeSourceInfo *Type,
Douglas Gregorce934142009-05-20 18:46:25 +0000822 SourceLocation LParenLoc,
823 Expr **Args,
824 unsigned NumArgs,
825 SourceLocation RParenLoc)
Douglas Gregor2b88c112010-09-08 00:15:04 +0000826 : Expr(CXXUnresolvedConstructExprClass,
827 Type->getType().getNonReferenceType(),
828 Type->getType()->isDependentType(), true),
829 Type(Type),
Douglas Gregorce934142009-05-20 18:46:25 +0000830 LParenLoc(LParenLoc),
831 RParenLoc(RParenLoc),
832 NumArgs(NumArgs) {
833 Stmt **StoredArgs = reinterpret_cast<Stmt **>(this + 1);
834 memcpy(StoredArgs, Args, sizeof(Expr *) * NumArgs);
835}
836
837CXXUnresolvedConstructExpr *
Mike Stump11289f42009-09-09 15:08:12 +0000838CXXUnresolvedConstructExpr::Create(ASTContext &C,
Douglas Gregor2b88c112010-09-08 00:15:04 +0000839 TypeSourceInfo *Type,
Douglas Gregorce934142009-05-20 18:46:25 +0000840 SourceLocation LParenLoc,
841 Expr **Args,
842 unsigned NumArgs,
843 SourceLocation RParenLoc) {
844 void *Mem = C.Allocate(sizeof(CXXUnresolvedConstructExpr) +
845 sizeof(Expr *) * NumArgs);
Douglas Gregor2b88c112010-09-08 00:15:04 +0000846 return new (Mem) CXXUnresolvedConstructExpr(Type, LParenLoc,
Douglas Gregorce934142009-05-20 18:46:25 +0000847 Args, NumArgs, RParenLoc);
848}
849
Argyrios Kyrtzidisbfcacee2010-06-24 08:57:31 +0000850CXXUnresolvedConstructExpr *
851CXXUnresolvedConstructExpr::CreateEmpty(ASTContext &C, unsigned NumArgs) {
852 Stmt::EmptyShell Empty;
853 void *Mem = C.Allocate(sizeof(CXXUnresolvedConstructExpr) +
854 sizeof(Expr *) * NumArgs);
855 return new (Mem) CXXUnresolvedConstructExpr(Empty, NumArgs);
856}
857
Douglas Gregor2b88c112010-09-08 00:15:04 +0000858SourceRange CXXUnresolvedConstructExpr::getSourceRange() const {
859 return SourceRange(Type->getTypeLoc().getBeginLoc(), RParenLoc);
860}
861
Douglas Gregorce934142009-05-20 18:46:25 +0000862Stmt::child_iterator CXXUnresolvedConstructExpr::child_begin() {
863 return child_iterator(reinterpret_cast<Stmt **>(this + 1));
864}
865
866Stmt::child_iterator CXXUnresolvedConstructExpr::child_end() {
867 return child_iterator(reinterpret_cast<Stmt **>(this + 1) + NumArgs);
868}
Sebastian Redle769ecf2009-05-16 18:50:46 +0000869
John McCall8cd78132009-11-19 22:55:06 +0000870CXXDependentScopeMemberExpr::CXXDependentScopeMemberExpr(ASTContext &C,
John McCall2d74de92009-12-01 22:10:20 +0000871 Expr *Base, QualType BaseType,
872 bool IsArrow,
Douglas Gregor308047d2009-09-09 00:23:06 +0000873 SourceLocation OperatorLoc,
874 NestedNameSpecifier *Qualifier,
875 SourceRange QualifierRange,
876 NamedDecl *FirstQualifierFoundInScope,
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000877 DeclarationNameInfo MemberNameInfo,
John McCall6b51f282009-11-23 01:53:49 +0000878 const TemplateArgumentListInfo *TemplateArgs)
John McCall8cd78132009-11-19 22:55:06 +0000879 : Expr(CXXDependentScopeMemberExprClass, C.DependentTy, true, true),
John McCall2d74de92009-12-01 22:10:20 +0000880 Base(Base), BaseType(BaseType), IsArrow(IsArrow),
881 HasExplicitTemplateArgs(TemplateArgs != 0),
Douglas Gregor308047d2009-09-09 00:23:06 +0000882 OperatorLoc(OperatorLoc),
883 Qualifier(Qualifier), QualifierRange(QualifierRange),
884 FirstQualifierFoundInScope(FirstQualifierFoundInScope),
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000885 MemberNameInfo(MemberNameInfo) {
John McCall6b51f282009-11-23 01:53:49 +0000886 if (TemplateArgs)
John McCallb3774b52010-08-19 23:49:38 +0000887 getExplicitTemplateArgs().initializeFrom(*TemplateArgs);
Douglas Gregor308047d2009-09-09 00:23:06 +0000888}
889
John McCall8cd78132009-11-19 22:55:06 +0000890CXXDependentScopeMemberExpr *
891CXXDependentScopeMemberExpr::Create(ASTContext &C,
John McCall2d74de92009-12-01 22:10:20 +0000892 Expr *Base, QualType BaseType, bool IsArrow,
Douglas Gregor308047d2009-09-09 00:23:06 +0000893 SourceLocation OperatorLoc,
894 NestedNameSpecifier *Qualifier,
895 SourceRange QualifierRange,
896 NamedDecl *FirstQualifierFoundInScope,
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000897 DeclarationNameInfo MemberNameInfo,
John McCall6b51f282009-11-23 01:53:49 +0000898 const TemplateArgumentListInfo *TemplateArgs) {
899 if (!TemplateArgs)
John McCall2d74de92009-12-01 22:10:20 +0000900 return new (C) CXXDependentScopeMemberExpr(C, Base, BaseType,
901 IsArrow, OperatorLoc,
902 Qualifier, QualifierRange,
903 FirstQualifierFoundInScope,
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000904 MemberNameInfo);
Mike Stump11289f42009-09-09 15:08:12 +0000905
John McCall6b51f282009-11-23 01:53:49 +0000906 std::size_t size = sizeof(CXXDependentScopeMemberExpr);
907 if (TemplateArgs)
908 size += ExplicitTemplateArgumentList::sizeFor(*TemplateArgs);
909
910 void *Mem = C.Allocate(size, llvm::alignof<CXXDependentScopeMemberExpr>());
John McCall2d74de92009-12-01 22:10:20 +0000911 return new (Mem) CXXDependentScopeMemberExpr(C, Base, BaseType,
912 IsArrow, OperatorLoc,
913 Qualifier, QualifierRange,
914 FirstQualifierFoundInScope,
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000915 MemberNameInfo, TemplateArgs);
Douglas Gregor308047d2009-09-09 00:23:06 +0000916}
917
Argyrios Kyrtzidisbfcacee2010-06-24 08:57:31 +0000918CXXDependentScopeMemberExpr *
919CXXDependentScopeMemberExpr::CreateEmpty(ASTContext &C,
920 unsigned NumTemplateArgs) {
921 if (NumTemplateArgs == 0)
922 return new (C) CXXDependentScopeMemberExpr(C, 0, QualType(),
923 0, SourceLocation(), 0,
924 SourceRange(), 0,
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000925 DeclarationNameInfo());
Argyrios Kyrtzidisbfcacee2010-06-24 08:57:31 +0000926
927 std::size_t size = sizeof(CXXDependentScopeMemberExpr) +
928 ExplicitTemplateArgumentList::sizeFor(NumTemplateArgs);
929 void *Mem = C.Allocate(size, llvm::alignof<CXXDependentScopeMemberExpr>());
930 CXXDependentScopeMemberExpr *E
931 = new (Mem) CXXDependentScopeMemberExpr(C, 0, QualType(),
932 0, SourceLocation(), 0,
933 SourceRange(), 0,
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000934 DeclarationNameInfo(), 0);
Argyrios Kyrtzidisbfcacee2010-06-24 08:57:31 +0000935 E->HasExplicitTemplateArgs = true;
936 return E;
937}
938
John McCall8cd78132009-11-19 22:55:06 +0000939Stmt::child_iterator CXXDependentScopeMemberExpr::child_begin() {
Douglas Gregora8db9542009-05-22 21:13:27 +0000940 return child_iterator(&Base);
941}
942
John McCall8cd78132009-11-19 22:55:06 +0000943Stmt::child_iterator CXXDependentScopeMemberExpr::child_end() {
John McCall2d74de92009-12-01 22:10:20 +0000944 if (isImplicitAccess())
945 return child_iterator(&Base);
Douglas Gregora8db9542009-05-22 21:13:27 +0000946 return child_iterator(&Base + 1);
947}
John McCall10eae182009-11-30 22:42:35 +0000948
Douglas Gregorc69978f2010-05-23 19:36:40 +0000949UnresolvedMemberExpr::UnresolvedMemberExpr(ASTContext &C, QualType T,
950 bool Dependent,
John McCall10eae182009-11-30 22:42:35 +0000951 bool HasUnresolvedUsing,
John McCall2d74de92009-12-01 22:10:20 +0000952 Expr *Base, QualType BaseType,
953 bool IsArrow,
John McCall10eae182009-11-30 22:42:35 +0000954 SourceLocation OperatorLoc,
955 NestedNameSpecifier *Qualifier,
956 SourceRange QualifierRange,
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000957 const DeclarationNameInfo &MemberNameInfo,
Douglas Gregor30a4f4c2010-05-23 18:57:34 +0000958 const TemplateArgumentListInfo *TemplateArgs,
959 UnresolvedSetIterator Begin,
960 UnresolvedSetIterator End)
Douglas Gregorc69978f2010-05-23 19:36:40 +0000961 : OverloadExpr(UnresolvedMemberExprClass, C, T, Dependent,
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000962 Qualifier, QualifierRange, MemberNameInfo,
Douglas Gregor30a4f4c2010-05-23 18:57:34 +0000963 TemplateArgs != 0, Begin, End),
John McCall1acbbb52010-02-02 06:20:04 +0000964 IsArrow(IsArrow), HasUnresolvedUsing(HasUnresolvedUsing),
965 Base(Base), BaseType(BaseType), OperatorLoc(OperatorLoc) {
John McCall10eae182009-11-30 22:42:35 +0000966 if (TemplateArgs)
John McCall1acbbb52010-02-02 06:20:04 +0000967 getExplicitTemplateArgs().initializeFrom(*TemplateArgs);
John McCall10eae182009-11-30 22:42:35 +0000968}
969
970UnresolvedMemberExpr *
971UnresolvedMemberExpr::Create(ASTContext &C, bool Dependent,
972 bool HasUnresolvedUsing,
John McCall2d74de92009-12-01 22:10:20 +0000973 Expr *Base, QualType BaseType, bool IsArrow,
John McCall10eae182009-11-30 22:42:35 +0000974 SourceLocation OperatorLoc,
975 NestedNameSpecifier *Qualifier,
976 SourceRange QualifierRange,
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000977 const DeclarationNameInfo &MemberNameInfo,
Douglas Gregor30a4f4c2010-05-23 18:57:34 +0000978 const TemplateArgumentListInfo *TemplateArgs,
979 UnresolvedSetIterator Begin,
980 UnresolvedSetIterator End) {
John McCall10eae182009-11-30 22:42:35 +0000981 std::size_t size = sizeof(UnresolvedMemberExpr);
982 if (TemplateArgs)
983 size += ExplicitTemplateArgumentList::sizeFor(*TemplateArgs);
984
985 void *Mem = C.Allocate(size, llvm::alignof<UnresolvedMemberExpr>());
Douglas Gregorc69978f2010-05-23 19:36:40 +0000986 return new (Mem) UnresolvedMemberExpr(C,
John McCall10eae182009-11-30 22:42:35 +0000987 Dependent ? C.DependentTy : C.OverloadTy,
John McCall2d74de92009-12-01 22:10:20 +0000988 Dependent, HasUnresolvedUsing, Base, BaseType,
989 IsArrow, OperatorLoc, Qualifier, QualifierRange,
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000990 MemberNameInfo, TemplateArgs, Begin, End);
John McCall10eae182009-11-30 22:42:35 +0000991}
992
Argyrios Kyrtzidisb8d3c632010-06-25 09:03:26 +0000993UnresolvedMemberExpr *
994UnresolvedMemberExpr::CreateEmpty(ASTContext &C, unsigned NumTemplateArgs) {
995 std::size_t size = sizeof(UnresolvedMemberExpr);
996 if (NumTemplateArgs != 0)
997 size += ExplicitTemplateArgumentList::sizeFor(NumTemplateArgs);
998
999 void *Mem = C.Allocate(size, llvm::alignof<UnresolvedMemberExpr>());
1000 UnresolvedMemberExpr *E = new (Mem) UnresolvedMemberExpr(EmptyShell());
1001 E->HasExplicitTemplateArgs = NumTemplateArgs != 0;
1002 return E;
1003}
1004
John McCall58cc69d2010-01-27 01:50:18 +00001005CXXRecordDecl *UnresolvedMemberExpr::getNamingClass() const {
1006 // Unlike for UnresolvedLookupExpr, it is very easy to re-derive this.
1007
1008 // If there was a nested name specifier, it names the naming class.
1009 // It can't be dependent: after all, we were actually able to do the
1010 // lookup.
Douglas Gregor9262f472010-04-27 18:19:34 +00001011 CXXRecordDecl *Record = 0;
John McCall1acbbb52010-02-02 06:20:04 +00001012 if (getQualifier()) {
1013 Type *T = getQualifier()->getAsType();
John McCall58cc69d2010-01-27 01:50:18 +00001014 assert(T && "qualifier in member expression does not name type");
Douglas Gregor9262f472010-04-27 18:19:34 +00001015 Record = T->getAsCXXRecordDecl();
1016 assert(Record && "qualifier in member expression does not name record");
1017 }
John McCall58cc69d2010-01-27 01:50:18 +00001018 // Otherwise the naming class must have been the base class.
Douglas Gregor9262f472010-04-27 18:19:34 +00001019 else {
John McCall58cc69d2010-01-27 01:50:18 +00001020 QualType BaseType = getBaseType().getNonReferenceType();
1021 if (isArrow()) {
1022 const PointerType *PT = BaseType->getAs<PointerType>();
1023 assert(PT && "base of arrow member access is not pointer");
1024 BaseType = PT->getPointeeType();
1025 }
1026
Douglas Gregor9262f472010-04-27 18:19:34 +00001027 Record = BaseType->getAsCXXRecordDecl();
1028 assert(Record && "base of member expression does not name record");
John McCall58cc69d2010-01-27 01:50:18 +00001029 }
1030
Douglas Gregor9262f472010-04-27 18:19:34 +00001031 return Record;
John McCall58cc69d2010-01-27 01:50:18 +00001032}
1033
John McCall10eae182009-11-30 22:42:35 +00001034Stmt::child_iterator UnresolvedMemberExpr::child_begin() {
1035 return child_iterator(&Base);
1036}
1037
1038Stmt::child_iterator UnresolvedMemberExpr::child_end() {
John McCall2d74de92009-12-01 22:10:20 +00001039 if (isImplicitAccess())
1040 return child_iterator(&Base);
John McCall10eae182009-11-30 22:42:35 +00001041 return child_iterator(&Base + 1);
1042}
Sebastian Redl4202c0f2010-09-10 20:55:43 +00001043
1044Stmt::child_iterator CXXNoexceptExpr::child_begin() {
1045 return child_iterator(&Operand);
1046}
1047Stmt::child_iterator CXXNoexceptExpr::child_end() {
1048 return child_iterator(&Operand + 1);
1049}