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" 18 using namespace clang; 19 20 void 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 33 Stmt::child_iterator CXXTypeidExpr::child_begin() { 34 return isTypeOperand() ? child_iterator() : &Operand.Ex; 35 } 36 Stmt::child_iterator CXXTypeidExpr::child_end() { 37 return isTypeOperand() ? child_iterator() : &Operand.Ex+1; 38 } 39 40 // CXXBoolLiteralExpr 41 Stmt::child_iterator CXXBoolLiteralExpr::child_begin() { 42 return child_iterator(); 43 } 44 Stmt::child_iterator CXXBoolLiteralExpr::child_end() { 45 return child_iterator(); 46 } 47 48 // CXXNullPtrLiteralExpr 49 Stmt::child_iterator CXXNullPtrLiteralExpr::child_begin() { 50 return child_iterator(); 51 } 52 Stmt::child_iterator CXXNullPtrLiteralExpr::child_end() { 53 return child_iterator(); 54 } 55 56 // CXXThisExpr 57 Stmt::child_iterator CXXThisExpr::child_begin() { return child_iterator(); } 58 Stmt::child_iterator CXXThisExpr::child_end() { return child_iterator(); } 59 60 // CXXThrowExpr 61 Stmt::child_iterator CXXThrowExpr::child_begin() { return &Op; } 62 Stmt::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 68 Stmt::child_iterator CXXDefaultArgExpr::child_begin() { 69 return child_iterator(); 70 } 71 Stmt::child_iterator CXXDefaultArgExpr::child_end() { 72 return child_iterator(); 73 } 74 75 // CXXZeroInitValueExpr 76 Stmt::child_iterator CXXZeroInitValueExpr::child_begin() { 77 return child_iterator(); 78 } 79 Stmt::child_iterator CXXZeroInitValueExpr::child_end() { 80 return child_iterator(); 81 } 82 83 // CXXConditionDeclExpr 84 Stmt::child_iterator CXXConditionDeclExpr::child_begin() { 85 return getVarDecl(); 86 } 87 Stmt::child_iterator CXXConditionDeclExpr::child_end() { 88 return child_iterator(); 89 } 90 91 // CXXNewExpr 92 CXXNewExpr::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 118 Stmt::child_iterator CXXNewExpr::child_begin() { return &SubExprs[0]; } 119 Stmt::child_iterator CXXNewExpr::child_end() { 120 return &SubExprs[0] + Array + getNumPlacementArgs() + getNumConstructorArgs(); 121 } 122 123 // CXXDeleteExpr 124 Stmt::child_iterator CXXDeleteExpr::child_begin() { return &Argument; } 125 Stmt::child_iterator CXXDeleteExpr::child_end() { return &Argument+1; } 126 127 // UnresolvedFunctionNameExpr 128 Stmt::child_iterator UnresolvedFunctionNameExpr::child_begin() { 129 return child_iterator(); 130 } 131 Stmt::child_iterator UnresolvedFunctionNameExpr::child_end() { 132 return child_iterator(); 133 } 134 135 UnresolvedFunctionNameExpr* 136 UnresolvedFunctionNameExpr::Clone(ASTContext &C) const { 137 return new (C) UnresolvedFunctionNameExpr(Name, getType(), Loc); 138 } 139 140 // UnaryTypeTraitExpr 141 Stmt::child_iterator UnaryTypeTraitExpr::child_begin() { 142 return child_iterator(); 143 } 144 Stmt::child_iterator UnaryTypeTraitExpr::child_end() { 145 return child_iterator(); 146 } 147 148 // UnresolvedDeclRefExpr 149 StmtIterator UnresolvedDeclRefExpr::child_begin() { 150 return child_iterator(); 151 } 152 153 StmtIterator UnresolvedDeclRefExpr::child_end() { 154 return child_iterator(); 155 } 156 157 TemplateIdRefExpr::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 184 TemplateIdRefExpr * 185 TemplateIdRefExpr::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 199 void 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 206 Stmt::child_iterator TemplateIdRefExpr::child_begin() { 207 // FIXME: Walk the expressions in the template arguments (?) 208 return Stmt::child_iterator(); 209 } 210 211 Stmt::child_iterator TemplateIdRefExpr::child_end() { 212 // FIXME: Walk the expressions in the template arguments (?) 213 return Stmt::child_iterator(); 214 } 215 216 bool UnaryTypeTraitExpr::EvaluateTrait(ASTContext& C) 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->getAs<RecordType>()) { 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->getAs<RecordType>()) { 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->getAs<RecordType>()) 236 return cast<CXXRecordDecl>(RT->getDecl())->isAbstract(); 237 return false; 238 case UTT_HasTrivialConstructor: 239 // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html: 240 // If __is_pod (type) is true then the trait is true, else if type is 241 // a cv class or union type (or array thereof) with a trivial default 242 // constructor ([class.ctor]) then the trait is true, else it is false. 243 if (QueriedType->isPODType()) 244 return true; 245 if (const RecordType *RT = 246 C.getBaseElementType(QueriedType)->getAs<RecordType>()) 247 return cast<CXXRecordDecl>(RT->getDecl())->hasTrivialConstructor(); 248 return false; 249 case UTT_HasTrivialCopy: 250 // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html: 251 // If __is_pod (type) is true or type is a reference type then 252 // the trait is true, else if type is a cv class or union type 253 // with a trivial copy constructor ([class.copy]) then the trait 254 // is true, else it is false. 255 if (QueriedType->isPODType() || QueriedType->isReferenceType()) 256 return true; 257 if (const RecordType *RT = QueriedType->getAs<RecordType>()) 258 return cast<CXXRecordDecl>(RT->getDecl())->hasTrivialCopyConstructor(); 259 return false; 260 case UTT_HasTrivialAssign: 261 // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html: 262 // If type is const qualified or is a reference type then the 263 // trait is false. Otherwise if __is_pod (type) is true then the 264 // trait is true, else if type is a cv class or union type with 265 // a trivial copy assignment ([class.copy]) then the trait is 266 // true, else it is false. 267 // Note: the const and reference restrictions are interesting, 268 // given that const and reference members don't prevent a class 269 // from having a trivial copy assignment operator (but do cause 270 // errors if the copy assignment operator is actually used, q.v. 271 // [class.copy]p12). 272 273 if (C.getBaseElementType(QueriedType).isConstQualified()) 274 return false; 275 if (QueriedType->isPODType()) 276 return true; 277 if (const RecordType *RT = QueriedType->getAs<RecordType>()) 278 return cast<CXXRecordDecl>(RT->getDecl())->hasTrivialCopyAssignment(); 279 return false; 280 case UTT_HasTrivialDestructor: 281 // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html: 282 // If __is_pod (type) is true or type is a reference type 283 // then the trait is true, else if type is a cv class or union 284 // type (or array thereof) with a trivial destructor 285 // ([class.dtor]) then the trait is true, else it is 286 // false. 287 if (QueriedType->isPODType() || QueriedType->isReferenceType()) 288 return true; 289 if (const RecordType *RT = 290 C.getBaseElementType(QueriedType)->getAs<RecordType>()) 291 return cast<CXXRecordDecl>(RT->getDecl())->hasTrivialDestructor(); 292 return false; 293 } 294 } 295 296 SourceRange CXXOperatorCallExpr::getSourceRange() const { 297 OverloadedOperatorKind Kind = getOperator(); 298 if (Kind == OO_PlusPlus || Kind == OO_MinusMinus) { 299 if (getNumArgs() == 1) 300 // Prefix operator 301 return SourceRange(getOperatorLoc(), 302 getArg(0)->getSourceRange().getEnd()); 303 else 304 // Postfix operator 305 return SourceRange(getArg(0)->getSourceRange().getEnd(), 306 getOperatorLoc()); 307 } else if (Kind == OO_Call) { 308 return SourceRange(getArg(0)->getSourceRange().getBegin(), getRParenLoc()); 309 } else if (Kind == OO_Subscript) { 310 return SourceRange(getArg(0)->getSourceRange().getBegin(), getRParenLoc()); 311 } else if (getNumArgs() == 1) { 312 return SourceRange(getOperatorLoc(), getArg(0)->getSourceRange().getEnd()); 313 } else if (getNumArgs() == 2) { 314 return SourceRange(getArg(0)->getSourceRange().getBegin(), 315 getArg(1)->getSourceRange().getEnd()); 316 } else { 317 return SourceRange(); 318 } 319 } 320 321 Expr *CXXMemberCallExpr::getImplicitObjectArgument() { 322 if (MemberExpr *MemExpr = dyn_cast<MemberExpr>(getCallee()->IgnoreParens())) 323 return MemExpr->getBase(); 324 325 // FIXME: Will eventually need to cope with member pointers. 326 return 0; 327 } 328 329 //===----------------------------------------------------------------------===// 330 // Named casts 331 //===----------------------------------------------------------------------===// 332 333 /// getCastName - Get the name of the C++ cast being used, e.g., 334 /// "static_cast", "dynamic_cast", "reinterpret_cast", or 335 /// "const_cast". The returned pointer must not be freed. 336 const char *CXXNamedCastExpr::getCastName() const { 337 switch (getStmtClass()) { 338 case CXXStaticCastExprClass: return "static_cast"; 339 case CXXDynamicCastExprClass: return "dynamic_cast"; 340 case CXXReinterpretCastExprClass: return "reinterpret_cast"; 341 case CXXConstCastExprClass: return "const_cast"; 342 default: return "<invalid cast>"; 343 } 344 } 345 346 CXXTemporary *CXXTemporary::Create(ASTContext &C, 347 const CXXDestructorDecl *Destructor) { 348 return new (C) CXXTemporary(Destructor); 349 } 350 351 void CXXTemporary::Destroy(ASTContext &C) { 352 this->~CXXTemporary(); 353 C.Deallocate(this); 354 } 355 356 CXXBindTemporaryExpr *CXXBindTemporaryExpr::Create(ASTContext &C, 357 CXXTemporary *Temp, 358 Expr* SubExpr) { 359 assert(SubExpr->getType()->isRecordType() && 360 "Expression bound to a temporary must have record type!"); 361 362 return new (C) CXXBindTemporaryExpr(Temp, SubExpr); 363 } 364 365 void CXXBindTemporaryExpr::Destroy(ASTContext &C) { 366 Temp->Destroy(C); 367 this->~CXXBindTemporaryExpr(); 368 C.Deallocate(this); 369 } 370 371 CXXTemporaryObjectExpr::CXXTemporaryObjectExpr(ASTContext &C, 372 CXXConstructorDecl *Cons, 373 QualType writtenTy, 374 SourceLocation tyBeginLoc, 375 Expr **Args, 376 unsigned NumArgs, 377 SourceLocation rParenLoc) 378 : CXXConstructExpr(C, CXXTemporaryObjectExprClass, writtenTy, Cons, 379 false, Args, NumArgs), 380 TyBeginLoc(tyBeginLoc), RParenLoc(rParenLoc) { 381 } 382 383 CXXConstructExpr *CXXConstructExpr::Create(ASTContext &C, QualType T, 384 CXXConstructorDecl *D, bool Elidable, 385 Expr **Args, unsigned NumArgs) { 386 return new (C) CXXConstructExpr(C, CXXConstructExprClass, T, D, Elidable, 387 Args, NumArgs); 388 } 389 390 CXXConstructExpr::CXXConstructExpr(ASTContext &C, StmtClass SC, QualType T, 391 CXXConstructorDecl *D, bool elidable, 392 Expr **args, unsigned numargs) 393 : Expr(SC, T, 394 T->isDependentType(), 395 (T->isDependentType() || 396 CallExpr::hasAnyValueDependentArguments(args, numargs))), 397 Constructor(D), Elidable(elidable), Args(0), NumArgs(numargs) { 398 if (NumArgs > 0) { 399 Args = new (C) Stmt*[NumArgs]; 400 for (unsigned i = 0; i < NumArgs; ++i) 401 Args[i] = args[i]; 402 } 403 } 404 405 void CXXConstructExpr::Destroy(ASTContext &C) { 406 DestroyChildren(C); 407 if (Args) 408 C.Deallocate(Args); 409 this->~CXXConstructExpr(); 410 C.Deallocate(this); 411 } 412 413 CXXExprWithTemporaries::CXXExprWithTemporaries(Expr *subexpr, 414 CXXTemporary **temps, 415 unsigned numtemps, 416 bool shoulddestroytemps) 417 : Expr(CXXExprWithTemporariesClass, subexpr->getType(), 418 subexpr->isTypeDependent(), subexpr->isValueDependent()), 419 SubExpr(subexpr), Temps(0), NumTemps(numtemps), 420 ShouldDestroyTemps(shoulddestroytemps) { 421 if (NumTemps > 0) { 422 Temps = new CXXTemporary*[NumTemps]; 423 for (unsigned i = 0; i < NumTemps; ++i) 424 Temps[i] = temps[i]; 425 } 426 } 427 428 CXXExprWithTemporaries *CXXExprWithTemporaries::Create(ASTContext &C, 429 Expr *SubExpr, 430 CXXTemporary **Temps, 431 unsigned NumTemps, 432 bool ShouldDestroyTemps){ 433 return new (C) CXXExprWithTemporaries(SubExpr, Temps, NumTemps, 434 ShouldDestroyTemps); 435 } 436 437 void CXXExprWithTemporaries::Destroy(ASTContext &C) { 438 DestroyChildren(C); 439 this->~CXXExprWithTemporaries(); 440 C.Deallocate(this); 441 } 442 443 CXXExprWithTemporaries::~CXXExprWithTemporaries() { 444 delete[] Temps; 445 } 446 447 // CXXBindTemporaryExpr 448 Stmt::child_iterator CXXBindTemporaryExpr::child_begin() { 449 return &SubExpr; 450 } 451 452 Stmt::child_iterator CXXBindTemporaryExpr::child_end() { 453 return &SubExpr + 1; 454 } 455 456 // CXXConstructExpr 457 Stmt::child_iterator CXXConstructExpr::child_begin() { 458 return &Args[0]; 459 } 460 Stmt::child_iterator CXXConstructExpr::child_end() { 461 return &Args[0]+NumArgs; 462 } 463 464 // CXXExprWithTemporaries 465 Stmt::child_iterator CXXExprWithTemporaries::child_begin() { 466 return &SubExpr; 467 } 468 469 Stmt::child_iterator CXXExprWithTemporaries::child_end() { 470 return &SubExpr + 1; 471 } 472 473 CXXUnresolvedConstructExpr::CXXUnresolvedConstructExpr( 474 SourceLocation TyBeginLoc, 475 QualType T, 476 SourceLocation LParenLoc, 477 Expr **Args, 478 unsigned NumArgs, 479 SourceLocation RParenLoc) 480 : Expr(CXXUnresolvedConstructExprClass, T.getNonReferenceType(), 481 T->isDependentType(), true), 482 TyBeginLoc(TyBeginLoc), 483 Type(T), 484 LParenLoc(LParenLoc), 485 RParenLoc(RParenLoc), 486 NumArgs(NumArgs) { 487 Stmt **StoredArgs = reinterpret_cast<Stmt **>(this + 1); 488 memcpy(StoredArgs, Args, sizeof(Expr *) * NumArgs); 489 } 490 491 CXXUnresolvedConstructExpr * 492 CXXUnresolvedConstructExpr::Create(ASTContext &C, 493 SourceLocation TyBegin, 494 QualType T, 495 SourceLocation LParenLoc, 496 Expr **Args, 497 unsigned NumArgs, 498 SourceLocation RParenLoc) { 499 void *Mem = C.Allocate(sizeof(CXXUnresolvedConstructExpr) + 500 sizeof(Expr *) * NumArgs); 501 return new (Mem) CXXUnresolvedConstructExpr(TyBegin, T, LParenLoc, 502 Args, NumArgs, RParenLoc); 503 } 504 505 Stmt::child_iterator CXXUnresolvedConstructExpr::child_begin() { 506 return child_iterator(reinterpret_cast<Stmt **>(this + 1)); 507 } 508 509 Stmt::child_iterator CXXUnresolvedConstructExpr::child_end() { 510 return child_iterator(reinterpret_cast<Stmt **>(this + 1) + NumArgs); 511 } 512 513 Stmt::child_iterator CXXUnresolvedMemberExpr::child_begin() { 514 return child_iterator(&Base); 515 } 516 517 Stmt::child_iterator CXXUnresolvedMemberExpr::child_end() { 518 return child_iterator(&Base + 1); 519 } 520 521 //===----------------------------------------------------------------------===// 522 // Cloners 523 //===----------------------------------------------------------------------===// 524 525 CXXBoolLiteralExpr* CXXBoolLiteralExpr::Clone(ASTContext &C) const { 526 return new (C) CXXBoolLiteralExpr(Value, getType(), Loc); 527 } 528 529 CXXNullPtrLiteralExpr* CXXNullPtrLiteralExpr::Clone(ASTContext &C) const { 530 return new (C) CXXNullPtrLiteralExpr(getType(), Loc); 531 } 532 533 CXXZeroInitValueExpr* CXXZeroInitValueExpr::Clone(ASTContext &C) const { 534 return new (C) CXXZeroInitValueExpr(getType(), TyBeginLoc, RParenLoc); 535 } 536