ExprCXX.cpp revision 3257fb58ef6583ce20036c77a8c5af95f158f2d3
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 getVarDecl()->Destroy(C); 21 delete this; 22} 23 24 25//===----------------------------------------------------------------------===// 26// Child Iterators for iterating over subexpressions/substatements 27//===----------------------------------------------------------------------===// 28 29// CXXTypeidExpr - has child iterators if the operand is an expression 30Stmt::child_iterator CXXTypeidExpr::child_begin() { 31 return isTypeOperand() ? child_iterator() : &Operand.Ex; 32} 33Stmt::child_iterator CXXTypeidExpr::child_end() { 34 return isTypeOperand() ? child_iterator() : &Operand.Ex+1; 35} 36 37// CXXBoolLiteralExpr 38Stmt::child_iterator CXXBoolLiteralExpr::child_begin() { 39 return child_iterator(); 40} 41Stmt::child_iterator CXXBoolLiteralExpr::child_end() { 42 return child_iterator(); 43} 44 45// CXXThisExpr 46Stmt::child_iterator CXXThisExpr::child_begin() { return child_iterator(); } 47Stmt::child_iterator CXXThisExpr::child_end() { return child_iterator(); } 48 49// CXXThrowExpr 50Stmt::child_iterator CXXThrowExpr::child_begin() { return &Op; } 51Stmt::child_iterator CXXThrowExpr::child_end() { 52 // If Op is 0, we are processing throw; which has no children. 53 return Op ? &Op+1 : &Op; 54} 55 56// CXXDefaultArgExpr 57Stmt::child_iterator CXXDefaultArgExpr::child_begin() { 58 return child_iterator(); 59} 60Stmt::child_iterator CXXDefaultArgExpr::child_end() { 61 return child_iterator(); 62} 63 64// CXXZeroInitValueExpr 65Stmt::child_iterator CXXZeroInitValueExpr::child_begin() { 66 return child_iterator(); 67} 68Stmt::child_iterator CXXZeroInitValueExpr::child_end() { 69 return child_iterator(); 70} 71 72// CXXConditionDeclExpr 73Stmt::child_iterator CXXConditionDeclExpr::child_begin() { 74 return getVarDecl(); 75} 76Stmt::child_iterator CXXConditionDeclExpr::child_end() { 77 return child_iterator(); 78} 79 80// CXXNewExpr 81CXXNewExpr::CXXNewExpr(bool globalNew, FunctionDecl *operatorNew, 82 Expr **placementArgs, unsigned numPlaceArgs, 83 bool parenTypeId, Expr *arraySize, 84 CXXConstructorDecl *constructor, bool initializer, 85 Expr **constructorArgs, unsigned numConsArgs, 86 FunctionDecl *operatorDelete, QualType ty, 87 SourceLocation startLoc, SourceLocation endLoc) 88 : Expr(CXXNewExprClass, ty), GlobalNew(globalNew), ParenTypeId(parenTypeId), 89 Initializer(initializer), Array(arraySize), NumPlacementArgs(numPlaceArgs), 90 NumConstructorArgs(numConsArgs), OperatorNew(operatorNew), 91 OperatorDelete(operatorDelete), Constructor(constructor), 92 StartLoc(startLoc), EndLoc(endLoc) 93{ 94 unsigned TotalSize = Array + NumPlacementArgs + NumConstructorArgs; 95 SubExprs = new Stmt*[TotalSize]; 96 unsigned i = 0; 97 if (Array) 98 SubExprs[i++] = arraySize; 99 for (unsigned j = 0; j < NumPlacementArgs; ++j) 100 SubExprs[i++] = placementArgs[j]; 101 for (unsigned j = 0; j < NumConstructorArgs; ++j) 102 SubExprs[i++] = constructorArgs[j]; 103 assert(i == TotalSize); 104} 105 106Stmt::child_iterator CXXNewExpr::child_begin() { return &SubExprs[0]; } 107Stmt::child_iterator CXXNewExpr::child_end() { 108 return &SubExprs[0] + Array + getNumPlacementArgs() + getNumConstructorArgs(); 109} 110 111// CXXDeleteExpr 112Stmt::child_iterator CXXDeleteExpr::child_begin() { return &Argument; } 113Stmt::child_iterator CXXDeleteExpr::child_end() { return &Argument+1; } 114 115// CXXDependentNameExpr 116Stmt::child_iterator CXXDependentNameExpr::child_begin() { 117 return child_iterator(); 118} 119Stmt::child_iterator CXXDependentNameExpr::child_end() { 120 return child_iterator(); 121} 122 123OverloadedOperatorKind CXXOperatorCallExpr::getOperator() const { 124 // All simple function calls (e.g. func()) are implicitly cast to pointer to 125 // function. As a result, we try and obtain the DeclRefExpr from the 126 // ImplicitCastExpr. 127 const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(getCallee()); 128 if (!ICE) // FIXME: deal with more complex calls (e.g. (func)(), (*func)()). 129 return OO_None; 130 131 const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(ICE->getSubExpr()); 132 if (!DRE) 133 return OO_None; 134 135 if (const FunctionDecl *FDecl = dyn_cast<FunctionDecl>(DRE->getDecl())) 136 return FDecl->getDeclName().getCXXOverloadedOperator(); 137 else if (const OverloadedFunctionDecl *Ovl 138 = dyn_cast<OverloadedFunctionDecl>(DRE->getDecl())) 139 return Ovl->getDeclName().getCXXOverloadedOperator(); 140 else 141 return OO_None; 142} 143 144SourceRange CXXOperatorCallExpr::getSourceRange() const { 145 OverloadedOperatorKind Kind = getOperator(); 146 if (Kind == OO_PlusPlus || Kind == OO_MinusMinus) { 147 if (getNumArgs() == 1) 148 // Prefix operator 149 return SourceRange(getOperatorLoc(), 150 getArg(0)->getSourceRange().getEnd()); 151 else 152 // Postfix operator 153 return SourceRange(getArg(0)->getSourceRange().getEnd(), 154 getOperatorLoc()); 155 } else if (Kind == OO_Call) { 156 return SourceRange(getArg(0)->getSourceRange().getBegin(), getRParenLoc()); 157 } else if (Kind == OO_Subscript) { 158 return SourceRange(getArg(0)->getSourceRange().getBegin(), getRParenLoc()); 159 } else if (getNumArgs() == 1) { 160 return SourceRange(getOperatorLoc(), getArg(0)->getSourceRange().getEnd()); 161 } else if (getNumArgs() == 2) { 162 return SourceRange(getArg(0)->getSourceRange().getBegin(), 163 getArg(1)->getSourceRange().getEnd()); 164 } else { 165 return SourceRange(); 166 } 167} 168 169Expr *CXXMemberCallExpr::getImplicitObjectArgument() { 170 if (MemberExpr *MemExpr = dyn_cast<MemberExpr>(getCallee()->IgnoreParens())) 171 return MemExpr->getBase(); 172 173 // FIXME: Will eventually need to cope with member pointers. 174 return 0; 175} 176 177//===----------------------------------------------------------------------===// 178// Named casts 179//===----------------------------------------------------------------------===// 180 181/// getCastName - Get the name of the C++ cast being used, e.g., 182/// "static_cast", "dynamic_cast", "reinterpret_cast", or 183/// "const_cast". The returned pointer must not be freed. 184const char *CXXNamedCastExpr::getCastName() const { 185 switch (getStmtClass()) { 186 case CXXStaticCastExprClass: return "static_cast"; 187 case CXXDynamicCastExprClass: return "dynamic_cast"; 188 case CXXReinterpretCastExprClass: return "reinterpret_cast"; 189 case CXXConstCastExprClass: return "const_cast"; 190 default: return "<invalid cast>"; 191 } 192} 193