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