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