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