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