blob: 8caf70b3e12d84b4797c78cfb31021ccac9830e3 [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
Douglas Gregorab6677e2010-09-08 00:15:04 +000078SourceRange CXXScalarValueInitExpr::getSourceRange() const {
79 SourceLocation Start = RParenLoc;
80 if (TypeInfo)
81 Start = TypeInfo->getTypeLoc().getBeginLoc();
82 return SourceRange(Start, RParenLoc);
83}
84
Douglas Gregored8abf12010-07-08 06:14:04 +000085Stmt::child_iterator CXXScalarValueInitExpr::child_begin() {
Argyrios Kyrtzidis987a14b2008-08-22 15:38:55 +000086 return child_iterator();
87}
Douglas Gregored8abf12010-07-08 06:14:04 +000088Stmt::child_iterator CXXScalarValueInitExpr::child_end() {
Argyrios Kyrtzidis987a14b2008-08-22 15:38:55 +000089 return child_iterator();
90}
Argyrios Kyrtzidis9e922b12008-09-09 23:47:53 +000091
Sebastian Redl4c5d3202008-11-21 19:14:01 +000092// CXXNewExpr
Ted Kremenekad7fe862010-02-11 22:51:03 +000093CXXNewExpr::CXXNewExpr(ASTContext &C, bool globalNew, FunctionDecl *operatorNew,
Sebastian Redl4c5d3202008-11-21 19:14:01 +000094 Expr **placementArgs, unsigned numPlaceArgs,
Douglas Gregor4bd40312010-07-13 15:54:32 +000095 SourceRange TypeIdParens, Expr *arraySize,
Sebastian Redl4c5d3202008-11-21 19:14:01 +000096 CXXConstructorDecl *constructor, bool initializer,
97 Expr **constructorArgs, unsigned numConsArgs,
98 FunctionDecl *operatorDelete, QualType ty,
Douglas Gregor1bb2a932010-09-07 21:49:58 +000099 TypeSourceInfo *AllocatedTypeInfo,
Sebastian Redl4c5d3202008-11-21 19:14:01 +0000100 SourceLocation startLoc, SourceLocation endLoc)
Sebastian Redl28507842009-02-26 14:39:58 +0000101 : Expr(CXXNewExprClass, ty, ty->isDependentType(), ty->isDependentType()),
Douglas Gregor4bd40312010-07-13 15:54:32 +0000102 GlobalNew(globalNew),
Chris Lattner59218632010-05-10 01:22:27 +0000103 Initializer(initializer), SubExprs(0), OperatorNew(operatorNew),
Sebastian Redlcee63fb2008-12-02 14:43:59 +0000104 OperatorDelete(operatorDelete), Constructor(constructor),
Douglas Gregor1bb2a932010-09-07 21:49:58 +0000105 AllocatedTypeInfo(AllocatedTypeInfo), TypeIdParens(TypeIdParens),
106 StartLoc(startLoc), EndLoc(endLoc) {
Chris Lattner59218632010-05-10 01:22:27 +0000107
108 AllocateArgsArray(C, arraySize != 0, numPlaceArgs, numConsArgs);
Sebastian Redl4c5d3202008-11-21 19:14:01 +0000109 unsigned i = 0;
Sebastian Redlcee63fb2008-12-02 14:43:59 +0000110 if (Array)
111 SubExprs[i++] = arraySize;
112 for (unsigned j = 0; j < NumPlacementArgs; ++j)
Sebastian Redl4c5d3202008-11-21 19:14:01 +0000113 SubExprs[i++] = placementArgs[j];
Sebastian Redlcee63fb2008-12-02 14:43:59 +0000114 for (unsigned j = 0; j < NumConstructorArgs; ++j)
Sebastian Redl4c5d3202008-11-21 19:14:01 +0000115 SubExprs[i++] = constructorArgs[j];
Sebastian Redl4c5d3202008-11-21 19:14:01 +0000116}
117
Chris Lattner59218632010-05-10 01:22:27 +0000118void CXXNewExpr::AllocateArgsArray(ASTContext &C, bool isArray,
119 unsigned numPlaceArgs, unsigned numConsArgs){
120 assert(SubExprs == 0 && "SubExprs already allocated");
121 Array = isArray;
122 NumPlacementArgs = numPlaceArgs;
123 NumConstructorArgs = numConsArgs;
124
125 unsigned TotalSize = Array + NumPlacementArgs + NumConstructorArgs;
126 SubExprs = new (C) Stmt*[TotalSize];
127}
128
129
Sebastian Redl4c5d3202008-11-21 19:14:01 +0000130Stmt::child_iterator CXXNewExpr::child_begin() { return &SubExprs[0]; }
131Stmt::child_iterator CXXNewExpr::child_end() {
Sebastian Redlcee63fb2008-12-02 14:43:59 +0000132 return &SubExprs[0] + Array + getNumPlacementArgs() + getNumConstructorArgs();
Sebastian Redl4c5d3202008-11-21 19:14:01 +0000133}
134
135// CXXDeleteExpr
136Stmt::child_iterator CXXDeleteExpr::child_begin() { return &Argument; }
137Stmt::child_iterator CXXDeleteExpr::child_end() { return &Argument+1; }
138
Douglas Gregora71d8192009-09-04 17:36:40 +0000139// CXXPseudoDestructorExpr
140Stmt::child_iterator CXXPseudoDestructorExpr::child_begin() { return &Base; }
141Stmt::child_iterator CXXPseudoDestructorExpr::child_end() {
142 return &Base + 1;
143}
144
Douglas Gregora2e7dd22010-02-25 01:56:36 +0000145PseudoDestructorTypeStorage::PseudoDestructorTypeStorage(TypeSourceInfo *Info)
146 : Type(Info)
147{
Abramo Bagnarabd054db2010-05-20 10:00:11 +0000148 Location = Info->getTypeLoc().getLocalSourceRange().getBegin();
Douglas Gregora2e7dd22010-02-25 01:56:36 +0000149}
150
151QualType CXXPseudoDestructorExpr::getDestroyedType() const {
152 if (TypeSourceInfo *TInfo = DestroyedType.getTypeSourceInfo())
153 return TInfo->getType();
154
155 return QualType();
156}
157
Douglas Gregor26d4ac92010-02-24 23:40:28 +0000158SourceRange CXXPseudoDestructorExpr::getSourceRange() const {
Douglas Gregora2e7dd22010-02-25 01:56:36 +0000159 SourceLocation End = DestroyedType.getLocation();
160 if (TypeSourceInfo *TInfo = DestroyedType.getTypeSourceInfo())
Abramo Bagnarabd054db2010-05-20 10:00:11 +0000161 End = TInfo->getTypeLoc().getLocalSourceRange().getEnd();
Douglas Gregora2e7dd22010-02-25 01:56:36 +0000162 return SourceRange(Base->getLocStart(), End);
Douglas Gregor26d4ac92010-02-24 23:40:28 +0000163}
164
165
John McCallba135432009-11-21 08:51:07 +0000166// UnresolvedLookupExpr
John McCallf7a1a742009-11-24 19:00:30 +0000167UnresolvedLookupExpr *
168UnresolvedLookupExpr::Create(ASTContext &C, bool Dependent,
John McCallc373d482010-01-27 01:50:18 +0000169 CXXRecordDecl *NamingClass,
John McCallf7a1a742009-11-24 19:00:30 +0000170 NestedNameSpecifier *Qualifier,
Abramo Bagnara25777432010-08-11 22:01:17 +0000171 SourceRange QualifierRange,
172 const DeclarationNameInfo &NameInfo,
173 bool ADL,
Douglas Gregor5a84dec2010-05-23 18:57:34 +0000174 const TemplateArgumentListInfo &Args,
175 UnresolvedSetIterator Begin,
176 UnresolvedSetIterator End)
John McCallf7a1a742009-11-24 19:00:30 +0000177{
178 void *Mem = C.Allocate(sizeof(UnresolvedLookupExpr) +
179 ExplicitTemplateArgumentList::sizeFor(Args));
180 UnresolvedLookupExpr *ULE
Douglas Gregor928e6fc2010-05-23 19:36:40 +0000181 = new (Mem) UnresolvedLookupExpr(C,
182 Dependent ? C.DependentTy : C.OverloadTy,
John McCallc373d482010-01-27 01:50:18 +0000183 Dependent, NamingClass,
Abramo Bagnara25777432010-08-11 22:01:17 +0000184 Qualifier, QualifierRange, NameInfo,
185 ADL,
John McCallf7a1a742009-11-24 19:00:30 +0000186 /*Overload*/ true,
Douglas Gregor5a84dec2010-05-23 18:57:34 +0000187 /*ExplicitTemplateArgs*/ true,
188 Begin, End);
John McCallf7a1a742009-11-24 19:00:30 +0000189
190 reinterpret_cast<ExplicitTemplateArgumentList*>(ULE+1)->initializeFrom(Args);
191
192 return ULE;
193}
194
Argyrios Kyrtzidisbd65bb52010-06-25 09:03:34 +0000195UnresolvedLookupExpr *
196UnresolvedLookupExpr::CreateEmpty(ASTContext &C, unsigned NumTemplateArgs) {
197 std::size_t size = sizeof(UnresolvedLookupExpr);
198 if (NumTemplateArgs != 0)
199 size += ExplicitTemplateArgumentList::sizeFor(NumTemplateArgs);
200
201 void *Mem = C.Allocate(size, llvm::alignof<UnresolvedLookupExpr>());
202 UnresolvedLookupExpr *E = new (Mem) UnresolvedLookupExpr(EmptyShell());
203 E->HasExplicitTemplateArgs = NumTemplateArgs != 0;
204 return E;
205}
206
Douglas Gregor928e6fc2010-05-23 19:36:40 +0000207OverloadExpr::OverloadExpr(StmtClass K, ASTContext &C, QualType T,
208 bool Dependent, NestedNameSpecifier *Qualifier,
Abramo Bagnara25777432010-08-11 22:01:17 +0000209 SourceRange QRange,
210 const DeclarationNameInfo &NameInfo,
211 bool HasTemplateArgs,
Douglas Gregor928e6fc2010-05-23 19:36:40 +0000212 UnresolvedSetIterator Begin,
213 UnresolvedSetIterator End)
214 : Expr(K, T, Dependent, Dependent),
Abramo Bagnara25777432010-08-11 22:01:17 +0000215 Results(0), NumResults(0), NameInfo(NameInfo), Qualifier(Qualifier),
216 QualifierRange(QRange), HasExplicitTemplateArgs(HasTemplateArgs)
Douglas Gregor928e6fc2010-05-23 19:36:40 +0000217{
Argyrios Kyrtzidisa77eb082010-06-25 09:03:26 +0000218 initializeResults(C, Begin, End);
219}
220
221void OverloadExpr::initializeResults(ASTContext &C,
222 UnresolvedSetIterator Begin,
223 UnresolvedSetIterator End) {
224 assert(Results == 0 && "Results already initialized!");
225 NumResults = End - Begin;
Douglas Gregor928e6fc2010-05-23 19:36:40 +0000226 if (NumResults) {
227 Results = static_cast<DeclAccessPair *>(
228 C.Allocate(sizeof(DeclAccessPair) * NumResults,
229 llvm::alignof<DeclAccessPair>()));
230 memcpy(Results, &*Begin.getIterator(),
Argyrios Kyrtzidisa77eb082010-06-25 09:03:26 +0000231 NumResults * sizeof(DeclAccessPair));
Douglas Gregor928e6fc2010-05-23 19:36:40 +0000232 }
233}
234
Argyrios Kyrtzidisa77eb082010-06-25 09:03:26 +0000235
John McCall7bb12da2010-02-02 06:20:04 +0000236bool OverloadExpr::ComputeDependence(UnresolvedSetIterator Begin,
237 UnresolvedSetIterator End,
238 const TemplateArgumentListInfo *Args) {
John McCalleec51cf2010-01-20 00:46:10 +0000239 for (UnresolvedSetImpl::const_iterator I = Begin; I != End; ++I)
John McCallf7a1a742009-11-24 19:00:30 +0000240 if ((*I)->getDeclContext()->isDependentContext())
241 return true;
242
243 if (Args && TemplateSpecializationType::anyDependentTemplateArguments(*Args))
244 return true;
245
246 return false;
247}
248
John McCalle9ee23e2010-04-22 18:44:12 +0000249CXXRecordDecl *OverloadExpr::getNamingClass() const {
250 if (isa<UnresolvedLookupExpr>(this))
251 return cast<UnresolvedLookupExpr>(this)->getNamingClass();
252 else
253 return cast<UnresolvedMemberExpr>(this)->getNamingClass();
254}
255
John McCallba135432009-11-21 08:51:07 +0000256Stmt::child_iterator UnresolvedLookupExpr::child_begin() {
Mike Stump1eb44332009-09-09 15:08:12 +0000257 return child_iterator();
Douglas Gregor5c37de72008-12-06 00:22:45 +0000258}
John McCallba135432009-11-21 08:51:07 +0000259Stmt::child_iterator UnresolvedLookupExpr::child_end() {
Douglas Gregor5c37de72008-12-06 00:22:45 +0000260 return child_iterator();
261}
Sebastian Redl64b45f72009-01-05 20:52:13 +0000262// UnaryTypeTraitExpr
263Stmt::child_iterator UnaryTypeTraitExpr::child_begin() {
264 return child_iterator();
265}
266Stmt::child_iterator UnaryTypeTraitExpr::child_end() {
267 return child_iterator();
268}
269
John McCall865d4472009-11-19 22:55:06 +0000270// DependentScopeDeclRefExpr
John McCallf7a1a742009-11-24 19:00:30 +0000271DependentScopeDeclRefExpr *
272DependentScopeDeclRefExpr::Create(ASTContext &C,
273 NestedNameSpecifier *Qualifier,
274 SourceRange QualifierRange,
Abramo Bagnara25777432010-08-11 22:01:17 +0000275 const DeclarationNameInfo &NameInfo,
John McCallf7a1a742009-11-24 19:00:30 +0000276 const TemplateArgumentListInfo *Args) {
277 std::size_t size = sizeof(DependentScopeDeclRefExpr);
278 if (Args) size += ExplicitTemplateArgumentList::sizeFor(*Args);
279 void *Mem = C.Allocate(size);
280
281 DependentScopeDeclRefExpr *DRE
282 = new (Mem) DependentScopeDeclRefExpr(C.DependentTy,
283 Qualifier, QualifierRange,
Abramo Bagnara25777432010-08-11 22:01:17 +0000284 NameInfo, Args != 0);
John McCallf7a1a742009-11-24 19:00:30 +0000285
286 if (Args)
287 reinterpret_cast<ExplicitTemplateArgumentList*>(DRE+1)
288 ->initializeFrom(*Args);
289
290 return DRE;
291}
292
Argyrios Kyrtzidis12dffcd2010-06-28 09:31:56 +0000293DependentScopeDeclRefExpr *
294DependentScopeDeclRefExpr::CreateEmpty(ASTContext &C,
295 unsigned NumTemplateArgs) {
296 std::size_t size = sizeof(DependentScopeDeclRefExpr);
297 if (NumTemplateArgs)
298 size += ExplicitTemplateArgumentList::sizeFor(NumTemplateArgs);
299 void *Mem = C.Allocate(size);
300
301 return new (Mem) DependentScopeDeclRefExpr(QualType(), 0, SourceRange(),
Abramo Bagnara25777432010-08-11 22:01:17 +0000302 DeclarationNameInfo(),
Argyrios Kyrtzidis12dffcd2010-06-28 09:31:56 +0000303 NumTemplateArgs != 0);
304}
305
John McCall865d4472009-11-19 22:55:06 +0000306StmtIterator DependentScopeDeclRefExpr::child_begin() {
Douglas Gregor5953d8b2009-03-19 17:26:29 +0000307 return child_iterator();
308}
309
John McCall865d4472009-11-19 22:55:06 +0000310StmtIterator DependentScopeDeclRefExpr::child_end() {
Douglas Gregor5953d8b2009-03-19 17:26:29 +0000311 return child_iterator();
312}
313
Douglas Gregor5e03f9e2009-07-23 23:49:00 +0000314bool UnaryTypeTraitExpr::EvaluateTrait(ASTContext& C) const {
Sebastian Redl64b45f72009-01-05 20:52:13 +0000315 switch(UTT) {
316 default: assert(false && "Unknown type trait or not implemented");
317 case UTT_IsPOD: return QueriedType->isPODType();
Sebastian Redlccf43502009-12-03 00:13:20 +0000318 case UTT_IsLiteral: return QueriedType->isLiteralType();
Sebastian Redl64b45f72009-01-05 20:52:13 +0000319 case UTT_IsClass: // Fallthrough
320 case UTT_IsUnion:
Ted Kremenek6217b802009-07-29 21:53:49 +0000321 if (const RecordType *Record = QueriedType->getAs<RecordType>()) {
Sebastian Redl64b45f72009-01-05 20:52:13 +0000322 bool Union = Record->getDecl()->isUnion();
323 return UTT == UTT_IsUnion ? Union : !Union;
324 }
325 return false;
326 case UTT_IsEnum: return QueriedType->isEnumeralType();
327 case UTT_IsPolymorphic:
Ted Kremenek6217b802009-07-29 21:53:49 +0000328 if (const RecordType *Record = QueriedType->getAs<RecordType>()) {
Sebastian Redl64b45f72009-01-05 20:52:13 +0000329 // Type traits are only parsed in C++, so we've got CXXRecords.
330 return cast<CXXRecordDecl>(Record->getDecl())->isPolymorphic();
331 }
332 return false;
Anders Carlsson67e4dd22009-03-22 01:52:17 +0000333 case UTT_IsAbstract:
Ted Kremenek6217b802009-07-29 21:53:49 +0000334 if (const RecordType *RT = QueriedType->getAs<RecordType>())
Anders Carlsson67e4dd22009-03-22 01:52:17 +0000335 return cast<CXXRecordDecl>(RT->getDecl())->isAbstract();
336 return false;
Eli Friedman1d954f62009-08-15 21:55:26 +0000337 case UTT_IsEmpty:
338 if (const RecordType *Record = QueriedType->getAs<RecordType>()) {
339 return !Record->getDecl()->isUnion()
340 && cast<CXXRecordDecl>(Record->getDecl())->isEmpty();
341 }
342 return false;
Anders Carlsson347ba892009-04-16 00:08:20 +0000343 case UTT_HasTrivialConstructor:
Douglas Gregor5e03f9e2009-07-23 23:49:00 +0000344 // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
345 // If __is_pod (type) is true then the trait is true, else if type is
346 // a cv class or union type (or array thereof) with a trivial default
347 // constructor ([class.ctor]) then the trait is true, else it is false.
348 if (QueriedType->isPODType())
349 return true;
350 if (const RecordType *RT =
Ted Kremenek6217b802009-07-29 21:53:49 +0000351 C.getBaseElementType(QueriedType)->getAs<RecordType>())
Anders Carlsson347ba892009-04-16 00:08:20 +0000352 return cast<CXXRecordDecl>(RT->getDecl())->hasTrivialConstructor();
Anders Carlsson072abef2009-04-17 02:34:54 +0000353 return false;
Douglas Gregor5e03f9e2009-07-23 23:49:00 +0000354 case UTT_HasTrivialCopy:
355 // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
356 // If __is_pod (type) is true or type is a reference type then
357 // the trait is true, else if type is a cv class or union type
358 // with a trivial copy constructor ([class.copy]) then the trait
359 // is true, else it is false.
360 if (QueriedType->isPODType() || QueriedType->isReferenceType())
361 return true;
Ted Kremenek6217b802009-07-29 21:53:49 +0000362 if (const RecordType *RT = QueriedType->getAs<RecordType>())
Douglas Gregor5e03f9e2009-07-23 23:49:00 +0000363 return cast<CXXRecordDecl>(RT->getDecl())->hasTrivialCopyConstructor();
364 return false;
365 case UTT_HasTrivialAssign:
366 // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
367 // If type is const qualified or is a reference type then the
368 // trait is false. Otherwise if __is_pod (type) is true then the
369 // trait is true, else if type is a cv class or union type with
370 // a trivial copy assignment ([class.copy]) then the trait is
371 // true, else it is false.
372 // Note: the const and reference restrictions are interesting,
373 // given that const and reference members don't prevent a class
374 // from having a trivial copy assignment operator (but do cause
375 // errors if the copy assignment operator is actually used, q.v.
376 // [class.copy]p12).
377
378 if (C.getBaseElementType(QueriedType).isConstQualified())
379 return false;
380 if (QueriedType->isPODType())
381 return true;
Ted Kremenek6217b802009-07-29 21:53:49 +0000382 if (const RecordType *RT = QueriedType->getAs<RecordType>())
Douglas Gregor5e03f9e2009-07-23 23:49:00 +0000383 return cast<CXXRecordDecl>(RT->getDecl())->hasTrivialCopyAssignment();
384 return false;
385 case UTT_HasTrivialDestructor:
386 // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
387 // If __is_pod (type) is true or type is a reference type
388 // then the trait is true, else if type is a cv class or union
389 // type (or array thereof) with a trivial destructor
390 // ([class.dtor]) then the trait is true, else it is
391 // false.
392 if (QueriedType->isPODType() || QueriedType->isReferenceType())
393 return true;
394 if (const RecordType *RT =
Ted Kremenek6217b802009-07-29 21:53:49 +0000395 C.getBaseElementType(QueriedType)->getAs<RecordType>())
Anders Carlsson072abef2009-04-17 02:34:54 +0000396 return cast<CXXRecordDecl>(RT->getDecl())->hasTrivialDestructor();
397 return false;
Sebastian Redlc238f092010-08-31 04:59:00 +0000398 // TODO: Propagate nothrowness for implicitly declared special members.
399 case UTT_HasNothrowAssign:
400 // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
401 // If type is const qualified or is a reference type then the
402 // trait is false. Otherwise if __has_trivial_assign (type)
403 // is true then the trait is true, else if type is a cv class
404 // or union type with copy assignment operators that are known
405 // not to throw an exception then the trait is true, else it is
406 // false.
407 if (C.getBaseElementType(QueriedType).isConstQualified())
408 return false;
409 if (QueriedType->isReferenceType())
410 return false;
411 if (QueriedType->isPODType())
412 return true;
413 if (const RecordType *RT = QueriedType->getAs<RecordType>()) {
414 CXXRecordDecl* RD = cast<CXXRecordDecl>(RT->getDecl());
415 if (RD->hasTrivialCopyAssignment())
416 return true;
417
418 bool FoundAssign = false;
419 bool AllNoThrow = true;
420 DeclarationName Name = C.DeclarationNames.getCXXOperatorName(OO_Equal);
421 DeclContext::lookup_const_iterator Op, OpEnd;
422 for (llvm::tie(Op, OpEnd) = RD->lookup(Name);
423 Op != OpEnd; ++Op) {
424 CXXMethodDecl *Operator = cast<CXXMethodDecl>(*Op);
425 if (Operator->isCopyAssignmentOperator()) {
426 FoundAssign = true;
427 const FunctionProtoType *CPT
428 = Operator->getType()->getAs<FunctionProtoType>();
429 if (!CPT->hasEmptyExceptionSpec()) {
430 AllNoThrow = false;
431 break;
432 }
433 }
434 }
435
436 return FoundAssign && AllNoThrow;
437 }
438 return false;
439 case UTT_HasNothrowCopy:
440 // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
441 // If __has_trivial_copy (type) is true then the trait is true, else
442 // if type is a cv class or union type with copy constructors that are
443 // known not to throw an exception then the trait is true, else it is
444 // false.
445 if (QueriedType->isPODType() || QueriedType->isReferenceType())
446 return true;
447 if (const RecordType *RT = QueriedType->getAs<RecordType>()) {
448 CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
449 if (RD->hasTrivialCopyConstructor())
450 return true;
451
452 bool FoundConstructor = false;
453 bool AllNoThrow = true;
454 unsigned FoundTQs;
455 DeclarationName ConstructorName
456 = C.DeclarationNames.getCXXConstructorName(
457 C.getCanonicalType(QueriedType));
458 DeclContext::lookup_const_iterator Con, ConEnd;
459 for (llvm::tie(Con, ConEnd) = RD->lookup(ConstructorName);
460 Con != ConEnd; ++Con) {
461 CXXConstructorDecl *Constructor = cast<CXXConstructorDecl>(*Con);
462 if (Constructor->isCopyConstructor(FoundTQs)) {
463 FoundConstructor = true;
464 const FunctionProtoType *CPT
465 = Constructor->getType()->getAs<FunctionProtoType>();
466 if (!CPT->hasEmptyExceptionSpec()) {
467 AllNoThrow = false;
468 break;
469 }
470 }
471 }
472
473 return FoundConstructor && AllNoThrow;
474 }
475 return false;
476 case UTT_HasNothrowConstructor:
477 // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
478 // If __has_trivial_constructor (type) is true then the trait is
479 // true, else if type is a cv class or union type (or array
480 // thereof) with a default constructor that is known not to
481 // throw an exception then the trait is true, else it is false.
482 if (QueriedType->isPODType())
483 return true;
484 if (const RecordType *RT =
485 C.getBaseElementType(QueriedType)->getAs<RecordType>()) {
486 CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
487 if (RD->hasTrivialConstructor())
488 return true;
489
490 if (CXXConstructorDecl *Constructor = RD->getDefaultConstructor()) {
491 const FunctionProtoType *CPT
492 = Constructor->getType()->getAs<FunctionProtoType>();
493 // TODO: check whether evaluating default arguments can throw.
494 // For now, we'll be conservative and assume that they can throw.
495 if (CPT->hasEmptyExceptionSpec() && CPT->getNumArgs() == 0)
496 return true;
497 }
498 }
499 return false;
Sebastian Redld4b25cb2010-09-02 23:19:42 +0000500 case UTT_HasVirtualDestructor:
501 // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
502 // If type is a class type with a virtual destructor ([class.dtor])
503 // then the trait is true, else it is false.
504 if (const RecordType *Record = QueriedType->getAs<RecordType>()) {
505 CXXRecordDecl *RD = cast<CXXRecordDecl>(Record->getDecl());
506 if (CXXDestructorDecl *Destructor = RD->getDestructor())
507 return Destructor->isVirtual();
508 }
509 return false;
Sebastian Redl64b45f72009-01-05 20:52:13 +0000510 }
511}
512
Ted Kremeneke3837682009-12-23 04:00:48 +0000513SourceRange CXXConstructExpr::getSourceRange() const {
514 // FIXME: Should we know where the parentheses are, if there are any?
515 for (std::reverse_iterator<Stmt**> I(&Args[NumArgs]), E(&Args[0]); I!=E;++I) {
516 // Ignore CXXDefaultExprs when computing the range, as they don't
517 // have a range.
518 if (!isa<CXXDefaultArgExpr>(*I))
519 return SourceRange(Loc, (*I)->getLocEnd());
520 }
521
522 return SourceRange(Loc);
523}
524
Douglas Gregorb4609802008-11-14 16:09:21 +0000525SourceRange CXXOperatorCallExpr::getSourceRange() const {
526 OverloadedOperatorKind Kind = getOperator();
527 if (Kind == OO_PlusPlus || Kind == OO_MinusMinus) {
528 if (getNumArgs() == 1)
529 // Prefix operator
Mike Stump1eb44332009-09-09 15:08:12 +0000530 return SourceRange(getOperatorLoc(),
Douglas Gregorb4609802008-11-14 16:09:21 +0000531 getArg(0)->getSourceRange().getEnd());
532 else
533 // Postfix operator
534 return SourceRange(getArg(0)->getSourceRange().getEnd(),
535 getOperatorLoc());
536 } else if (Kind == OO_Call) {
537 return SourceRange(getArg(0)->getSourceRange().getBegin(), getRParenLoc());
538 } else if (Kind == OO_Subscript) {
539 return SourceRange(getArg(0)->getSourceRange().getBegin(), getRParenLoc());
540 } else if (getNumArgs() == 1) {
541 return SourceRange(getOperatorLoc(), getArg(0)->getSourceRange().getEnd());
542 } else if (getNumArgs() == 2) {
543 return SourceRange(getArg(0)->getSourceRange().getBegin(),
544 getArg(1)->getSourceRange().getEnd());
545 } else {
546 return SourceRange();
547 }
548}
549
Douglas Gregor88a35142008-12-22 05:46:06 +0000550Expr *CXXMemberCallExpr::getImplicitObjectArgument() {
551 if (MemberExpr *MemExpr = dyn_cast<MemberExpr>(getCallee()->IgnoreParens()))
552 return MemExpr->getBase();
553
554 // FIXME: Will eventually need to cope with member pointers.
555 return 0;
556}
557
Douglas Gregor00b98c22009-11-12 15:31:47 +0000558SourceRange CXXMemberCallExpr::getSourceRange() const {
559 SourceLocation LocStart = getCallee()->getLocStart();
560 if (LocStart.isInvalid() && getNumArgs() > 0)
561 LocStart = getArg(0)->getLocStart();
562 return SourceRange(LocStart, getRParenLoc());
563}
564
565
Douglas Gregor49badde2008-10-27 19:41:14 +0000566//===----------------------------------------------------------------------===//
567// Named casts
568//===----------------------------------------------------------------------===//
569
570/// getCastName - Get the name of the C++ cast being used, e.g.,
571/// "static_cast", "dynamic_cast", "reinterpret_cast", or
572/// "const_cast". The returned pointer must not be freed.
573const char *CXXNamedCastExpr::getCastName() const {
574 switch (getStmtClass()) {
575 case CXXStaticCastExprClass: return "static_cast";
576 case CXXDynamicCastExprClass: return "dynamic_cast";
577 case CXXReinterpretCastExprClass: return "reinterpret_cast";
578 case CXXConstCastExprClass: return "const_cast";
579 default: return "<invalid cast>";
580 }
581}
Douglas Gregor506ae412009-01-16 18:33:17 +0000582
John McCallf871d0c2010-08-07 06:22:56 +0000583CXXStaticCastExpr *CXXStaticCastExpr::Create(ASTContext &C, QualType T,
584 CastKind K, Expr *Op,
585 const CXXCastPath *BasePath,
586 TypeSourceInfo *WrittenTy,
587 SourceLocation L) {
588 unsigned PathSize = (BasePath ? BasePath->size() : 0);
589 void *Buffer = C.Allocate(sizeof(CXXStaticCastExpr)
590 + PathSize * sizeof(CXXBaseSpecifier*));
591 CXXStaticCastExpr *E =
592 new (Buffer) CXXStaticCastExpr(T, K, Op, PathSize, WrittenTy, L);
593 if (PathSize) E->setCastPath(*BasePath);
594 return E;
595}
596
597CXXStaticCastExpr *CXXStaticCastExpr::CreateEmpty(ASTContext &C,
598 unsigned PathSize) {
599 void *Buffer =
600 C.Allocate(sizeof(CXXStaticCastExpr) + PathSize * sizeof(CXXBaseSpecifier*));
601 return new (Buffer) CXXStaticCastExpr(EmptyShell(), PathSize);
602}
603
604CXXDynamicCastExpr *CXXDynamicCastExpr::Create(ASTContext &C, QualType T,
605 CastKind K, Expr *Op,
606 const CXXCastPath *BasePath,
607 TypeSourceInfo *WrittenTy,
608 SourceLocation L) {
609 unsigned PathSize = (BasePath ? BasePath->size() : 0);
610 void *Buffer = C.Allocate(sizeof(CXXDynamicCastExpr)
611 + PathSize * sizeof(CXXBaseSpecifier*));
612 CXXDynamicCastExpr *E =
613 new (Buffer) CXXDynamicCastExpr(T, K, Op, PathSize, WrittenTy, L);
614 if (PathSize) E->setCastPath(*BasePath);
615 return E;
616}
617
618CXXDynamicCastExpr *CXXDynamicCastExpr::CreateEmpty(ASTContext &C,
619 unsigned PathSize) {
620 void *Buffer =
621 C.Allocate(sizeof(CXXDynamicCastExpr) + PathSize * sizeof(CXXBaseSpecifier*));
622 return new (Buffer) CXXDynamicCastExpr(EmptyShell(), PathSize);
623}
624
625CXXReinterpretCastExpr *
626CXXReinterpretCastExpr::Create(ASTContext &C, QualType T, CastKind K, Expr *Op,
627 const CXXCastPath *BasePath,
628 TypeSourceInfo *WrittenTy, SourceLocation L) {
629 unsigned PathSize = (BasePath ? BasePath->size() : 0);
630 void *Buffer =
631 C.Allocate(sizeof(CXXReinterpretCastExpr) + PathSize * sizeof(CXXBaseSpecifier*));
632 CXXReinterpretCastExpr *E =
633 new (Buffer) CXXReinterpretCastExpr(T, K, Op, PathSize, WrittenTy, L);
634 if (PathSize) E->setCastPath(*BasePath);
635 return E;
636}
637
638CXXReinterpretCastExpr *
639CXXReinterpretCastExpr::CreateEmpty(ASTContext &C, unsigned PathSize) {
640 void *Buffer = C.Allocate(sizeof(CXXReinterpretCastExpr)
641 + PathSize * sizeof(CXXBaseSpecifier*));
642 return new (Buffer) CXXReinterpretCastExpr(EmptyShell(), PathSize);
643}
644
645CXXConstCastExpr *CXXConstCastExpr::Create(ASTContext &C, QualType T, Expr *Op,
646 TypeSourceInfo *WrittenTy,
647 SourceLocation L) {
648 return new (C) CXXConstCastExpr(T, Op, WrittenTy, L);
649}
650
651CXXConstCastExpr *CXXConstCastExpr::CreateEmpty(ASTContext &C) {
652 return new (C) CXXConstCastExpr(EmptyShell());
653}
654
655CXXFunctionalCastExpr *
656CXXFunctionalCastExpr::Create(ASTContext &C, QualType T,
657 TypeSourceInfo *Written, SourceLocation L,
658 CastKind K, Expr *Op, const CXXCastPath *BasePath,
659 SourceLocation R) {
660 unsigned PathSize = (BasePath ? BasePath->size() : 0);
661 void *Buffer = C.Allocate(sizeof(CXXFunctionalCastExpr)
662 + PathSize * sizeof(CXXBaseSpecifier*));
663 CXXFunctionalCastExpr *E =
664 new (Buffer) CXXFunctionalCastExpr(T, Written, L, K, Op, PathSize, R);
665 if (PathSize) E->setCastPath(*BasePath);
666 return E;
667}
668
669CXXFunctionalCastExpr *
670CXXFunctionalCastExpr::CreateEmpty(ASTContext &C, unsigned PathSize) {
671 void *Buffer = C.Allocate(sizeof(CXXFunctionalCastExpr)
672 + PathSize * sizeof(CXXBaseSpecifier*));
673 return new (Buffer) CXXFunctionalCastExpr(EmptyShell(), PathSize);
674}
675
676
Douglas Gregor65222e82009-12-23 18:19:08 +0000677CXXDefaultArgExpr *
Douglas Gregor036aed12009-12-23 23:03:06 +0000678CXXDefaultArgExpr::Create(ASTContext &C, SourceLocation Loc,
679 ParmVarDecl *Param, Expr *SubExpr) {
Douglas Gregor65222e82009-12-23 18:19:08 +0000680 void *Mem = C.Allocate(sizeof(CXXDefaultArgExpr) + sizeof(Stmt *));
Douglas Gregor036aed12009-12-23 23:03:06 +0000681 return new (Mem) CXXDefaultArgExpr(CXXDefaultArgExprClass, Loc, Param,
682 SubExpr);
Douglas Gregor65222e82009-12-23 18:19:08 +0000683}
684
Mike Stump1eb44332009-09-09 15:08:12 +0000685CXXTemporary *CXXTemporary::Create(ASTContext &C,
Anders Carlssonb859f352009-05-30 20:34:37 +0000686 const CXXDestructorDecl *Destructor) {
Anders Carlsson88eaf072009-05-30 22:38:53 +0000687 return new (C) CXXTemporary(Destructor);
688}
689
Mike Stump1eb44332009-09-09 15:08:12 +0000690CXXBindTemporaryExpr *CXXBindTemporaryExpr::Create(ASTContext &C,
Anders Carlssonfceb0a82009-05-30 20:03:25 +0000691 CXXTemporary *Temp,
692 Expr* SubExpr) {
Mike Stump1eb44332009-09-09 15:08:12 +0000693 assert(SubExpr->getType()->isRecordType() &&
Anders Carlssonfceb0a82009-05-30 20:03:25 +0000694 "Expression bound to a temporary must have record type!");
695
Anders Carlssonb859f352009-05-30 20:34:37 +0000696 return new (C) CXXBindTemporaryExpr(Temp, SubExpr);
Anders Carlssonfceb0a82009-05-30 20:03:25 +0000697}
698
Anders Carlsson8e587a12009-05-30 20:56:46 +0000699CXXTemporaryObjectExpr::CXXTemporaryObjectExpr(ASTContext &C,
Anders Carlsson26de5492009-04-24 05:23:13 +0000700 CXXConstructorDecl *Cons,
Douglas Gregorab6677e2010-09-08 00:15:04 +0000701 TypeSourceInfo *Type,
Douglas Gregor506ae412009-01-16 18:33:17 +0000702 Expr **Args,
Mike Stump1eb44332009-09-09 15:08:12 +0000703 unsigned NumArgs,
Douglas Gregor1c63b9c2010-04-27 20:36:09 +0000704 SourceLocation rParenLoc,
705 bool ZeroInitialization)
Douglas Gregorab6677e2010-09-08 00:15:04 +0000706 : CXXConstructExpr(C, CXXTemporaryObjectExprClass,
707 Type->getType().getNonReferenceType(),
708 Type->getTypeLoc().getBeginLoc(),
Douglas Gregor1c63b9c2010-04-27 20:36:09 +0000709 Cons, false, Args, NumArgs, ZeroInitialization),
Douglas Gregorab6677e2010-09-08 00:15:04 +0000710 RParenLoc(rParenLoc), Type(Type) {
711}
712
713SourceRange CXXTemporaryObjectExpr::getSourceRange() const {
714 return SourceRange(Type->getTypeLoc().getBeginLoc(), RParenLoc);
Douglas Gregor506ae412009-01-16 18:33:17 +0000715}
Anders Carlsson19d28a62009-04-21 02:22:11 +0000716
Mike Stump1eb44332009-09-09 15:08:12 +0000717CXXConstructExpr *CXXConstructExpr::Create(ASTContext &C, QualType T,
Douglas Gregor99a2e602009-12-16 01:38:02 +0000718 SourceLocation Loc,
Anders Carlsson8e587a12009-05-30 20:56:46 +0000719 CXXConstructorDecl *D, bool Elidable,
Douglas Gregor16006c92009-12-16 18:50:27 +0000720 Expr **Args, unsigned NumArgs,
Douglas Gregor9db7dbb2010-01-31 09:12:51 +0000721 bool ZeroInitialization,
Anders Carlssonfcaeef22010-05-02 23:53:04 +0000722 ConstructionKind ConstructKind) {
Douglas Gregor99a2e602009-12-16 01:38:02 +0000723 return new (C) CXXConstructExpr(C, CXXConstructExprClass, T, Loc, D,
Douglas Gregor9db7dbb2010-01-31 09:12:51 +0000724 Elidable, Args, NumArgs, ZeroInitialization,
Anders Carlssonfcaeef22010-05-02 23:53:04 +0000725 ConstructKind);
Anders Carlssone349bea2009-04-23 02:32:43 +0000726}
727
Mike Stump1eb44332009-09-09 15:08:12 +0000728CXXConstructExpr::CXXConstructExpr(ASTContext &C, StmtClass SC, QualType T,
Douglas Gregor99a2e602009-12-16 01:38:02 +0000729 SourceLocation Loc,
Anders Carlsson8e587a12009-05-30 20:56:46 +0000730 CXXConstructorDecl *D, bool elidable,
Douglas Gregor16006c92009-12-16 18:50:27 +0000731 Expr **args, unsigned numargs,
Anders Carlsson72e96fd2010-05-02 22:54:08 +0000732 bool ZeroInitialization,
733 ConstructionKind ConstructKind)
Anders Carlssonbd6734e2009-04-24 05:04:04 +0000734: Expr(SC, T,
Anders Carlssone349bea2009-04-23 02:32:43 +0000735 T->isDependentType(),
736 (T->isDependentType() ||
737 CallExpr::hasAnyValueDependentArguments(args, numargs))),
Douglas Gregor16006c92009-12-16 18:50:27 +0000738 Constructor(D), Loc(Loc), Elidable(elidable),
Anders Carlsson72e96fd2010-05-02 22:54:08 +0000739 ZeroInitialization(ZeroInitialization), ConstructKind(ConstructKind),
740 Args(0), NumArgs(numargs)
Douglas Gregor16006c92009-12-16 18:50:27 +0000741{
742 if (NumArgs) {
743 Args = new (C) Stmt*[NumArgs];
744
745 for (unsigned i = 0; i != NumArgs; ++i) {
746 assert(args[i] && "NULL argument in CXXConstructExpr");
747 Args[i] = args[i];
Anders Carlssone349bea2009-04-23 02:32:43 +0000748 }
Douglas Gregor16006c92009-12-16 18:50:27 +0000749 }
Anders Carlssone349bea2009-04-23 02:32:43 +0000750}
751
Ted Kremenekd04ed412010-05-10 20:06:30 +0000752CXXExprWithTemporaries::CXXExprWithTemporaries(ASTContext &C,
753 Expr *subexpr,
Mike Stump1eb44332009-09-09 15:08:12 +0000754 CXXTemporary **temps,
Anders Carlsson0ece4912009-12-15 20:51:39 +0000755 unsigned numtemps)
Chris Lattnerd2598362010-05-10 00:25:06 +0000756 : Expr(CXXExprWithTemporariesClass, subexpr->getType(),
Mike Stump1eb44332009-09-09 15:08:12 +0000757 subexpr->isTypeDependent(), subexpr->isValueDependent()),
Chris Lattnerd2598362010-05-10 00:25:06 +0000758 SubExpr(subexpr), Temps(0), NumTemps(0) {
Chris Lattneraff32cb2010-05-10 00:45:12 +0000759 if (numtemps) {
Ted Kremenekd04ed412010-05-10 20:06:30 +0000760 setNumTemporaries(C, numtemps);
Chris Lattnerd2598362010-05-10 00:25:06 +0000761 for (unsigned i = 0; i != numtemps; ++i)
Anders Carlssonff6b3d62009-05-30 21:05:25 +0000762 Temps[i] = temps[i];
Anders Carlsson02bbfa32009-04-24 22:47:04 +0000763 }
764}
765
Ted Kremenekd04ed412010-05-10 20:06:30 +0000766void CXXExprWithTemporaries::setNumTemporaries(ASTContext &C, unsigned N) {
Chris Lattnerd2598362010-05-10 00:25:06 +0000767 assert(Temps == 0 && "Cannot resize with this");
Daniel Dunbar90556d42010-05-10 15:59:37 +0000768 NumTemps = N;
Ted Kremenekd04ed412010-05-10 20:06:30 +0000769 Temps = new (C) CXXTemporary*[NumTemps];
Chris Lattnerd2598362010-05-10 00:25:06 +0000770}
771
772
Mike Stump1eb44332009-09-09 15:08:12 +0000773CXXExprWithTemporaries *CXXExprWithTemporaries::Create(ASTContext &C,
Anders Carlsson88eaf072009-05-30 22:38:53 +0000774 Expr *SubExpr,
Mike Stump1eb44332009-09-09 15:08:12 +0000775 CXXTemporary **Temps,
Anders Carlsson0ece4912009-12-15 20:51:39 +0000776 unsigned NumTemps) {
Ted Kremenekd04ed412010-05-10 20:06:30 +0000777 return new (C) CXXExprWithTemporaries(C, SubExpr, Temps, NumTemps);
Anders Carlsson88eaf072009-05-30 22:38:53 +0000778}
779
Anders Carlssonfceb0a82009-05-30 20:03:25 +0000780// CXXBindTemporaryExpr
781Stmt::child_iterator CXXBindTemporaryExpr::child_begin() {
782 return &SubExpr;
783}
784
Mike Stump1eb44332009-09-09 15:08:12 +0000785Stmt::child_iterator CXXBindTemporaryExpr::child_end() {
Anders Carlssonfceb0a82009-05-30 20:03:25 +0000786 return &SubExpr + 1;
787}
788
Anders Carlssone349bea2009-04-23 02:32:43 +0000789// CXXConstructExpr
790Stmt::child_iterator CXXConstructExpr::child_begin() {
791 return &Args[0];
792}
793Stmt::child_iterator CXXConstructExpr::child_end() {
794 return &Args[0]+NumArgs;
795}
796
Anders Carlsson55674ac2009-05-01 22:21:22 +0000797// CXXExprWithTemporaries
798Stmt::child_iterator CXXExprWithTemporaries::child_begin() {
799 return &SubExpr;
Anders Carlsson19d28a62009-04-21 02:22:11 +0000800}
Anders Carlsson02bbfa32009-04-24 22:47:04 +0000801
Mike Stump1eb44332009-09-09 15:08:12 +0000802Stmt::child_iterator CXXExprWithTemporaries::child_end() {
Anders Carlsson55674ac2009-05-01 22:21:22 +0000803 return &SubExpr + 1;
804}
Anders Carlsson02bbfa32009-04-24 22:47:04 +0000805
Douglas Gregorab6677e2010-09-08 00:15:04 +0000806CXXUnresolvedConstructExpr::CXXUnresolvedConstructExpr(TypeSourceInfo *Type,
Douglas Gregord81e6ca2009-05-20 18:46:25 +0000807 SourceLocation LParenLoc,
808 Expr **Args,
809 unsigned NumArgs,
810 SourceLocation RParenLoc)
Douglas Gregorab6677e2010-09-08 00:15:04 +0000811 : Expr(CXXUnresolvedConstructExprClass,
812 Type->getType().getNonReferenceType(),
813 Type->getType()->isDependentType(), true),
814 Type(Type),
Douglas Gregord81e6ca2009-05-20 18:46:25 +0000815 LParenLoc(LParenLoc),
816 RParenLoc(RParenLoc),
817 NumArgs(NumArgs) {
818 Stmt **StoredArgs = reinterpret_cast<Stmt **>(this + 1);
819 memcpy(StoredArgs, Args, sizeof(Expr *) * NumArgs);
820}
821
822CXXUnresolvedConstructExpr *
Mike Stump1eb44332009-09-09 15:08:12 +0000823CXXUnresolvedConstructExpr::Create(ASTContext &C,
Douglas Gregorab6677e2010-09-08 00:15:04 +0000824 TypeSourceInfo *Type,
Douglas Gregord81e6ca2009-05-20 18:46:25 +0000825 SourceLocation LParenLoc,
826 Expr **Args,
827 unsigned NumArgs,
828 SourceLocation RParenLoc) {
829 void *Mem = C.Allocate(sizeof(CXXUnresolvedConstructExpr) +
830 sizeof(Expr *) * NumArgs);
Douglas Gregorab6677e2010-09-08 00:15:04 +0000831 return new (Mem) CXXUnresolvedConstructExpr(Type, LParenLoc,
Douglas Gregord81e6ca2009-05-20 18:46:25 +0000832 Args, NumArgs, RParenLoc);
833}
834
Argyrios Kyrtzidis8dfbd8b2010-06-24 08:57:31 +0000835CXXUnresolvedConstructExpr *
836CXXUnresolvedConstructExpr::CreateEmpty(ASTContext &C, unsigned NumArgs) {
837 Stmt::EmptyShell Empty;
838 void *Mem = C.Allocate(sizeof(CXXUnresolvedConstructExpr) +
839 sizeof(Expr *) * NumArgs);
840 return new (Mem) CXXUnresolvedConstructExpr(Empty, NumArgs);
841}
842
Douglas Gregorab6677e2010-09-08 00:15:04 +0000843SourceRange CXXUnresolvedConstructExpr::getSourceRange() const {
844 return SourceRange(Type->getTypeLoc().getBeginLoc(), RParenLoc);
845}
846
Douglas Gregord81e6ca2009-05-20 18:46:25 +0000847Stmt::child_iterator CXXUnresolvedConstructExpr::child_begin() {
848 return child_iterator(reinterpret_cast<Stmt **>(this + 1));
849}
850
851Stmt::child_iterator CXXUnresolvedConstructExpr::child_end() {
852 return child_iterator(reinterpret_cast<Stmt **>(this + 1) + NumArgs);
853}
Sebastian Redl8b0b4752009-05-16 18:50:46 +0000854
John McCall865d4472009-11-19 22:55:06 +0000855CXXDependentScopeMemberExpr::CXXDependentScopeMemberExpr(ASTContext &C,
John McCallaa81e162009-12-01 22:10:20 +0000856 Expr *Base, QualType BaseType,
857 bool IsArrow,
Douglas Gregor3b6afbb2009-09-09 00:23:06 +0000858 SourceLocation OperatorLoc,
859 NestedNameSpecifier *Qualifier,
860 SourceRange QualifierRange,
861 NamedDecl *FirstQualifierFoundInScope,
Abramo Bagnara25777432010-08-11 22:01:17 +0000862 DeclarationNameInfo MemberNameInfo,
John McCalld5532b62009-11-23 01:53:49 +0000863 const TemplateArgumentListInfo *TemplateArgs)
John McCall865d4472009-11-19 22:55:06 +0000864 : Expr(CXXDependentScopeMemberExprClass, C.DependentTy, true, true),
John McCallaa81e162009-12-01 22:10:20 +0000865 Base(Base), BaseType(BaseType), IsArrow(IsArrow),
866 HasExplicitTemplateArgs(TemplateArgs != 0),
Douglas Gregor3b6afbb2009-09-09 00:23:06 +0000867 OperatorLoc(OperatorLoc),
868 Qualifier(Qualifier), QualifierRange(QualifierRange),
869 FirstQualifierFoundInScope(FirstQualifierFoundInScope),
Abramo Bagnara25777432010-08-11 22:01:17 +0000870 MemberNameInfo(MemberNameInfo) {
John McCalld5532b62009-11-23 01:53:49 +0000871 if (TemplateArgs)
John McCall096832c2010-08-19 23:49:38 +0000872 getExplicitTemplateArgs().initializeFrom(*TemplateArgs);
Douglas Gregor3b6afbb2009-09-09 00:23:06 +0000873}
874
John McCall865d4472009-11-19 22:55:06 +0000875CXXDependentScopeMemberExpr *
876CXXDependentScopeMemberExpr::Create(ASTContext &C,
John McCallaa81e162009-12-01 22:10:20 +0000877 Expr *Base, QualType BaseType, bool IsArrow,
Douglas Gregor3b6afbb2009-09-09 00:23:06 +0000878 SourceLocation OperatorLoc,
879 NestedNameSpecifier *Qualifier,
880 SourceRange QualifierRange,
881 NamedDecl *FirstQualifierFoundInScope,
Abramo Bagnara25777432010-08-11 22:01:17 +0000882 DeclarationNameInfo MemberNameInfo,
John McCalld5532b62009-11-23 01:53:49 +0000883 const TemplateArgumentListInfo *TemplateArgs) {
884 if (!TemplateArgs)
John McCallaa81e162009-12-01 22:10:20 +0000885 return new (C) CXXDependentScopeMemberExpr(C, Base, BaseType,
886 IsArrow, OperatorLoc,
887 Qualifier, QualifierRange,
888 FirstQualifierFoundInScope,
Abramo Bagnara25777432010-08-11 22:01:17 +0000889 MemberNameInfo);
Mike Stump1eb44332009-09-09 15:08:12 +0000890
John McCalld5532b62009-11-23 01:53:49 +0000891 std::size_t size = sizeof(CXXDependentScopeMemberExpr);
892 if (TemplateArgs)
893 size += ExplicitTemplateArgumentList::sizeFor(*TemplateArgs);
894
895 void *Mem = C.Allocate(size, llvm::alignof<CXXDependentScopeMemberExpr>());
John McCallaa81e162009-12-01 22:10:20 +0000896 return new (Mem) CXXDependentScopeMemberExpr(C, Base, BaseType,
897 IsArrow, OperatorLoc,
898 Qualifier, QualifierRange,
899 FirstQualifierFoundInScope,
Abramo Bagnara25777432010-08-11 22:01:17 +0000900 MemberNameInfo, TemplateArgs);
Douglas Gregor3b6afbb2009-09-09 00:23:06 +0000901}
902
Argyrios Kyrtzidis8dfbd8b2010-06-24 08:57:31 +0000903CXXDependentScopeMemberExpr *
904CXXDependentScopeMemberExpr::CreateEmpty(ASTContext &C,
905 unsigned NumTemplateArgs) {
906 if (NumTemplateArgs == 0)
907 return new (C) CXXDependentScopeMemberExpr(C, 0, QualType(),
908 0, SourceLocation(), 0,
909 SourceRange(), 0,
Abramo Bagnara25777432010-08-11 22:01:17 +0000910 DeclarationNameInfo());
Argyrios Kyrtzidis8dfbd8b2010-06-24 08:57:31 +0000911
912 std::size_t size = sizeof(CXXDependentScopeMemberExpr) +
913 ExplicitTemplateArgumentList::sizeFor(NumTemplateArgs);
914 void *Mem = C.Allocate(size, llvm::alignof<CXXDependentScopeMemberExpr>());
915 CXXDependentScopeMemberExpr *E
916 = new (Mem) CXXDependentScopeMemberExpr(C, 0, QualType(),
917 0, SourceLocation(), 0,
918 SourceRange(), 0,
Abramo Bagnara25777432010-08-11 22:01:17 +0000919 DeclarationNameInfo(), 0);
Argyrios Kyrtzidis8dfbd8b2010-06-24 08:57:31 +0000920 E->HasExplicitTemplateArgs = true;
921 return E;
922}
923
John McCall865d4472009-11-19 22:55:06 +0000924Stmt::child_iterator CXXDependentScopeMemberExpr::child_begin() {
Douglas Gregor1c0ca592009-05-22 21:13:27 +0000925 return child_iterator(&Base);
926}
927
John McCall865d4472009-11-19 22:55:06 +0000928Stmt::child_iterator CXXDependentScopeMemberExpr::child_end() {
John McCallaa81e162009-12-01 22:10:20 +0000929 if (isImplicitAccess())
930 return child_iterator(&Base);
Douglas Gregor1c0ca592009-05-22 21:13:27 +0000931 return child_iterator(&Base + 1);
932}
John McCall129e2df2009-11-30 22:42:35 +0000933
Douglas Gregor928e6fc2010-05-23 19:36:40 +0000934UnresolvedMemberExpr::UnresolvedMemberExpr(ASTContext &C, QualType T,
935 bool Dependent,
John McCall129e2df2009-11-30 22:42:35 +0000936 bool HasUnresolvedUsing,
John McCallaa81e162009-12-01 22:10:20 +0000937 Expr *Base, QualType BaseType,
938 bool IsArrow,
John McCall129e2df2009-11-30 22:42:35 +0000939 SourceLocation OperatorLoc,
940 NestedNameSpecifier *Qualifier,
941 SourceRange QualifierRange,
Abramo Bagnara25777432010-08-11 22:01:17 +0000942 const DeclarationNameInfo &MemberNameInfo,
Douglas Gregor5a84dec2010-05-23 18:57:34 +0000943 const TemplateArgumentListInfo *TemplateArgs,
944 UnresolvedSetIterator Begin,
945 UnresolvedSetIterator End)
Douglas Gregor928e6fc2010-05-23 19:36:40 +0000946 : OverloadExpr(UnresolvedMemberExprClass, C, T, Dependent,
Abramo Bagnara25777432010-08-11 22:01:17 +0000947 Qualifier, QualifierRange, MemberNameInfo,
Douglas Gregor5a84dec2010-05-23 18:57:34 +0000948 TemplateArgs != 0, Begin, End),
John McCall7bb12da2010-02-02 06:20:04 +0000949 IsArrow(IsArrow), HasUnresolvedUsing(HasUnresolvedUsing),
950 Base(Base), BaseType(BaseType), OperatorLoc(OperatorLoc) {
John McCall129e2df2009-11-30 22:42:35 +0000951 if (TemplateArgs)
John McCall7bb12da2010-02-02 06:20:04 +0000952 getExplicitTemplateArgs().initializeFrom(*TemplateArgs);
John McCall129e2df2009-11-30 22:42:35 +0000953}
954
955UnresolvedMemberExpr *
956UnresolvedMemberExpr::Create(ASTContext &C, bool Dependent,
957 bool HasUnresolvedUsing,
John McCallaa81e162009-12-01 22:10:20 +0000958 Expr *Base, QualType BaseType, bool IsArrow,
John McCall129e2df2009-11-30 22:42:35 +0000959 SourceLocation OperatorLoc,
960 NestedNameSpecifier *Qualifier,
961 SourceRange QualifierRange,
Abramo Bagnara25777432010-08-11 22:01:17 +0000962 const DeclarationNameInfo &MemberNameInfo,
Douglas Gregor5a84dec2010-05-23 18:57:34 +0000963 const TemplateArgumentListInfo *TemplateArgs,
964 UnresolvedSetIterator Begin,
965 UnresolvedSetIterator End) {
John McCall129e2df2009-11-30 22:42:35 +0000966 std::size_t size = sizeof(UnresolvedMemberExpr);
967 if (TemplateArgs)
968 size += ExplicitTemplateArgumentList::sizeFor(*TemplateArgs);
969
970 void *Mem = C.Allocate(size, llvm::alignof<UnresolvedMemberExpr>());
Douglas Gregor928e6fc2010-05-23 19:36:40 +0000971 return new (Mem) UnresolvedMemberExpr(C,
John McCall129e2df2009-11-30 22:42:35 +0000972 Dependent ? C.DependentTy : C.OverloadTy,
John McCallaa81e162009-12-01 22:10:20 +0000973 Dependent, HasUnresolvedUsing, Base, BaseType,
974 IsArrow, OperatorLoc, Qualifier, QualifierRange,
Abramo Bagnara25777432010-08-11 22:01:17 +0000975 MemberNameInfo, TemplateArgs, Begin, End);
John McCall129e2df2009-11-30 22:42:35 +0000976}
977
Argyrios Kyrtzidisa77eb082010-06-25 09:03:26 +0000978UnresolvedMemberExpr *
979UnresolvedMemberExpr::CreateEmpty(ASTContext &C, unsigned NumTemplateArgs) {
980 std::size_t size = sizeof(UnresolvedMemberExpr);
981 if (NumTemplateArgs != 0)
982 size += ExplicitTemplateArgumentList::sizeFor(NumTemplateArgs);
983
984 void *Mem = C.Allocate(size, llvm::alignof<UnresolvedMemberExpr>());
985 UnresolvedMemberExpr *E = new (Mem) UnresolvedMemberExpr(EmptyShell());
986 E->HasExplicitTemplateArgs = NumTemplateArgs != 0;
987 return E;
988}
989
John McCallc373d482010-01-27 01:50:18 +0000990CXXRecordDecl *UnresolvedMemberExpr::getNamingClass() const {
991 // Unlike for UnresolvedLookupExpr, it is very easy to re-derive this.
992
993 // If there was a nested name specifier, it names the naming class.
994 // It can't be dependent: after all, we were actually able to do the
995 // lookup.
Douglas Gregorc96be1e2010-04-27 18:19:34 +0000996 CXXRecordDecl *Record = 0;
John McCall7bb12da2010-02-02 06:20:04 +0000997 if (getQualifier()) {
998 Type *T = getQualifier()->getAsType();
John McCallc373d482010-01-27 01:50:18 +0000999 assert(T && "qualifier in member expression does not name type");
Douglas Gregorc96be1e2010-04-27 18:19:34 +00001000 Record = T->getAsCXXRecordDecl();
1001 assert(Record && "qualifier in member expression does not name record");
1002 }
John McCallc373d482010-01-27 01:50:18 +00001003 // Otherwise the naming class must have been the base class.
Douglas Gregorc96be1e2010-04-27 18:19:34 +00001004 else {
John McCallc373d482010-01-27 01:50:18 +00001005 QualType BaseType = getBaseType().getNonReferenceType();
1006 if (isArrow()) {
1007 const PointerType *PT = BaseType->getAs<PointerType>();
1008 assert(PT && "base of arrow member access is not pointer");
1009 BaseType = PT->getPointeeType();
1010 }
1011
Douglas Gregorc96be1e2010-04-27 18:19:34 +00001012 Record = BaseType->getAsCXXRecordDecl();
1013 assert(Record && "base of member expression does not name record");
John McCallc373d482010-01-27 01:50:18 +00001014 }
1015
Douglas Gregorc96be1e2010-04-27 18:19:34 +00001016 return Record;
John McCallc373d482010-01-27 01:50:18 +00001017}
1018
John McCall129e2df2009-11-30 22:42:35 +00001019Stmt::child_iterator UnresolvedMemberExpr::child_begin() {
1020 return child_iterator(&Base);
1021}
1022
1023Stmt::child_iterator UnresolvedMemberExpr::child_end() {
John McCallaa81e162009-12-01 22:10:20 +00001024 if (isImplicitAccess())
1025 return child_iterator(&Base);
John McCall129e2df2009-11-30 22:42:35 +00001026 return child_iterator(&Base + 1);
1027}