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"
17 using namespace clang;
18 
19 void 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
32 Stmt::child_iterator CXXTypeidExpr::child_begin() {
33   return isTypeOperand() ? child_iterator() : &Operand.Ex;
34 }
35 Stmt::child_iterator CXXTypeidExpr::child_end() {
36   return isTypeOperand() ? child_iterator() : &Operand.Ex+1;
37 }
38 
39 // CXXBoolLiteralExpr
40 Stmt::child_iterator CXXBoolLiteralExpr::child_begin() {
41   return child_iterator();
42 }
43 Stmt::child_iterator CXXBoolLiteralExpr::child_end() {
44   return child_iterator();
45 }
46 
47 // CXXNullPtrLiteralExpr
48 Stmt::child_iterator CXXNullPtrLiteralExpr::child_begin() {
49   return child_iterator();
50 }
51 Stmt::child_iterator CXXNullPtrLiteralExpr::child_end() {
52   return child_iterator();
53 }
54 
55 // CXXThisExpr
56 Stmt::child_iterator CXXThisExpr::child_begin() { return child_iterator(); }
57 Stmt::child_iterator CXXThisExpr::child_end() { return child_iterator(); }
58 
59 // CXXThrowExpr
60 Stmt::child_iterator CXXThrowExpr::child_begin() { return &Op; }
61 Stmt::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
67 Stmt::child_iterator CXXDefaultArgExpr::child_begin() {
68   return child_iterator();
69 }
70 Stmt::child_iterator CXXDefaultArgExpr::child_end() {
71   return child_iterator();
72 }
73 
74 // CXXZeroInitValueExpr
75 Stmt::child_iterator CXXZeroInitValueExpr::child_begin() {
76   return child_iterator();
77 }
78 Stmt::child_iterator CXXZeroInitValueExpr::child_end() {
79   return child_iterator();
80 }
81 
82 // CXXConditionDeclExpr
83 Stmt::child_iterator CXXConditionDeclExpr::child_begin() {
84   return getVarDecl();
85 }
86 Stmt::child_iterator CXXConditionDeclExpr::child_end() {
87   return child_iterator();
88 }
89 
90 // CXXNewExpr
91 CXXNewExpr::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 
117 Stmt::child_iterator CXXNewExpr::child_begin() { return &SubExprs[0]; }
118 Stmt::child_iterator CXXNewExpr::child_end() {
119   return &SubExprs[0] + Array + getNumPlacementArgs() + getNumConstructorArgs();
120 }
121 
122 // CXXDeleteExpr
123 Stmt::child_iterator CXXDeleteExpr::child_begin() { return &Argument; }
124 Stmt::child_iterator CXXDeleteExpr::child_end() { return &Argument+1; }
125 
126 // UnresolvedFunctionNameExpr
127 Stmt::child_iterator UnresolvedFunctionNameExpr::child_begin() {
128   return child_iterator();
129 }
130 Stmt::child_iterator UnresolvedFunctionNameExpr::child_end() {
131   return child_iterator();
132 }
133 
134 UnresolvedFunctionNameExpr*
135 UnresolvedFunctionNameExpr::Clone(ASTContext &C) const {
136   return new (C) UnresolvedFunctionNameExpr(Name, getType(), Loc);
137 }
138 
139 // UnaryTypeTraitExpr
140 Stmt::child_iterator UnaryTypeTraitExpr::child_begin() {
141   return child_iterator();
142 }
143 Stmt::child_iterator UnaryTypeTraitExpr::child_end() {
144   return child_iterator();
145 }
146 
147 // UnresolvedDeclRefExpr
148 StmtIterator UnresolvedDeclRefExpr::child_begin() {
149   return child_iterator();
150 }
151 
152 StmtIterator UnresolvedDeclRefExpr::child_end() {
153   return child_iterator();
154 }
155 
156 bool 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 
189 SourceRange 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 
214 Expr *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.
229 const 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 
239 CXXTemporary *CXXTemporary::Create(ASTContext &C,
240                                    const CXXDestructorDecl *Destructor) {
241   return new (C) CXXTemporary(Destructor);
242 }
243 
244 void CXXTemporary::Destroy(ASTContext &C) {
245   this->~CXXTemporary();
246   C.Deallocate(this);
247 }
248 
249 CXXBindTemporaryExpr *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 
258 void CXXBindTemporaryExpr::Destroy(ASTContext &C) {
259   Temp->Destroy(C);
260   this->~CXXBindTemporaryExpr();
261   C.Deallocate(this);
262 }
263 
264 CXXTemporaryObjectExpr::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 
276 CXXConstructExpr *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 
283 CXXConstructExpr::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 
298 void CXXConstructExpr::Destroy(ASTContext &C) {
299   DestroyChildren(C);
300   if (Args)
301     C.Deallocate(Args);
302   this->~CXXConstructExpr();
303   C.Deallocate(this);
304 }
305 
306 CXXExprWithTemporaries::CXXExprWithTemporaries(Expr *subexpr,
307                                                CXXTemporary **temps,
308                                                unsigned numtemps,
309                                                bool destroytemps)
310 : Expr(CXXExprWithTemporariesClass, subexpr->getType(),
311        subexpr->isTypeDependent(), subexpr->isValueDependent()),
312   SubExpr(subexpr), Temps(0), NumTemps(numtemps), DestroyTemps(destroytemps) {
313   if (NumTemps > 0) {
314     Temps = new CXXTemporary*[NumTemps];
315     for (unsigned i = 0; i < NumTemps; ++i)
316       Temps[i] = temps[i];
317   }
318 }
319 
320 CXXExprWithTemporaries *CXXExprWithTemporaries::Create(ASTContext &C,
321                                                        Expr *SubExpr,
322                                                        CXXTemporary **Temps,
323                                                        unsigned NumTemps,
324                                                        bool DestroyTemps) {
325   return new (C) CXXExprWithTemporaries(SubExpr, Temps, NumTemps,
326                                         DestroyTemps);
327 }
328 
329 void CXXExprWithTemporaries::Destroy(ASTContext &C) {
330   DestroyChildren(C);
331   this->~CXXExprWithTemporaries();
332   C.Deallocate(this);
333 }
334 
335 CXXExprWithTemporaries::~CXXExprWithTemporaries() {
336   delete[] Temps;
337 }
338 
339 // CXXBindTemporaryExpr
340 Stmt::child_iterator CXXBindTemporaryExpr::child_begin() {
341   return &SubExpr;
342 }
343 
344 Stmt::child_iterator CXXBindTemporaryExpr::child_end() {
345   return &SubExpr + 1;
346 }
347 
348 // CXXConstructExpr
349 Stmt::child_iterator CXXConstructExpr::child_begin() {
350   return &Args[0];
351 }
352 Stmt::child_iterator CXXConstructExpr::child_end() {
353   return &Args[0]+NumArgs;
354 }
355 
356 // CXXExprWithTemporaries
357 Stmt::child_iterator CXXExprWithTemporaries::child_begin() {
358   return &SubExpr;
359 }
360 
361 Stmt::child_iterator CXXExprWithTemporaries::child_end() {
362   return &SubExpr + 1;
363 }
364 
365 CXXUnresolvedConstructExpr::CXXUnresolvedConstructExpr(
366                                                  SourceLocation TyBeginLoc,
367                                                  QualType T,
368                                                  SourceLocation LParenLoc,
369                                                  Expr **Args,
370                                                  unsigned NumArgs,
371                                                  SourceLocation RParenLoc)
372   : Expr(CXXUnresolvedConstructExprClass, T.getNonReferenceType(),
373          T->isDependentType(), true),
374     TyBeginLoc(TyBeginLoc),
375     Type(T),
376     LParenLoc(LParenLoc),
377     RParenLoc(RParenLoc),
378     NumArgs(NumArgs) {
379   Stmt **StoredArgs = reinterpret_cast<Stmt **>(this + 1);
380   memcpy(StoredArgs, Args, sizeof(Expr *) * NumArgs);
381 }
382 
383 CXXUnresolvedConstructExpr *
384 CXXUnresolvedConstructExpr::Create(ASTContext &C,
385                                    SourceLocation TyBegin,
386                                    QualType T,
387                                    SourceLocation LParenLoc,
388                                    Expr **Args,
389                                    unsigned NumArgs,
390                                    SourceLocation RParenLoc) {
391   void *Mem = C.Allocate(sizeof(CXXUnresolvedConstructExpr) +
392                          sizeof(Expr *) * NumArgs);
393   return new (Mem) CXXUnresolvedConstructExpr(TyBegin, T, LParenLoc,
394                                               Args, NumArgs, RParenLoc);
395 }
396 
397 Stmt::child_iterator CXXUnresolvedConstructExpr::child_begin() {
398   return child_iterator(reinterpret_cast<Stmt **>(this + 1));
399 }
400 
401 Stmt::child_iterator CXXUnresolvedConstructExpr::child_end() {
402   return child_iterator(reinterpret_cast<Stmt **>(this + 1) + NumArgs);
403 }
404 
405 Stmt::child_iterator CXXUnresolvedMemberExpr::child_begin() {
406   return child_iterator(&Base);
407 }
408 
409 Stmt::child_iterator CXXUnresolvedMemberExpr::child_end() {
410   return child_iterator(&Base + 1);
411 }
412 
413 //===----------------------------------------------------------------------===//
414 //  Cloners
415 //===----------------------------------------------------------------------===//
416 
417 CXXBoolLiteralExpr* CXXBoolLiteralExpr::Clone(ASTContext &C) const {
418   return new (C) CXXBoolLiteralExpr(Value, getType(), Loc);
419 }
420 
421 CXXNullPtrLiteralExpr* CXXNullPtrLiteralExpr::Clone(ASTContext &C) const {
422   return new (C) CXXNullPtrLiteralExpr(getType(), Loc);
423 }
424 
425 CXXZeroInitValueExpr* CXXZeroInitValueExpr::Clone(ASTContext &C) const {
426   return new (C) CXXZeroInitValueExpr(getType(), TyBeginLoc, RParenLoc);
427 }
428