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