blob: 53be84b20d2fe3206e9add877fe5c603cd9cd05f [file] [log] [blame]
Ted Kremenekfc7b6f72007-08-24 20:21:10 +00001//===--- ExprCXX.cpp - (C++) Expression AST Node Implementation -----------===//
2//
3// The LLVM Compiler Infrastructure
4//
Chris Lattner959e5be2007-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 Kremenekfc7b6f72007-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 Gregor65fedaf2008-11-14 16:09:21 +000014#include "clang/Basic/IdentifierTable.h"
15#include "clang/AST/DeclCXX.h"
Ted Kremenekfc7b6f72007-08-24 20:21:10 +000016#include "clang/AST/ExprCXX.h"
17using namespace clang;
18
Argiris Kirtzidis080b9cc2008-09-10 02:14:49 +000019void CXXConditionDeclExpr::Destroy(ASTContext& C) {
Sebastian Redl2ee55612009-02-05 15:12:41 +000020 // FIXME: Cannot destroy the decl here, because it is linked into the
21 // DeclContext's chain.
22 //getVarDecl()->Destroy(C);
Ted Kremenek0c97e042009-02-07 01:47:29 +000023 this->~CXXConditionDeclExpr();
24 C.Deallocate(this);
Argiris Kirtzidis080b9cc2008-09-10 02:14:49 +000025}
Argiris Kirtzidisdbce6c12008-09-09 23:47:53 +000026
Douglas Gregor7e508262009-03-19 03:51:16 +000027QualifiedDeclRefExpr::QualifiedDeclRefExpr(NamedDecl *d, QualType t,
28 SourceLocation l, bool TD,
29 bool VD, SourceRange R,
30 const NestedNameSpecifier *Components,
31 unsigned NumComponents)
32 : DeclRefExpr(QualifiedDeclRefExprClass, d, t, l, TD, VD),
33 QualifierRange(R), NumComponents(NumComponents) {
34 NestedNameSpecifier *Data
35 = reinterpret_cast<NestedNameSpecifier *>(this + 1);
36 for (unsigned I = 0; I < NumComponents; ++I)
37 Data[I] = Components[I];
38}
39
40QualifiedDeclRefExpr *
41QualifiedDeclRefExpr::Create(ASTContext &Context, NamedDecl *d, QualType t,
42 SourceLocation l, bool TD,
43 bool VD, SourceRange R,
44 const NestedNameSpecifier *Components,
45 unsigned NumComponents) {
46 void *Mem = Context.Allocate((sizeof(QualifiedDeclRefExpr) +
47 sizeof(NestedNameSpecifier) * NumComponents));
48 return new (Mem) QualifiedDeclRefExpr(d, t, l, TD, VD, R, Components,
49 NumComponents);
50}
51
Douglas Gregor47bde7c2009-03-19 17:26:29 +000052UnresolvedDeclRefExpr::UnresolvedDeclRefExpr(DeclarationName N, QualType T,
53 SourceLocation L, SourceRange R,
54 const NestedNameSpecifier *Components,
55 unsigned NumComponents)
56 : Expr(UnresolvedDeclRefExprClass, T, true, true),
57 Name(N), Loc(L), QualifierRange(R), NumComponents(NumComponents) {
58 NestedNameSpecifier *Data
59 = reinterpret_cast<NestedNameSpecifier *>(this + 1);
60 for (unsigned I = 0; I < NumComponents; ++I)
61 Data[I] = Components[I];
62}
63
64UnresolvedDeclRefExpr *
65UnresolvedDeclRefExpr::Create(ASTContext &Context, DeclarationName N,
66 SourceLocation L, SourceRange R,
67 const NestedNameSpecifier *Components,
68 unsigned NumComponents) {
69 void *Mem = Context.Allocate((sizeof(UnresolvedDeclRefExpr) +
70 sizeof(NestedNameSpecifier) * NumComponents));
71 return new (Mem) UnresolvedDeclRefExpr(N, Context.DependentTy, L, R,
72 Components, NumComponents);
73}
74
Ted Kremenekfc7b6f72007-08-24 20:21:10 +000075//===----------------------------------------------------------------------===//
76// Child Iterators for iterating over subexpressions/substatements
77//===----------------------------------------------------------------------===//
78
Sebastian Redlb93b49c2008-11-11 11:37:55 +000079// CXXTypeidExpr - has child iterators if the operand is an expression
80Stmt::child_iterator CXXTypeidExpr::child_begin() {
Sebastian Redl9f81c3f2008-12-03 23:17:54 +000081 return isTypeOperand() ? child_iterator() : &Operand.Ex;
Sebastian Redlb93b49c2008-11-11 11:37:55 +000082}
83Stmt::child_iterator CXXTypeidExpr::child_end() {
Sebastian Redl9f81c3f2008-12-03 23:17:54 +000084 return isTypeOperand() ? child_iterator() : &Operand.Ex+1;
Sebastian Redlb93b49c2008-11-11 11:37:55 +000085}
Ted Kremenekfc7b6f72007-08-24 20:21:10 +000086
Ted Kremenekfc7b6f72007-08-24 20:21:10 +000087// CXXBoolLiteralExpr
Ted Kremeneka6478552007-10-18 23:28:49 +000088Stmt::child_iterator CXXBoolLiteralExpr::child_begin() {
89 return child_iterator();
90}
91Stmt::child_iterator CXXBoolLiteralExpr::child_end() {
92 return child_iterator();
93}
Chris Lattnera7447ba2008-02-26 00:51:44 +000094
Douglas Gregora5b022a2008-11-04 14:32:21 +000095// CXXThisExpr
96Stmt::child_iterator CXXThisExpr::child_begin() { return child_iterator(); }
97Stmt::child_iterator CXXThisExpr::child_end() { return child_iterator(); }
98
Chris Lattnera7447ba2008-02-26 00:51:44 +000099// CXXThrowExpr
Ted Kremenek156714e2008-06-17 03:11:08 +0000100Stmt::child_iterator CXXThrowExpr::child_begin() { return &Op; }
Chris Lattnera7447ba2008-02-26 00:51:44 +0000101Stmt::child_iterator CXXThrowExpr::child_end() {
102 // If Op is 0, we are processing throw; which has no children.
Ted Kremenek156714e2008-06-17 03:11:08 +0000103 return Op ? &Op+1 : &Op;
Chris Lattnera7447ba2008-02-26 00:51:44 +0000104}
Chris Lattner3e254fb2008-04-08 04:40:51 +0000105
106// CXXDefaultArgExpr
107Stmt::child_iterator CXXDefaultArgExpr::child_begin() {
Chris Lattner97316c02008-04-10 02:22:51 +0000108 return child_iterator();
Chris Lattner3e254fb2008-04-08 04:40:51 +0000109}
110Stmt::child_iterator CXXDefaultArgExpr::child_end() {
Chris Lattner97316c02008-04-10 02:22:51 +0000111 return child_iterator();
Chris Lattner3e254fb2008-04-08 04:40:51 +0000112}
Argiris Kirtzidis7a1e7412008-08-22 15:38:55 +0000113
Douglas Gregor861e7902009-01-16 18:33:17 +0000114// CXXTemporaryObjectExpr
115Stmt::child_iterator CXXTemporaryObjectExpr::child_begin() {
116 return child_iterator(Args);
117}
118Stmt::child_iterator CXXTemporaryObjectExpr::child_end() {
119 return child_iterator(Args + NumArgs);
120}
121
Argiris Kirtzidis7a1e7412008-08-22 15:38:55 +0000122// CXXZeroInitValueExpr
123Stmt::child_iterator CXXZeroInitValueExpr::child_begin() {
124 return child_iterator();
125}
126Stmt::child_iterator CXXZeroInitValueExpr::child_end() {
127 return child_iterator();
128}
Argiris Kirtzidisdbce6c12008-09-09 23:47:53 +0000129
130// CXXConditionDeclExpr
131Stmt::child_iterator CXXConditionDeclExpr::child_begin() {
132 return getVarDecl();
133}
134Stmt::child_iterator CXXConditionDeclExpr::child_end() {
135 return child_iterator();
136}
Douglas Gregor21a04f32008-10-27 19:41:14 +0000137
Sebastian Redl19fec9d2008-11-21 19:14:01 +0000138// CXXNewExpr
139CXXNewExpr::CXXNewExpr(bool globalNew, FunctionDecl *operatorNew,
140 Expr **placementArgs, unsigned numPlaceArgs,
Sebastian Redl66df3ef2008-12-02 14:43:59 +0000141 bool parenTypeId, Expr *arraySize,
Sebastian Redl19fec9d2008-11-21 19:14:01 +0000142 CXXConstructorDecl *constructor, bool initializer,
143 Expr **constructorArgs, unsigned numConsArgs,
144 FunctionDecl *operatorDelete, QualType ty,
145 SourceLocation startLoc, SourceLocation endLoc)
Sebastian Redl6fdb28d2009-02-26 14:39:58 +0000146 : Expr(CXXNewExprClass, ty, ty->isDependentType(), ty->isDependentType()),
147 GlobalNew(globalNew), ParenTypeId(parenTypeId),
Sebastian Redl66df3ef2008-12-02 14:43:59 +0000148 Initializer(initializer), Array(arraySize), NumPlacementArgs(numPlaceArgs),
Sebastian Redl19fec9d2008-11-21 19:14:01 +0000149 NumConstructorArgs(numConsArgs), OperatorNew(operatorNew),
Sebastian Redl66df3ef2008-12-02 14:43:59 +0000150 OperatorDelete(operatorDelete), Constructor(constructor),
Sebastian Redl19fec9d2008-11-21 19:14:01 +0000151 StartLoc(startLoc), EndLoc(endLoc)
152{
Sebastian Redl66df3ef2008-12-02 14:43:59 +0000153 unsigned TotalSize = Array + NumPlacementArgs + NumConstructorArgs;
Sebastian Redl19fec9d2008-11-21 19:14:01 +0000154 SubExprs = new Stmt*[TotalSize];
155 unsigned i = 0;
Sebastian Redl66df3ef2008-12-02 14:43:59 +0000156 if (Array)
157 SubExprs[i++] = arraySize;
158 for (unsigned j = 0; j < NumPlacementArgs; ++j)
Sebastian Redl19fec9d2008-11-21 19:14:01 +0000159 SubExprs[i++] = placementArgs[j];
Sebastian Redl66df3ef2008-12-02 14:43:59 +0000160 for (unsigned j = 0; j < NumConstructorArgs; ++j)
Sebastian Redl19fec9d2008-11-21 19:14:01 +0000161 SubExprs[i++] = constructorArgs[j];
162 assert(i == TotalSize);
163}
164
165Stmt::child_iterator CXXNewExpr::child_begin() { return &SubExprs[0]; }
166Stmt::child_iterator CXXNewExpr::child_end() {
Sebastian Redl66df3ef2008-12-02 14:43:59 +0000167 return &SubExprs[0] + Array + getNumPlacementArgs() + getNumConstructorArgs();
Sebastian Redl19fec9d2008-11-21 19:14:01 +0000168}
169
170// CXXDeleteExpr
171Stmt::child_iterator CXXDeleteExpr::child_begin() { return &Argument; }
172Stmt::child_iterator CXXDeleteExpr::child_end() { return &Argument+1; }
173
Douglas Gregor4646f9c2009-02-04 15:01:18 +0000174// UnresolvedFunctionNameExpr
175Stmt::child_iterator UnresolvedFunctionNameExpr::child_begin() {
Douglas Gregora133e262008-12-06 00:22:45 +0000176 return child_iterator();
177}
Douglas Gregor4646f9c2009-02-04 15:01:18 +0000178Stmt::child_iterator UnresolvedFunctionNameExpr::child_end() {
Douglas Gregora133e262008-12-06 00:22:45 +0000179 return child_iterator();
180}
181
Sebastian Redl39c0f6f2009-01-05 20:52:13 +0000182// UnaryTypeTraitExpr
183Stmt::child_iterator UnaryTypeTraitExpr::child_begin() {
184 return child_iterator();
185}
186Stmt::child_iterator UnaryTypeTraitExpr::child_end() {
187 return child_iterator();
188}
189
Douglas Gregor47bde7c2009-03-19 17:26:29 +0000190// UnresolvedDeclRefExpr
191StmtIterator UnresolvedDeclRefExpr::child_begin() {
192 return child_iterator();
193}
194
195StmtIterator UnresolvedDeclRefExpr::child_end() {
196 return child_iterator();
197}
198
Daniel Dunbar8360a9c2009-02-17 23:20:26 +0000199bool UnaryTypeTraitExpr::EvaluateTrait() const {
Sebastian Redl39c0f6f2009-01-05 20:52:13 +0000200 switch(UTT) {
201 default: assert(false && "Unknown type trait or not implemented");
202 case UTT_IsPOD: return QueriedType->isPODType();
203 case UTT_IsClass: // Fallthrough
204 case UTT_IsUnion:
205 if (const RecordType *Record = QueriedType->getAsRecordType()) {
206 bool Union = Record->getDecl()->isUnion();
207 return UTT == UTT_IsUnion ? Union : !Union;
208 }
209 return false;
210 case UTT_IsEnum: return QueriedType->isEnumeralType();
211 case UTT_IsPolymorphic:
212 if (const RecordType *Record = QueriedType->getAsRecordType()) {
213 // Type traits are only parsed in C++, so we've got CXXRecords.
214 return cast<CXXRecordDecl>(Record->getDecl())->isPolymorphic();
215 }
216 return false;
217 }
218}
219
Douglas Gregor65fedaf2008-11-14 16:09:21 +0000220SourceRange CXXOperatorCallExpr::getSourceRange() const {
221 OverloadedOperatorKind Kind = getOperator();
222 if (Kind == OO_PlusPlus || Kind == OO_MinusMinus) {
223 if (getNumArgs() == 1)
224 // Prefix operator
225 return SourceRange(getOperatorLoc(),
226 getArg(0)->getSourceRange().getEnd());
227 else
228 // Postfix operator
229 return SourceRange(getArg(0)->getSourceRange().getEnd(),
230 getOperatorLoc());
231 } else if (Kind == OO_Call) {
232 return SourceRange(getArg(0)->getSourceRange().getBegin(), getRParenLoc());
233 } else if (Kind == OO_Subscript) {
234 return SourceRange(getArg(0)->getSourceRange().getBegin(), getRParenLoc());
235 } else if (getNumArgs() == 1) {
236 return SourceRange(getOperatorLoc(), getArg(0)->getSourceRange().getEnd());
237 } else if (getNumArgs() == 2) {
238 return SourceRange(getArg(0)->getSourceRange().getBegin(),
239 getArg(1)->getSourceRange().getEnd());
240 } else {
241 return SourceRange();
242 }
243}
244
Douglas Gregor3257fb52008-12-22 05:46:06 +0000245Expr *CXXMemberCallExpr::getImplicitObjectArgument() {
246 if (MemberExpr *MemExpr = dyn_cast<MemberExpr>(getCallee()->IgnoreParens()))
247 return MemExpr->getBase();
248
249 // FIXME: Will eventually need to cope with member pointers.
250 return 0;
251}
252
Douglas Gregor21a04f32008-10-27 19:41:14 +0000253//===----------------------------------------------------------------------===//
254// Named casts
255//===----------------------------------------------------------------------===//
256
257/// getCastName - Get the name of the C++ cast being used, e.g.,
258/// "static_cast", "dynamic_cast", "reinterpret_cast", or
259/// "const_cast". The returned pointer must not be freed.
260const char *CXXNamedCastExpr::getCastName() const {
261 switch (getStmtClass()) {
262 case CXXStaticCastExprClass: return "static_cast";
263 case CXXDynamicCastExprClass: return "dynamic_cast";
264 case CXXReinterpretCastExprClass: return "reinterpret_cast";
265 case CXXConstCastExprClass: return "const_cast";
266 default: return "<invalid cast>";
267 }
268}
Douglas Gregor861e7902009-01-16 18:33:17 +0000269
270CXXTemporaryObjectExpr::CXXTemporaryObjectExpr(CXXConstructorDecl *Cons,
271 QualType writtenTy,
272 SourceLocation tyBeginLoc,
273 Expr **Args,
274 unsigned NumArgs,
275 SourceLocation rParenLoc)
Douglas Gregor396f1142009-03-13 21:01:28 +0000276 : Expr(CXXTemporaryObjectExprClass, writtenTy,
277 writtenTy->isDependentType(),
278 (writtenTy->isDependentType() ||
279 CallExpr::hasAnyValueDependentArguments(Args, NumArgs))),
Douglas Gregor861e7902009-01-16 18:33:17 +0000280 TyBeginLoc(tyBeginLoc), RParenLoc(rParenLoc),
281 Constructor(Cons), Args(0), NumArgs(NumArgs) {
282 if (NumArgs > 0) {
283 this->Args = new Stmt*[NumArgs];
284 for (unsigned i = 0; i < NumArgs; ++i)
285 this->Args[i] = Args[i];
286 }
287}
288
289CXXTemporaryObjectExpr::~CXXTemporaryObjectExpr() {
290 delete [] Args;
291}