ExprCXX.cpp revision cb8e0c060390e2a97c736aab525eb1127b7d0176
1//===--- ExprCXX.cpp - (C++) Expression AST Node Implementation -----------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the subclesses of Expr class declared in ExprCXX.h
11//
12//===----------------------------------------------------------------------===//
13
14#include "clang/Basic/IdentifierTable.h"
15#include "clang/AST/DeclCXX.h"
16#include "clang/AST/ExprCXX.h"
17using namespace clang;
18
19void CXXConditionDeclExpr::Destroy(ASTContext& C) {
20  // FIXME: Cannot destroy the decl here, because it is linked into the
21  // DeclContext's chain.
22  //getVarDecl()->Destroy(C);
23  this->~CXXConditionDeclExpr();
24  C.Deallocate(this);
25}
26
27//===----------------------------------------------------------------------===//
28//  Child Iterators for iterating over subexpressions/substatements
29//===----------------------------------------------------------------------===//
30
31// CXXTypeidExpr - has child iterators if the operand is an expression
32Stmt::child_iterator CXXTypeidExpr::child_begin() {
33  return isTypeOperand() ? child_iterator() : &Operand.Ex;
34}
35Stmt::child_iterator CXXTypeidExpr::child_end() {
36  return isTypeOperand() ? child_iterator() : &Operand.Ex+1;
37}
38
39// CXXBoolLiteralExpr
40Stmt::child_iterator CXXBoolLiteralExpr::child_begin() {
41  return child_iterator();
42}
43Stmt::child_iterator CXXBoolLiteralExpr::child_end() {
44  return child_iterator();
45}
46
47// CXXNullPtrLiteralExpr
48Stmt::child_iterator CXXNullPtrLiteralExpr::child_begin() {
49  return child_iterator();
50}
51Stmt::child_iterator CXXNullPtrLiteralExpr::child_end() {
52  return child_iterator();
53}
54
55// CXXThisExpr
56Stmt::child_iterator CXXThisExpr::child_begin() { return child_iterator(); }
57Stmt::child_iterator CXXThisExpr::child_end() { return child_iterator(); }
58
59// CXXThrowExpr
60Stmt::child_iterator CXXThrowExpr::child_begin() { return &Op; }
61Stmt::child_iterator CXXThrowExpr::child_end() {
62  // If Op is 0, we are processing throw; which has no children.
63  return Op ? &Op+1 : &Op;
64}
65
66// CXXDefaultArgExpr
67Stmt::child_iterator CXXDefaultArgExpr::child_begin() {
68  return child_iterator();
69}
70Stmt::child_iterator CXXDefaultArgExpr::child_end() {
71  return child_iterator();
72}
73
74// CXXZeroInitValueExpr
75Stmt::child_iterator CXXZeroInitValueExpr::child_begin() {
76  return child_iterator();
77}
78Stmt::child_iterator CXXZeroInitValueExpr::child_end() {
79  return child_iterator();
80}
81
82// CXXConditionDeclExpr
83Stmt::child_iterator CXXConditionDeclExpr::child_begin() {
84  return getVarDecl();
85}
86Stmt::child_iterator CXXConditionDeclExpr::child_end() {
87  return child_iterator();
88}
89
90// CXXNewExpr
91CXXNewExpr::CXXNewExpr(bool globalNew, FunctionDecl *operatorNew,
92                       Expr **placementArgs, unsigned numPlaceArgs,
93                       bool parenTypeId, Expr *arraySize,
94                       CXXConstructorDecl *constructor, bool initializer,
95                       Expr **constructorArgs, unsigned numConsArgs,
96                       FunctionDecl *operatorDelete, QualType ty,
97                       SourceLocation startLoc, SourceLocation endLoc)
98  : Expr(CXXNewExprClass, ty, ty->isDependentType(), ty->isDependentType()),
99    GlobalNew(globalNew), ParenTypeId(parenTypeId),
100    Initializer(initializer), Array(arraySize), NumPlacementArgs(numPlaceArgs),
101    NumConstructorArgs(numConsArgs), OperatorNew(operatorNew),
102    OperatorDelete(operatorDelete), Constructor(constructor),
103    StartLoc(startLoc), EndLoc(endLoc)
104{
105  unsigned TotalSize = Array + NumPlacementArgs + NumConstructorArgs;
106  SubExprs = new Stmt*[TotalSize];
107  unsigned i = 0;
108  if (Array)
109    SubExprs[i++] = arraySize;
110  for (unsigned j = 0; j < NumPlacementArgs; ++j)
111    SubExprs[i++] = placementArgs[j];
112  for (unsigned j = 0; j < NumConstructorArgs; ++j)
113    SubExprs[i++] = constructorArgs[j];
114  assert(i == TotalSize);
115}
116
117Stmt::child_iterator CXXNewExpr::child_begin() { return &SubExprs[0]; }
118Stmt::child_iterator CXXNewExpr::child_end() {
119  return &SubExprs[0] + Array + getNumPlacementArgs() + getNumConstructorArgs();
120}
121
122// CXXDeleteExpr
123Stmt::child_iterator CXXDeleteExpr::child_begin() { return &Argument; }
124Stmt::child_iterator CXXDeleteExpr::child_end() { return &Argument+1; }
125
126// UnresolvedFunctionNameExpr
127Stmt::child_iterator UnresolvedFunctionNameExpr::child_begin() {
128  return child_iterator();
129}
130Stmt::child_iterator UnresolvedFunctionNameExpr::child_end() {
131  return child_iterator();
132}
133
134UnresolvedFunctionNameExpr*
135UnresolvedFunctionNameExpr::Clone(ASTContext &C) const {
136  return new (C) UnresolvedFunctionNameExpr(Name, getType(), Loc);
137}
138
139// UnaryTypeTraitExpr
140Stmt::child_iterator UnaryTypeTraitExpr::child_begin() {
141  return child_iterator();
142}
143Stmt::child_iterator UnaryTypeTraitExpr::child_end() {
144  return child_iterator();
145}
146
147// UnresolvedDeclRefExpr
148StmtIterator UnresolvedDeclRefExpr::child_begin() {
149  return child_iterator();
150}
151
152StmtIterator UnresolvedDeclRefExpr::child_end() {
153  return child_iterator();
154}
155
156bool UnaryTypeTraitExpr::EvaluateTrait() const {
157  switch(UTT) {
158  default: assert(false && "Unknown type trait or not implemented");
159  case UTT_IsPOD: return QueriedType->isPODType();
160  case UTT_IsClass: // Fallthrough
161  case UTT_IsUnion:
162    if (const RecordType *Record = QueriedType->getAsRecordType()) {
163      bool Union = Record->getDecl()->isUnion();
164      return UTT == UTT_IsUnion ? Union : !Union;
165    }
166    return false;
167  case UTT_IsEnum: return QueriedType->isEnumeralType();
168  case UTT_IsPolymorphic:
169    if (const RecordType *Record = QueriedType->getAsRecordType()) {
170      // Type traits are only parsed in C++, so we've got CXXRecords.
171      return cast<CXXRecordDecl>(Record->getDecl())->isPolymorphic();
172    }
173    return false;
174  case UTT_IsAbstract:
175    if (const RecordType *RT = QueriedType->getAsRecordType())
176      return cast<CXXRecordDecl>(RT->getDecl())->isAbstract();
177    return false;
178  case UTT_HasTrivialConstructor:
179    if (const RecordType *RT = QueriedType->getAsRecordType())
180      return cast<CXXRecordDecl>(RT->getDecl())->hasTrivialConstructor();
181    return false;
182  case UTT_HasTrivialDestructor:
183    if (const RecordType *RT = QueriedType->getAsRecordType())
184      return cast<CXXRecordDecl>(RT->getDecl())->hasTrivialDestructor();
185    return false;
186  }
187}
188
189SourceRange CXXOperatorCallExpr::getSourceRange() const {
190  OverloadedOperatorKind Kind = getOperator();
191  if (Kind == OO_PlusPlus || Kind == OO_MinusMinus) {
192    if (getNumArgs() == 1)
193      // Prefix operator
194      return SourceRange(getOperatorLoc(),
195                         getArg(0)->getSourceRange().getEnd());
196    else
197      // Postfix operator
198      return SourceRange(getArg(0)->getSourceRange().getEnd(),
199                         getOperatorLoc());
200  } else if (Kind == OO_Call) {
201    return SourceRange(getArg(0)->getSourceRange().getBegin(), getRParenLoc());
202  } else if (Kind == OO_Subscript) {
203    return SourceRange(getArg(0)->getSourceRange().getBegin(), getRParenLoc());
204  } else if (getNumArgs() == 1) {
205    return SourceRange(getOperatorLoc(), getArg(0)->getSourceRange().getEnd());
206  } else if (getNumArgs() == 2) {
207    return SourceRange(getArg(0)->getSourceRange().getBegin(),
208                       getArg(1)->getSourceRange().getEnd());
209  } else {
210    return SourceRange();
211  }
212}
213
214Expr *CXXMemberCallExpr::getImplicitObjectArgument() {
215  if (MemberExpr *MemExpr = dyn_cast<MemberExpr>(getCallee()->IgnoreParens()))
216    return MemExpr->getBase();
217
218  // FIXME: Will eventually need to cope with member pointers.
219  return 0;
220}
221
222//===----------------------------------------------------------------------===//
223//  Named casts
224//===----------------------------------------------------------------------===//
225
226/// getCastName - Get the name of the C++ cast being used, e.g.,
227/// "static_cast", "dynamic_cast", "reinterpret_cast", or
228/// "const_cast". The returned pointer must not be freed.
229const char *CXXNamedCastExpr::getCastName() const {
230  switch (getStmtClass()) {
231  case CXXStaticCastExprClass:      return "static_cast";
232  case CXXDynamicCastExprClass:     return "dynamic_cast";
233  case CXXReinterpretCastExprClass: return "reinterpret_cast";
234  case CXXConstCastExprClass:       return "const_cast";
235  default:                          return "<invalid cast>";
236  }
237}
238
239CXXTemporary *CXXTemporary::Create(ASTContext &C,
240                                   const CXXDestructorDecl *Destructor) {
241  return new (C) CXXTemporary(Destructor);
242}
243
244void CXXTemporary::Destroy(ASTContext &C) {
245  this->~CXXTemporary();
246  C.Deallocate(this);
247}
248
249CXXBindTemporaryExpr *CXXBindTemporaryExpr::Create(ASTContext &C,
250                                                   CXXTemporary *Temp,
251                                                   Expr* SubExpr) {
252  assert(SubExpr->getType()->isRecordType() &&
253         "Expression bound to a temporary must have record type!");
254
255  return new (C) CXXBindTemporaryExpr(Temp, SubExpr);
256}
257
258void CXXBindTemporaryExpr::Destroy(ASTContext &C) {
259  Temp->Destroy(C);
260  this->~CXXBindTemporaryExpr();
261  C.Deallocate(this);
262}
263
264CXXTemporaryObjectExpr::CXXTemporaryObjectExpr(ASTContext &C,
265                                               CXXConstructorDecl *Cons,
266                                               QualType writtenTy,
267                                               SourceLocation tyBeginLoc,
268                                               Expr **Args,
269                                               unsigned NumArgs,
270                                               SourceLocation rParenLoc)
271  : CXXConstructExpr(C, CXXTemporaryObjectExprClass, writtenTy, Cons,
272                     false, Args, NumArgs),
273  TyBeginLoc(tyBeginLoc), RParenLoc(rParenLoc) {
274}
275
276CXXConstructExpr *CXXConstructExpr::Create(ASTContext &C, QualType T,
277                                           CXXConstructorDecl *D, bool Elidable,
278                                           Expr **Args, unsigned NumArgs) {
279  return new (C) CXXConstructExpr(C, CXXConstructExprClass, T, D, Elidable,
280                                  Args, NumArgs);
281}
282
283CXXConstructExpr::CXXConstructExpr(ASTContext &C, StmtClass SC, QualType T,
284                                   CXXConstructorDecl *D, bool elidable,
285                                   Expr **args, unsigned numargs)
286: Expr(SC, T,
287       T->isDependentType(),
288       (T->isDependentType() ||
289        CallExpr::hasAnyValueDependentArguments(args, numargs))),
290  Constructor(D), Elidable(elidable), Args(0), NumArgs(numargs) {
291    if (NumArgs > 0) {
292      Args = new (C) Stmt*[NumArgs];
293      for (unsigned i = 0; i < NumArgs; ++i)
294        Args[i] = args[i];
295    }
296}
297
298void CXXConstructExpr::Destroy(ASTContext &C) {
299  DestroyChildren(C);
300  if (Args)
301    C.Deallocate(Args);
302  this->~CXXConstructExpr();
303  C.Deallocate(this);
304}
305
306CXXExprWithTemporaries::CXXExprWithTemporaries(Expr *subexpr,
307                                               CXXTemporary **temps,
308                                               unsigned numtemps)
309: Expr(CXXExprWithTemporariesClass, subexpr->getType(),
310       subexpr->isTypeDependent(), subexpr->isValueDependent()),
311  SubExpr(subexpr), Temps(0), NumTemps(numtemps) {
312  if (NumTemps > 0) {
313    Temps = new CXXTemporary*[NumTemps];
314    for (unsigned i = 0; i < NumTemps; ++i)
315      Temps[i] = temps[i];
316  }
317}
318
319CXXExprWithTemporaries *CXXExprWithTemporaries::Create(ASTContext &C,
320                                                       Expr *SubExpr,
321                                                       CXXTemporary **Temps,
322                                                       unsigned NumTemps) {
323  return new (C) CXXExprWithTemporaries(SubExpr, Temps, NumTemps);
324}
325
326void CXXExprWithTemporaries::Destroy(ASTContext &C) {
327  DestroyChildren(C);
328  this->~CXXExprWithTemporaries();
329  C.Deallocate(this);
330}
331
332CXXExprWithTemporaries::~CXXExprWithTemporaries() {
333  delete[] Temps;
334}
335
336// CXXBindTemporaryExpr
337Stmt::child_iterator CXXBindTemporaryExpr::child_begin() {
338  return &SubExpr;
339}
340
341Stmt::child_iterator CXXBindTemporaryExpr::child_end() {
342  return &SubExpr + 1;
343}
344
345// CXXConstructExpr
346Stmt::child_iterator CXXConstructExpr::child_begin() {
347  return &Args[0];
348}
349Stmt::child_iterator CXXConstructExpr::child_end() {
350  return &Args[0]+NumArgs;
351}
352
353// CXXExprWithTemporaries
354Stmt::child_iterator CXXExprWithTemporaries::child_begin() {
355  return &SubExpr;
356}
357
358Stmt::child_iterator CXXExprWithTemporaries::child_end() {
359  return &SubExpr + 1;
360}
361
362CXXUnresolvedConstructExpr::CXXUnresolvedConstructExpr(
363                                                 SourceLocation TyBeginLoc,
364                                                 QualType T,
365                                                 SourceLocation LParenLoc,
366                                                 Expr **Args,
367                                                 unsigned NumArgs,
368                                                 SourceLocation RParenLoc)
369  : Expr(CXXUnresolvedConstructExprClass, T.getNonReferenceType(),
370         T->isDependentType(), true),
371    TyBeginLoc(TyBeginLoc),
372    Type(T),
373    LParenLoc(LParenLoc),
374    RParenLoc(RParenLoc),
375    NumArgs(NumArgs) {
376  Stmt **StoredArgs = reinterpret_cast<Stmt **>(this + 1);
377  memcpy(StoredArgs, Args, sizeof(Expr *) * NumArgs);
378}
379
380CXXUnresolvedConstructExpr *
381CXXUnresolvedConstructExpr::Create(ASTContext &C,
382                                   SourceLocation TyBegin,
383                                   QualType T,
384                                   SourceLocation LParenLoc,
385                                   Expr **Args,
386                                   unsigned NumArgs,
387                                   SourceLocation RParenLoc) {
388  void *Mem = C.Allocate(sizeof(CXXUnresolvedConstructExpr) +
389                         sizeof(Expr *) * NumArgs);
390  return new (Mem) CXXUnresolvedConstructExpr(TyBegin, T, LParenLoc,
391                                              Args, NumArgs, RParenLoc);
392}
393
394Stmt::child_iterator CXXUnresolvedConstructExpr::child_begin() {
395  return child_iterator(reinterpret_cast<Stmt **>(this + 1));
396}
397
398Stmt::child_iterator CXXUnresolvedConstructExpr::child_end() {
399  return child_iterator(reinterpret_cast<Stmt **>(this + 1) + NumArgs);
400}
401
402Stmt::child_iterator CXXUnresolvedMemberExpr::child_begin() {
403  return child_iterator(&Base);
404}
405
406Stmt::child_iterator CXXUnresolvedMemberExpr::child_end() {
407  return child_iterator(&Base + 1);
408}
409
410//===----------------------------------------------------------------------===//
411//  Cloners
412//===----------------------------------------------------------------------===//
413
414CXXBoolLiteralExpr* CXXBoolLiteralExpr::Clone(ASTContext &C) const {
415  return new (C) CXXBoolLiteralExpr(Value, getType(), Loc);
416}
417
418CXXNullPtrLiteralExpr* CXXNullPtrLiteralExpr::Clone(ASTContext &C) const {
419  return new (C) CXXNullPtrLiteralExpr(getType(), Loc);
420}
421
422CXXZeroInitValueExpr* CXXZeroInitValueExpr::Clone(ASTContext &C) const {
423  return new (C) CXXZeroInitValueExpr(getType(), TyBeginLoc, RParenLoc);
424}
425