CGExprCXX.cpp revision 199990
1//===--- CGExprCXX.cpp - Emit LLVM Code for C++ expressions ---------------===// 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 contains code dealing with code generation of C++ expressions 11// 12//===----------------------------------------------------------------------===// 13 14#include "CodeGenFunction.h" 15using namespace clang; 16using namespace CodeGen; 17 18static uint64_t CalculateCookiePadding(ASTContext &Ctx, const CXXNewExpr *E) { 19 if (!E->isArray()) 20 return 0; 21 22 QualType T = E->getAllocatedType(); 23 24 const RecordType *RT = T->getAs<RecordType>(); 25 if (!RT) 26 return 0; 27 28 const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl()); 29 if (!RD) 30 return 0; 31 32 // Check if the class has a trivial destructor. 33 if (RD->hasTrivialDestructor()) { 34 // FIXME: Check for a two-argument delete. 35 return 0; 36 } 37 38 // Padding is the maximum of sizeof(size_t) and alignof(T) 39 return std::max(Ctx.getTypeSize(Ctx.getSizeType()), 40 static_cast<uint64_t>(Ctx.getTypeAlign(T))) / 8; 41} 42 43static llvm::Value *EmitCXXNewAllocSize(CodeGenFunction &CGF, 44 const CXXNewExpr *E, 45 llvm::Value *& NumElements) { 46 QualType Type = E->getAllocatedType(); 47 uint64_t TypeSizeInBytes = CGF.getContext().getTypeSize(Type) / 8; 48 const llvm::Type *SizeTy = CGF.ConvertType(CGF.getContext().getSizeType()); 49 50 if (!E->isArray()) 51 return llvm::ConstantInt::get(SizeTy, TypeSizeInBytes); 52 53 uint64_t CookiePadding = CalculateCookiePadding(CGF.getContext(), E); 54 55 Expr::EvalResult Result; 56 if (E->getArraySize()->Evaluate(Result, CGF.getContext()) && 57 !Result.HasSideEffects && Result.Val.isInt()) { 58 59 uint64_t AllocSize = 60 Result.Val.getInt().getZExtValue() * TypeSizeInBytes + CookiePadding; 61 62 NumElements = 63 llvm::ConstantInt::get(SizeTy, Result.Val.getInt().getZExtValue()); 64 65 return llvm::ConstantInt::get(SizeTy, AllocSize); 66 } 67 68 // Emit the array size expression. 69 NumElements = CGF.EmitScalarExpr(E->getArraySize()); 70 71 // Multiply with the type size. 72 llvm::Value *V = 73 CGF.Builder.CreateMul(NumElements, 74 llvm::ConstantInt::get(SizeTy, TypeSizeInBytes)); 75 76 // And add the cookie padding if necessary. 77 if (CookiePadding) 78 V = CGF.Builder.CreateAdd(V, llvm::ConstantInt::get(SizeTy, CookiePadding)); 79 80 return V; 81} 82 83static void EmitNewInitializer(CodeGenFunction &CGF, const CXXNewExpr *E, 84 llvm::Value *NewPtr, 85 llvm::Value *NumElements) { 86 if (E->isArray()) { 87 if (CXXConstructorDecl *Ctor = E->getConstructor()) 88 CGF.EmitCXXAggrConstructorCall(Ctor, NumElements, NewPtr, 89 E->constructor_arg_begin(), 90 E->constructor_arg_end()); 91 return; 92 } 93 94 QualType AllocType = E->getAllocatedType(); 95 96 if (CXXConstructorDecl *Ctor = E->getConstructor()) { 97 CGF.EmitCXXConstructorCall(Ctor, Ctor_Complete, NewPtr, 98 E->constructor_arg_begin(), 99 E->constructor_arg_end()); 100 101 return; 102 } 103 104 // We have a POD type. 105 if (E->getNumConstructorArgs() == 0) 106 return; 107 108 assert(E->getNumConstructorArgs() == 1 && 109 "Can only have one argument to initializer of POD type."); 110 111 const Expr *Init = E->getConstructorArg(0); 112 113 if (!CGF.hasAggregateLLVMType(AllocType)) 114 CGF.EmitStoreOfScalar(CGF.EmitScalarExpr(Init), NewPtr, 115 AllocType.isVolatileQualified(), AllocType); 116 else if (AllocType->isAnyComplexType()) 117 CGF.EmitComplexExprIntoAddr(Init, NewPtr, 118 AllocType.isVolatileQualified()); 119 else 120 CGF.EmitAggExpr(Init, NewPtr, AllocType.isVolatileQualified()); 121} 122 123llvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) { 124 QualType AllocType = E->getAllocatedType(); 125 FunctionDecl *NewFD = E->getOperatorNew(); 126 const FunctionProtoType *NewFTy = NewFD->getType()->getAs<FunctionProtoType>(); 127 128 CallArgList NewArgs; 129 130 // The allocation size is the first argument. 131 QualType SizeTy = getContext().getSizeType(); 132 133 llvm::Value *NumElements = 0; 134 llvm::Value *AllocSize = EmitCXXNewAllocSize(*this, E, NumElements); 135 136 NewArgs.push_back(std::make_pair(RValue::get(AllocSize), SizeTy)); 137 138 // Emit the rest of the arguments. 139 // FIXME: Ideally, this should just use EmitCallArgs. 140 CXXNewExpr::const_arg_iterator NewArg = E->placement_arg_begin(); 141 142 // First, use the types from the function type. 143 // We start at 1 here because the first argument (the allocation size) 144 // has already been emitted. 145 for (unsigned i = 1, e = NewFTy->getNumArgs(); i != e; ++i, ++NewArg) { 146 QualType ArgType = NewFTy->getArgType(i); 147 148 assert(getContext().getCanonicalType(ArgType.getNonReferenceType()). 149 getTypePtr() == 150 getContext().getCanonicalType(NewArg->getType()).getTypePtr() && 151 "type mismatch in call argument!"); 152 153 NewArgs.push_back(std::make_pair(EmitCallArg(*NewArg, ArgType), 154 ArgType)); 155 156 } 157 158 // Either we've emitted all the call args, or we have a call to a 159 // variadic function. 160 assert((NewArg == E->placement_arg_end() || NewFTy->isVariadic()) && 161 "Extra arguments in non-variadic function!"); 162 163 // If we still have any arguments, emit them using the type of the argument. 164 for (CXXNewExpr::const_arg_iterator NewArgEnd = E->placement_arg_end(); 165 NewArg != NewArgEnd; ++NewArg) { 166 QualType ArgType = NewArg->getType(); 167 NewArgs.push_back(std::make_pair(EmitCallArg(*NewArg, ArgType), 168 ArgType)); 169 } 170 171 // Emit the call to new. 172 RValue RV = 173 EmitCall(CGM.getTypes().getFunctionInfo(NewFTy->getResultType(), NewArgs), 174 CGM.GetAddrOfFunction(NewFD), NewArgs, NewFD); 175 176 // If an allocation function is declared with an empty exception specification 177 // it returns null to indicate failure to allocate storage. [expr.new]p13. 178 // (We don't need to check for null when there's no new initializer and 179 // we're allocating a POD type). 180 bool NullCheckResult = NewFTy->hasEmptyExceptionSpec() && 181 !(AllocType->isPODType() && !E->hasInitializer()); 182 183 llvm::BasicBlock *NewNull = 0; 184 llvm::BasicBlock *NewNotNull = 0; 185 llvm::BasicBlock *NewEnd = 0; 186 187 llvm::Value *NewPtr = RV.getScalarVal(); 188 189 if (NullCheckResult) { 190 NewNull = createBasicBlock("new.null"); 191 NewNotNull = createBasicBlock("new.notnull"); 192 NewEnd = createBasicBlock("new.end"); 193 194 llvm::Value *IsNull = 195 Builder.CreateICmpEQ(NewPtr, 196 llvm::Constant::getNullValue(NewPtr->getType()), 197 "isnull"); 198 199 Builder.CreateCondBr(IsNull, NewNull, NewNotNull); 200 EmitBlock(NewNotNull); 201 } 202 203 if (uint64_t CookiePadding = CalculateCookiePadding(getContext(), E)) { 204 uint64_t CookieOffset = 205 CookiePadding - getContext().getTypeSize(SizeTy) / 8; 206 207 llvm::Value *NumElementsPtr = 208 Builder.CreateConstInBoundsGEP1_64(NewPtr, CookieOffset); 209 210 NumElementsPtr = Builder.CreateBitCast(NumElementsPtr, 211 ConvertType(SizeTy)->getPointerTo()); 212 Builder.CreateStore(NumElements, NumElementsPtr); 213 214 // Now add the padding to the new ptr. 215 NewPtr = Builder.CreateConstInBoundsGEP1_64(NewPtr, CookiePadding); 216 } 217 218 NewPtr = Builder.CreateBitCast(NewPtr, ConvertType(E->getType())); 219 220 EmitNewInitializer(*this, E, NewPtr, NumElements); 221 222 if (NullCheckResult) { 223 Builder.CreateBr(NewEnd); 224 NewNotNull = Builder.GetInsertBlock(); 225 EmitBlock(NewNull); 226 Builder.CreateBr(NewEnd); 227 EmitBlock(NewEnd); 228 229 llvm::PHINode *PHI = Builder.CreatePHI(NewPtr->getType()); 230 PHI->reserveOperandSpace(2); 231 PHI->addIncoming(NewPtr, NewNotNull); 232 PHI->addIncoming(llvm::Constant::getNullValue(NewPtr->getType()), NewNull); 233 234 NewPtr = PHI; 235 } 236 237 return NewPtr; 238} 239 240void CodeGenFunction::EmitDeleteCall(const FunctionDecl *DeleteFD, 241 llvm::Value *Ptr, 242 QualType DeleteTy) { 243 const FunctionProtoType *DeleteFTy = 244 DeleteFD->getType()->getAs<FunctionProtoType>(); 245 246 CallArgList DeleteArgs; 247 248 QualType ArgTy = DeleteFTy->getArgType(0); 249 llvm::Value *DeletePtr = Builder.CreateBitCast(Ptr, ConvertType(ArgTy)); 250 DeleteArgs.push_back(std::make_pair(RValue::get(DeletePtr), ArgTy)); 251 252 if (DeleteFTy->getNumArgs() == 2) { 253 QualType SizeTy = DeleteFTy->getArgType(1); 254 uint64_t SizeVal = getContext().getTypeSize(DeleteTy) / 8; 255 llvm::Constant *Size = llvm::ConstantInt::get(ConvertType(SizeTy), 256 SizeVal); 257 DeleteArgs.push_back(std::make_pair(RValue::get(Size), SizeTy)); 258 } 259 260 // Emit the call to delete. 261 EmitCall(CGM.getTypes().getFunctionInfo(DeleteFTy->getResultType(), 262 DeleteArgs), 263 CGM.GetAddrOfFunction(DeleteFD), 264 DeleteArgs, DeleteFD); 265} 266 267void CodeGenFunction::EmitCXXDeleteExpr(const CXXDeleteExpr *E) { 268 269 // Get at the argument before we performed the implicit conversion 270 // to void*. 271 const Expr *Arg = E->getArgument(); 272 while (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Arg)) { 273 if (ICE->getCastKind() != CastExpr::CK_UserDefinedConversion && 274 ICE->getType()->isVoidPointerType()) 275 Arg = ICE->getSubExpr(); 276 else 277 break; 278 } 279 280 QualType DeleteTy = Arg->getType()->getAs<PointerType>()->getPointeeType(); 281 282 llvm::Value *Ptr = EmitScalarExpr(Arg); 283 284 // Null check the pointer. 285 llvm::BasicBlock *DeleteNotNull = createBasicBlock("delete.notnull"); 286 llvm::BasicBlock *DeleteEnd = createBasicBlock("delete.end"); 287 288 llvm::Value *IsNull = 289 Builder.CreateICmpEQ(Ptr, llvm::Constant::getNullValue(Ptr->getType()), 290 "isnull"); 291 292 Builder.CreateCondBr(IsNull, DeleteEnd, DeleteNotNull); 293 EmitBlock(DeleteNotNull); 294 295 bool ShouldCallDelete = true; 296 297 // Call the destructor if necessary. 298 if (const RecordType *RT = DeleteTy->getAs<RecordType>()) { 299 if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl())) { 300 if (!RD->hasTrivialDestructor()) { 301 const CXXDestructorDecl *Dtor = RD->getDestructor(getContext()); 302 if (E->isArrayForm()) { 303 QualType SizeTy = getContext().getSizeType(); 304 uint64_t CookiePadding = std::max(getContext().getTypeSize(SizeTy), 305 static_cast<uint64_t>(getContext().getTypeAlign(DeleteTy))) / 8; 306 if (CookiePadding) { 307 llvm::Type *Ptr8Ty = 308 llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext), 0); 309 uint64_t CookieOffset = 310 CookiePadding - getContext().getTypeSize(SizeTy) / 8; 311 llvm::Value *AllocatedObjectPtr = 312 Builder.CreateConstInBoundsGEP1_64( 313 Builder.CreateBitCast(Ptr, Ptr8Ty), -CookiePadding); 314 llvm::Value *NumElementsPtr = 315 Builder.CreateConstInBoundsGEP1_64(AllocatedObjectPtr, 316 CookieOffset); 317 NumElementsPtr = Builder.CreateBitCast(NumElementsPtr, 318 ConvertType(SizeTy)->getPointerTo()); 319 320 llvm::Value *NumElements = 321 Builder.CreateLoad(NumElementsPtr); 322 NumElements = 323 Builder.CreateIntCast(NumElements, 324 llvm::Type::getInt64Ty(VMContext), false, 325 "count.tmp"); 326 EmitCXXAggrDestructorCall(Dtor, NumElements, Ptr); 327 Ptr = AllocatedObjectPtr; 328 } 329 } 330 else if (Dtor->isVirtual()) { 331 const llvm::Type *Ty = 332 CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(Dtor), 333 /*isVariadic=*/false); 334 335 llvm::Value *Callee = BuildVirtualCall(Dtor, Dtor_Deleting, Ptr, Ty); 336 EmitCXXMemberCall(Dtor, Callee, Ptr, 0, 0); 337 338 // The dtor took care of deleting the object. 339 ShouldCallDelete = false; 340 } else 341 EmitCXXDestructorCall(Dtor, Dtor_Complete, Ptr); 342 } 343 } 344 } 345 346 if (ShouldCallDelete) 347 EmitDeleteCall(E->getOperatorDelete(), Ptr, DeleteTy); 348 349 EmitBlock(DeleteEnd); 350} 351 352llvm::Value * CodeGenFunction::EmitCXXTypeidExpr(const CXXTypeidExpr *E) { 353 QualType Ty = E->getType(); 354 const llvm::Type *LTy = ConvertType(Ty)->getPointerTo(); 355 if (E->isTypeOperand()) { 356 Ty = E->getTypeOperand(); 357 CanQualType CanTy = CGM.getContext().getCanonicalType(Ty); 358 Ty = CanTy.getUnqualifiedType().getNonReferenceType(); 359 if (const RecordType *RT = Ty->getAs<RecordType>()) { 360 const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl()); 361 if (RD->isPolymorphic()) 362 return Builder.CreateBitCast(CGM.GenerateRttiRef(RD), LTy); 363 return Builder.CreateBitCast(CGM.GenerateRtti(RD), LTy); 364 } 365 return Builder.CreateBitCast(CGM.GenerateRtti(Ty), LTy); 366 } 367 Expr *subE = E->getExprOperand(); 368 Ty = subE->getType(); 369 CanQualType CanTy = CGM.getContext().getCanonicalType(Ty); 370 Ty = CanTy.getUnqualifiedType().getNonReferenceType(); 371 if (const RecordType *RT = Ty->getAs<RecordType>()) { 372 const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl()); 373 if (RD->isPolymorphic()) { 374 // FIXME: if subE is an lvalue do 375 LValue Obj = EmitLValue(subE); 376 llvm::Value *This = Obj.getAddress(); 377 LTy = LTy->getPointerTo()->getPointerTo(); 378 llvm::Value *V = Builder.CreateBitCast(This, LTy); 379 // We need to do a zero check for *p, unless it has NonNullAttr. 380 // FIXME: PointerType->hasAttr<NonNullAttr>() 381 bool CanBeZero = false; 382 if (UnaryOperator *UO = dyn_cast<UnaryOperator>(subE->IgnoreParens())) 383 if (UO->getOpcode() == UnaryOperator::Deref) 384 CanBeZero = true; 385 if (CanBeZero) { 386 llvm::BasicBlock *NonZeroBlock = createBasicBlock(); 387 llvm::BasicBlock *ZeroBlock = createBasicBlock(); 388 389 llvm::Value *Zero = llvm::Constant::getNullValue(LTy); 390 Builder.CreateCondBr(Builder.CreateICmpNE(V, Zero), 391 NonZeroBlock, ZeroBlock); 392 EmitBlock(ZeroBlock); 393 /// Call __cxa_bad_typeid 394 const llvm::Type *ResultType = llvm::Type::getVoidTy(VMContext); 395 const llvm::FunctionType *FTy; 396 FTy = llvm::FunctionType::get(ResultType, false); 397 llvm::Value *F = CGM.CreateRuntimeFunction(FTy, "__cxa_bad_typeid"); 398 Builder.CreateCall(F)->setDoesNotReturn(); 399 Builder.CreateUnreachable(); 400 EmitBlock(NonZeroBlock); 401 } 402 V = Builder.CreateLoad(V, "vtable"); 403 V = Builder.CreateConstInBoundsGEP1_64(V, -1ULL); 404 V = Builder.CreateLoad(V); 405 return V; 406 } 407 return Builder.CreateBitCast(CGM.GenerateRtti(RD), LTy); 408 } 409 return Builder.CreateBitCast(CGM.GenerateRtti(Ty), LTy); 410} 411 412llvm::Value *CodeGenFunction::EmitDynamicCast(llvm::Value *V, 413 const CXXDynamicCastExpr *DCE) { 414 QualType CastTy = DCE->getTypeAsWritten(); 415 QualType InnerType = CastTy->getPointeeType(); 416 QualType ArgTy = DCE->getSubExpr()->getType(); 417 const llvm::Type *LArgTy = ConvertType(ArgTy); 418 const llvm::Type *LTy = ConvertType(DCE->getType()); 419 420 bool CanBeZero = false; 421 bool ToVoid = false; 422 bool ThrowOnBad = false; 423 if (CastTy->isPointerType()) { 424 // FIXME: if PointerType->hasAttr<NonNullAttr>(), we don't set this 425 CanBeZero = true; 426 if (InnerType->isVoidType()) 427 ToVoid = true; 428 } else { 429 LTy = LTy->getPointerTo(); 430 ThrowOnBad = true; 431 } 432 433 CXXRecordDecl *SrcTy; 434 QualType Ty = ArgTy; 435 if (ArgTy.getTypePtr()->isPointerType() 436 || ArgTy.getTypePtr()->isReferenceType()) 437 Ty = Ty.getTypePtr()->getPointeeType(); 438 CanQualType CanTy = CGM.getContext().getCanonicalType(Ty); 439 Ty = CanTy.getUnqualifiedType(); 440 SrcTy = cast<CXXRecordDecl>(Ty->getAs<RecordType>()->getDecl()); 441 442 llvm::BasicBlock *ContBlock = createBasicBlock(); 443 llvm::BasicBlock *NullBlock = 0; 444 llvm::BasicBlock *NonZeroBlock = 0; 445 if (CanBeZero) { 446 NonZeroBlock = createBasicBlock(); 447 NullBlock = createBasicBlock(); 448 llvm::Value *Zero = llvm::Constant::getNullValue(LArgTy); 449 Builder.CreateCondBr(Builder.CreateICmpNE(V, Zero), 450 NonZeroBlock, NullBlock); 451 EmitBlock(NonZeroBlock); 452 } 453 454 llvm::BasicBlock *BadCastBlock = 0; 455 456 const llvm::Type *PtrDiffTy = ConvertType(getContext().getSizeType()); 457 458 // See if this is a dynamic_cast(void*) 459 if (ToVoid) { 460 llvm::Value *This = V; 461 V = Builder.CreateBitCast(This, PtrDiffTy->getPointerTo()->getPointerTo()); 462 V = Builder.CreateLoad(V, "vtable"); 463 V = Builder.CreateConstInBoundsGEP1_64(V, -2ULL); 464 V = Builder.CreateLoad(V, "offset to top"); 465 This = Builder.CreateBitCast(This, llvm::Type::getInt8PtrTy(VMContext)); 466 V = Builder.CreateInBoundsGEP(This, V); 467 V = Builder.CreateBitCast(V, LTy); 468 } else { 469 /// Call __dynamic_cast 470 const llvm::Type *ResultType = llvm::Type::getInt8PtrTy(VMContext); 471 const llvm::FunctionType *FTy; 472 std::vector<const llvm::Type*> ArgTys; 473 const llvm::Type *PtrToInt8Ty 474 = llvm::Type::getInt8Ty(VMContext)->getPointerTo(); 475 ArgTys.push_back(PtrToInt8Ty); 476 ArgTys.push_back(PtrToInt8Ty); 477 ArgTys.push_back(PtrToInt8Ty); 478 ArgTys.push_back(PtrDiffTy); 479 FTy = llvm::FunctionType::get(ResultType, ArgTys, false); 480 CXXRecordDecl *DstTy; 481 Ty = CastTy.getTypePtr()->getPointeeType(); 482 CanTy = CGM.getContext().getCanonicalType(Ty); 483 Ty = CanTy.getUnqualifiedType(); 484 DstTy = cast<CXXRecordDecl>(Ty->getAs<RecordType>()->getDecl()); 485 486 // FIXME: Calculate better hint. 487 llvm::Value *hint = llvm::ConstantInt::get(PtrDiffTy, -1ULL); 488 llvm::Value *SrcArg = CGM.GenerateRttiRef(SrcTy); 489 llvm::Value *DstArg = CGM.GenerateRttiRef(DstTy); 490 V = Builder.CreateBitCast(V, PtrToInt8Ty); 491 V = Builder.CreateCall4(CGM.CreateRuntimeFunction(FTy, "__dynamic_cast"), 492 V, SrcArg, DstArg, hint); 493 V = Builder.CreateBitCast(V, LTy); 494 495 if (ThrowOnBad) { 496 BadCastBlock = createBasicBlock(); 497 498 llvm::Value *Zero = llvm::Constant::getNullValue(LTy); 499 Builder.CreateCondBr(Builder.CreateICmpNE(V, Zero), 500 ContBlock, BadCastBlock); 501 EmitBlock(BadCastBlock); 502 /// Call __cxa_bad_cast 503 ResultType = llvm::Type::getVoidTy(VMContext); 504 const llvm::FunctionType *FBadTy; 505 FBadTy = llvm::FunctionType::get(ResultType, false); 506 llvm::Value *F = CGM.CreateRuntimeFunction(FBadTy, "__cxa_bad_cast"); 507 Builder.CreateCall(F)->setDoesNotReturn(); 508 Builder.CreateUnreachable(); 509 } 510 } 511 512 if (CanBeZero) { 513 Builder.CreateBr(ContBlock); 514 EmitBlock(NullBlock); 515 Builder.CreateBr(ContBlock); 516 } 517 EmitBlock(ContBlock); 518 if (CanBeZero) { 519 llvm::PHINode *PHI = Builder.CreatePHI(LTy); 520 PHI->reserveOperandSpace(2); 521 PHI->addIncoming(V, NonZeroBlock); 522 PHI->addIncoming(llvm::Constant::getNullValue(LTy), NullBlock); 523 V = PHI; 524 } 525 526 return V; 527} 528