blob: 5a9de19254d3be63974c5bb83e29d66911284259 [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;
Anders Carlsson1dae87f2009-03-22 01:52:17 +0000217 case UTT_IsAbstract:
218 if (const RecordType *RT = QueriedType->getAsRecordType())
219 return cast<CXXRecordDecl>(RT->getDecl())->isAbstract();
220 return false;
Sebastian Redl39c0f6f2009-01-05 20:52:13 +0000221 }
222}
223
Douglas Gregor65fedaf2008-11-14 16:09:21 +0000224SourceRange CXXOperatorCallExpr::getSourceRange() const {
225 OverloadedOperatorKind Kind = getOperator();
226 if (Kind == OO_PlusPlus || Kind == OO_MinusMinus) {
227 if (getNumArgs() == 1)
228 // Prefix operator
229 return SourceRange(getOperatorLoc(),
230 getArg(0)->getSourceRange().getEnd());
231 else
232 // Postfix operator
233 return SourceRange(getArg(0)->getSourceRange().getEnd(),
234 getOperatorLoc());
235 } else if (Kind == OO_Call) {
236 return SourceRange(getArg(0)->getSourceRange().getBegin(), getRParenLoc());
237 } else if (Kind == OO_Subscript) {
238 return SourceRange(getArg(0)->getSourceRange().getBegin(), getRParenLoc());
239 } else if (getNumArgs() == 1) {
240 return SourceRange(getOperatorLoc(), getArg(0)->getSourceRange().getEnd());
241 } else if (getNumArgs() == 2) {
242 return SourceRange(getArg(0)->getSourceRange().getBegin(),
243 getArg(1)->getSourceRange().getEnd());
244 } else {
245 return SourceRange();
246 }
247}
248
Douglas Gregor3257fb52008-12-22 05:46:06 +0000249Expr *CXXMemberCallExpr::getImplicitObjectArgument() {
250 if (MemberExpr *MemExpr = dyn_cast<MemberExpr>(getCallee()->IgnoreParens()))
251 return MemExpr->getBase();
252
253 // FIXME: Will eventually need to cope with member pointers.
254 return 0;
255}
256
Douglas Gregor21a04f32008-10-27 19:41:14 +0000257//===----------------------------------------------------------------------===//
258// Named casts
259//===----------------------------------------------------------------------===//
260
261/// getCastName - Get the name of the C++ cast being used, e.g.,
262/// "static_cast", "dynamic_cast", "reinterpret_cast", or
263/// "const_cast". The returned pointer must not be freed.
264const char *CXXNamedCastExpr::getCastName() const {
265 switch (getStmtClass()) {
266 case CXXStaticCastExprClass: return "static_cast";
267 case CXXDynamicCastExprClass: return "dynamic_cast";
268 case CXXReinterpretCastExprClass: return "reinterpret_cast";
269 case CXXConstCastExprClass: return "const_cast";
270 default: return "<invalid cast>";
271 }
272}
Douglas Gregor861e7902009-01-16 18:33:17 +0000273
274CXXTemporaryObjectExpr::CXXTemporaryObjectExpr(CXXConstructorDecl *Cons,
275 QualType writtenTy,
276 SourceLocation tyBeginLoc,
277 Expr **Args,
278 unsigned NumArgs,
279 SourceLocation rParenLoc)
Douglas Gregor396f1142009-03-13 21:01:28 +0000280 : Expr(CXXTemporaryObjectExprClass, writtenTy,
281 writtenTy->isDependentType(),
282 (writtenTy->isDependentType() ||
283 CallExpr::hasAnyValueDependentArguments(Args, NumArgs))),
Douglas Gregor861e7902009-01-16 18:33:17 +0000284 TyBeginLoc(tyBeginLoc), RParenLoc(rParenLoc),
285 Constructor(Cons), Args(0), NumArgs(NumArgs) {
286 if (NumArgs > 0) {
287 this->Args = new Stmt*[NumArgs];
288 for (unsigned i = 0; i < NumArgs; ++i)
289 this->Args[i] = Args[i];
290 }
291}
292
293CXXTemporaryObjectExpr::~CXXTemporaryObjectExpr() {
294 delete [] Args;
295}