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" 15 using namespace clang; 16 using namespace CodeGen; 17 18 static 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 43 static 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 83 static 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 123 llvm::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 240 void 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 267 void 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 352 llvm::Value * CodeGenFunction::EmitCXXTypeidExpr(const CXXTypeidExpr *E) { 353 QualType Ty = E->getType(); 354 const llvm::Type *LTy = ConvertType(Ty)->getPointerTo(); 355 356 if (E->isTypeOperand()) 357 return Builder.CreateBitCast(CGM.GetAddrOfRTTI(E->getTypeOperand()), LTy); 358 359 Expr *subE = E->getExprOperand(); 360 Ty = subE->getType(); 361 CanQualType CanTy = CGM.getContext().getCanonicalType(Ty); 362 Ty = CanTy.getUnqualifiedType().getNonReferenceType(); 363 if (const RecordType *RT = Ty->getAs<RecordType>()) { 364 const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl()); 365 if (RD->isPolymorphic()) { 366 // FIXME: if subE is an lvalue do 367 LValue Obj = EmitLValue(subE); 368 llvm::Value *This = Obj.getAddress(); 369 LTy = LTy->getPointerTo()->getPointerTo(); 370 llvm::Value *V = Builder.CreateBitCast(This, LTy); 371 // We need to do a zero check for *p, unless it has NonNullAttr. 372 // FIXME: PointerType->hasAttr<NonNullAttr>() 373 bool CanBeZero = false; 374 if (UnaryOperator *UO = dyn_cast<UnaryOperator>(subE->IgnoreParens())) 375 if (UO->getOpcode() == UnaryOperator::Deref) 376 CanBeZero = true; 377 if (CanBeZero) { 378 llvm::BasicBlock *NonZeroBlock = createBasicBlock(); 379 llvm::BasicBlock *ZeroBlock = createBasicBlock(); 380 381 llvm::Value *Zero = llvm::Constant::getNullValue(LTy); 382 Builder.CreateCondBr(Builder.CreateICmpNE(V, Zero), 383 NonZeroBlock, ZeroBlock); 384 EmitBlock(ZeroBlock); 385 /// Call __cxa_bad_typeid 386 const llvm::Type *ResultType = llvm::Type::getVoidTy(VMContext); 387 const llvm::FunctionType *FTy; 388 FTy = llvm::FunctionType::get(ResultType, false); 389 llvm::Value *F = CGM.CreateRuntimeFunction(FTy, "__cxa_bad_typeid"); 390 Builder.CreateCall(F)->setDoesNotReturn(); 391 Builder.CreateUnreachable(); 392 EmitBlock(NonZeroBlock); 393 } 394 V = Builder.CreateLoad(V, "vtable"); 395 V = Builder.CreateConstInBoundsGEP1_64(V, -1ULL); 396 V = Builder.CreateLoad(V); 397 return V; 398 } 399 return Builder.CreateBitCast(CGM.GenerateRTTI(RD), LTy); 400 } 401 return Builder.CreateBitCast(CGM.GenerateRTTI(Ty), LTy); 402 } 403 404 llvm::Value *CodeGenFunction::EmitDynamicCast(llvm::Value *V, 405 const CXXDynamicCastExpr *DCE) { 406 QualType CastTy = DCE->getTypeAsWritten(); 407 QualType InnerType = CastTy->getPointeeType(); 408 QualType ArgTy = DCE->getSubExpr()->getType(); 409 const llvm::Type *LArgTy = ConvertType(ArgTy); 410 const llvm::Type *LTy = ConvertType(DCE->getType()); 411 412 bool CanBeZero = false; 413 bool ToVoid = false; 414 bool ThrowOnBad = false; 415 if (CastTy->isPointerType()) { 416 // FIXME: if PointerType->hasAttr<NonNullAttr>(), we don't set this 417 CanBeZero = true; 418 if (InnerType->isVoidType()) 419 ToVoid = true; 420 } else { 421 LTy = LTy->getPointerTo(); 422 ThrowOnBad = true; 423 } 424 425 CXXRecordDecl *SrcTy; 426 QualType Ty = ArgTy; 427 if (ArgTy.getTypePtr()->isPointerType() 428 || ArgTy.getTypePtr()->isReferenceType()) 429 Ty = Ty.getTypePtr()->getPointeeType(); 430 CanQualType CanTy = CGM.getContext().getCanonicalType(Ty); 431 Ty = CanTy.getUnqualifiedType(); 432 SrcTy = cast<CXXRecordDecl>(Ty->getAs<RecordType>()->getDecl()); 433 434 llvm::BasicBlock *ContBlock = createBasicBlock(); 435 llvm::BasicBlock *NullBlock = 0; 436 llvm::BasicBlock *NonZeroBlock = 0; 437 if (CanBeZero) { 438 NonZeroBlock = createBasicBlock(); 439 NullBlock = createBasicBlock(); 440 llvm::Value *Zero = llvm::Constant::getNullValue(LArgTy); 441 Builder.CreateCondBr(Builder.CreateICmpNE(V, Zero), 442 NonZeroBlock, NullBlock); 443 EmitBlock(NonZeroBlock); 444 } 445 446 llvm::BasicBlock *BadCastBlock = 0; 447 448 const llvm::Type *PtrDiffTy = ConvertType(getContext().getSizeType()); 449 450 // See if this is a dynamic_cast(void*) 451 if (ToVoid) { 452 llvm::Value *This = V; 453 V = Builder.CreateBitCast(This, PtrDiffTy->getPointerTo()->getPointerTo()); 454 V = Builder.CreateLoad(V, "vtable"); 455 V = Builder.CreateConstInBoundsGEP1_64(V, -2ULL); 456 V = Builder.CreateLoad(V, "offset to top"); 457 This = Builder.CreateBitCast(This, llvm::Type::getInt8PtrTy(VMContext)); 458 V = Builder.CreateInBoundsGEP(This, V); 459 V = Builder.CreateBitCast(V, LTy); 460 } else { 461 /// Call __dynamic_cast 462 const llvm::Type *ResultType = llvm::Type::getInt8PtrTy(VMContext); 463 const llvm::FunctionType *FTy; 464 std::vector<const llvm::Type*> ArgTys; 465 const llvm::Type *PtrToInt8Ty 466 = llvm::Type::getInt8Ty(VMContext)->getPointerTo(); 467 ArgTys.push_back(PtrToInt8Ty); 468 ArgTys.push_back(PtrToInt8Ty); 469 ArgTys.push_back(PtrToInt8Ty); 470 ArgTys.push_back(PtrDiffTy); 471 FTy = llvm::FunctionType::get(ResultType, ArgTys, false); 472 CXXRecordDecl *DstTy; 473 Ty = CastTy.getTypePtr()->getPointeeType(); 474 CanTy = CGM.getContext().getCanonicalType(Ty); 475 Ty = CanTy.getUnqualifiedType(); 476 DstTy = cast<CXXRecordDecl>(Ty->getAs<RecordType>()->getDecl()); 477 478 // FIXME: Calculate better hint. 479 llvm::Value *hint = llvm::ConstantInt::get(PtrDiffTy, -1ULL); 480 llvm::Value *SrcArg = CGM.GenerateRTTIRef(SrcTy); 481 llvm::Value *DstArg = CGM.GenerateRTTIRef(DstTy); 482 V = Builder.CreateBitCast(V, PtrToInt8Ty); 483 V = Builder.CreateCall4(CGM.CreateRuntimeFunction(FTy, "__dynamic_cast"), 484 V, SrcArg, DstArg, hint); 485 V = Builder.CreateBitCast(V, LTy); 486 487 if (ThrowOnBad) { 488 BadCastBlock = createBasicBlock(); 489 490 llvm::Value *Zero = llvm::Constant::getNullValue(LTy); 491 Builder.CreateCondBr(Builder.CreateICmpNE(V, Zero), 492 ContBlock, BadCastBlock); 493 EmitBlock(BadCastBlock); 494 /// Call __cxa_bad_cast 495 ResultType = llvm::Type::getVoidTy(VMContext); 496 const llvm::FunctionType *FBadTy; 497 FBadTy = llvm::FunctionType::get(ResultType, false); 498 llvm::Value *F = CGM.CreateRuntimeFunction(FBadTy, "__cxa_bad_cast"); 499 Builder.CreateCall(F)->setDoesNotReturn(); 500 Builder.CreateUnreachable(); 501 } 502 } 503 504 if (CanBeZero) { 505 Builder.CreateBr(ContBlock); 506 EmitBlock(NullBlock); 507 Builder.CreateBr(ContBlock); 508 } 509 EmitBlock(ContBlock); 510 if (CanBeZero) { 511 llvm::PHINode *PHI = Builder.CreatePHI(LTy); 512 PHI->reserveOperandSpace(2); 513 PHI->addIncoming(V, NonZeroBlock); 514 PHI->addIncoming(llvm::Constant::getNullValue(LTy), NullBlock); 515 V = PHI; 516 } 517 518 return V; 519 } 520