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