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