blob: bf08caa3b43584677ad5f41a1c0d336d703c91a1 [file] [log] [blame]
Anders Carlsson16d81b82009-09-22 22:53:17 +00001//===--- CGCXXExpr.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
Anders Carlssona4d4c012009-09-23 16:07:23 +000018static uint64_t CalculateCookiePadding(ASTContext &Ctx, const CXXNewExpr *E) {
19 QualType T = E->getAllocatedType();
20
21 const RecordType *RT = T->getAs<RecordType>();
22 if (!RT)
23 return 0;
24
25 const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl());
26 if (!RD)
27 return 0;
28
29 // Check if the class has a trivial destructor.
30 if (RD->hasTrivialDestructor()) {
31 // FIXME: Check for a two-argument delete.
32 return 0;
33 }
34
35 // Padding is the maximum of sizeof(size_t) and alignof(T)
36 return std::max(Ctx.getTypeSize(Ctx.getSizeType()),
37 static_cast<uint64_t>(Ctx.getTypeAlign(T)));
38}
39
40static llvm::Value *EmitCXXNewAllocSize(CodeGenFunction &CGF,
41 const CXXNewExpr *E,
42 llvm::Value *& NumElements) {
43 QualType Type = E->getAllocatedType();
44 uint64_t TypeSizeInBytes = CGF.getContext().getTypeSize(Type) / 8;
45 const llvm::Type *SizeTy = CGF.ConvertType(CGF.getContext().getSizeType());
46
47 if (!E->isArray())
48 return llvm::ConstantInt::get(SizeTy, TypeSizeInBytes);
49
50 uint64_t CookiePadding = CalculateCookiePadding(CGF.getContext(), E);
51
52 Expr::EvalResult Result;
53 if (E->getArraySize()->Evaluate(Result, CGF.getContext()) &&
54 !Result.HasSideEffects && Result.Val.isInt()) {
55
56 uint64_t AllocSize =
57 Result.Val.getInt().getZExtValue() * TypeSizeInBytes + CookiePadding;
58
59 NumElements =
60 llvm::ConstantInt::get(SizeTy, Result.Val.getInt().getZExtValue());
61
62 return llvm::ConstantInt::get(SizeTy, AllocSize);
63 }
64
65 // Emit the array size expression.
66 NumElements = CGF.EmitScalarExpr(E->getArraySize());
67
68 // Multiply with the type size.
69 llvm::Value *V =
70 CGF.Builder.CreateMul(NumElements,
71 llvm::ConstantInt::get(SizeTy, TypeSizeInBytes));
72
73 // And add the cookie padding if necessary.
74 if (CookiePadding)
75 V = CGF.Builder.CreateAdd(V, llvm::ConstantInt::get(SizeTy, CookiePadding));
76
77 return V;
78}
79
80static void EmitNewInitializer(CodeGenFunction &CGF, const CXXNewExpr *E,
81 llvm::Value *NewPtr,
82 llvm::Value *NumElements) {
83 QualType AllocType = E->getAllocatedType();
84
85 if (!E->isArray()) {
86 if (CXXConstructorDecl *Ctor = E->getConstructor()) {
87 CGF.EmitCXXConstructorCall(Ctor, Ctor_Complete, NewPtr,
88 E->constructor_arg_begin(),
89 E->constructor_arg_end());
90
91 return;
92 }
93
94 // We have a POD type.
95 if (E->getNumConstructorArgs() == 0)
96 return;
97
98 assert(E->getNumConstructorArgs() == 1 &&
99 "Can only have one argument to initializer of POD type.");
100
101 const Expr *Init = E->getConstructorArg(0);
102
103 if (!CGF.hasAggregateLLVMType(AllocType))
104 CGF.Builder.CreateStore(CGF.EmitScalarExpr(Init), NewPtr);
105 else if (AllocType->isAnyComplexType())
106 CGF.EmitComplexExprIntoAddr(Init, NewPtr,
107 AllocType.isVolatileQualified());
108 else
109 CGF.EmitAggExpr(Init, NewPtr, AllocType.isVolatileQualified());
110 return;
111 }
112
113 if (CXXConstructorDecl *Ctor = E->getConstructor())
114 CGF.EmitCXXAggrConstructorCall(Ctor, NumElements, NewPtr);
115}
116
Anders Carlsson16d81b82009-09-22 22:53:17 +0000117llvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) {
Anders Carlssona4d4c012009-09-23 16:07:23 +0000118 if (E->isArray() && CalculateCookiePadding(getContext(), E)) {
Anders Carlsson16d81b82009-09-22 22:53:17 +0000119 ErrorUnsupported(E, "new[] expression");
120 return llvm::UndefValue::get(ConvertType(E->getType()));
121 }
122
123 QualType AllocType = E->getAllocatedType();
124 FunctionDecl *NewFD = E->getOperatorNew();
125 const FunctionProtoType *NewFTy = NewFD->getType()->getAs<FunctionProtoType>();
126
127 CallArgList NewArgs;
128
129 // The allocation size is the first argument.
130 QualType SizeTy = getContext().getSizeType();
Anders Carlsson16d81b82009-09-22 22:53:17 +0000131
Anders Carlssona4d4c012009-09-23 16:07:23 +0000132 llvm::Value *NumElements = 0;
133 llvm::Value *AllocSize = EmitCXXNewAllocSize(*this, E, NumElements);
134
Anders Carlsson16d81b82009-09-22 22:53:17 +0000135 NewArgs.push_back(std::make_pair(RValue::get(AllocSize), SizeTy));
136
137 // Emit the rest of the arguments.
138 // FIXME: Ideally, this should just use EmitCallArgs.
139 CXXNewExpr::const_arg_iterator NewArg = E->placement_arg_begin();
140
141 // First, use the types from the function type.
142 // We start at 1 here because the first argument (the allocation size)
143 // has already been emitted.
144 for (unsigned i = 1, e = NewFTy->getNumArgs(); i != e; ++i, ++NewArg) {
145 QualType ArgType = NewFTy->getArgType(i);
146
147 assert(getContext().getCanonicalType(ArgType.getNonReferenceType()).
148 getTypePtr() ==
149 getContext().getCanonicalType(NewArg->getType()).getTypePtr() &&
150 "type mismatch in call argument!");
151
152 NewArgs.push_back(std::make_pair(EmitCallArg(*NewArg, ArgType),
153 ArgType));
154
155 }
156
157 // Either we've emitted all the call args, or we have a call to a
158 // variadic function.
159 assert((NewArg == E->placement_arg_end() || NewFTy->isVariadic()) &&
160 "Extra arguments in non-variadic function!");
161
162 // If we still have any arguments, emit them using the type of the argument.
163 for (CXXNewExpr::const_arg_iterator NewArgEnd = E->placement_arg_end();
164 NewArg != NewArgEnd; ++NewArg) {
165 QualType ArgType = NewArg->getType();
166 NewArgs.push_back(std::make_pair(EmitCallArg(*NewArg, ArgType),
167 ArgType));
168 }
169
170 // Emit the call to new.
171 RValue RV =
172 EmitCall(CGM.getTypes().getFunctionInfo(NewFTy->getResultType(), NewArgs),
173 CGM.GetAddrOfFunction(NewFD), NewArgs, NewFD);
174
175 // If an allocation function is declared with an empty exception specification
176 // it returns null to indicate failure to allocate storage. [expr.new]p13.
177 // (We don't need to check for null when there's no new initializer and
178 // we're allocating a POD type).
179 bool NullCheckResult = NewFTy->hasEmptyExceptionSpec() &&
180 !(AllocType->isPODType() && !E->hasInitializer());
181
182 llvm::BasicBlock *NewNull = 0;
183 llvm::BasicBlock *NewNotNull = 0;
184 llvm::BasicBlock *NewEnd = 0;
185
186 llvm::Value *NewPtr = RV.getScalarVal();
187
188 if (NullCheckResult) {
189 NewNull = createBasicBlock("new.null");
190 NewNotNull = createBasicBlock("new.notnull");
191 NewEnd = createBasicBlock("new.end");
192
193 llvm::Value *IsNull =
194 Builder.CreateICmpEQ(NewPtr,
195 llvm::Constant::getNullValue(NewPtr->getType()),
196 "isnull");
197
198 Builder.CreateCondBr(IsNull, NewNull, NewNotNull);
199 EmitBlock(NewNotNull);
200 }
201
202 NewPtr = Builder.CreateBitCast(NewPtr, ConvertType(E->getType()));
203
Anders Carlssona4d4c012009-09-23 16:07:23 +0000204 EmitNewInitializer(*this, E, NewPtr, NumElements);
Anders Carlsson16d81b82009-09-22 22:53:17 +0000205
206 if (NullCheckResult) {
207 Builder.CreateBr(NewEnd);
208 EmitBlock(NewNull);
209 Builder.CreateBr(NewEnd);
210 EmitBlock(NewEnd);
211
212 llvm::PHINode *PHI = Builder.CreatePHI(NewPtr->getType());
213 PHI->reserveOperandSpace(2);
214 PHI->addIncoming(NewPtr, NewNotNull);
215 PHI->addIncoming(llvm::Constant::getNullValue(NewPtr->getType()), NewNull);
216
217 NewPtr = PHI;
218 }
219
220 return NewPtr;
221}
222
223void CodeGenFunction::EmitCXXDeleteExpr(const CXXDeleteExpr *E) {
224 if (E->isArrayForm()) {
225 ErrorUnsupported(E, "delete[] expression");
226 return;
227 };
228
229 QualType DeleteTy =
230 E->getArgument()->getType()->getAs<PointerType>()->getPointeeType();
231
232 llvm::Value *Ptr = EmitScalarExpr(E->getArgument());
233
234 // Null check the pointer.
235 llvm::BasicBlock *DeleteNotNull = createBasicBlock("delete.notnull");
236 llvm::BasicBlock *DeleteEnd = createBasicBlock("delete.end");
237
238 llvm::Value *IsNull =
239 Builder.CreateICmpEQ(Ptr, llvm::Constant::getNullValue(Ptr->getType()),
240 "isnull");
241
242 Builder.CreateCondBr(IsNull, DeleteEnd, DeleteNotNull);
243 EmitBlock(DeleteNotNull);
244
245 // Call the destructor if necessary.
246 if (const RecordType *RT = DeleteTy->getAs<RecordType>()) {
247 if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl())) {
248 if (!RD->hasTrivialDestructor()) {
249 const CXXDestructorDecl *Dtor = RD->getDestructor(getContext());
250 if (Dtor->isVirtual()) {
251 const llvm::Type *Ty =
252 CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(Dtor),
253 /*isVariadic=*/false);
254
255 llvm::Value *Callee = BuildVirtualCall(Dtor, Ptr, Ty);
256 EmitCXXMemberCall(Dtor, Callee, Ptr, 0, 0);
257 } else
258 EmitCXXDestructorCall(Dtor, Dtor_Complete, Ptr);
259 }
260 }
261 }
262
263 // Call delete.
264 FunctionDecl *DeleteFD = E->getOperatorDelete();
265 const FunctionProtoType *DeleteFTy =
266 DeleteFD->getType()->getAs<FunctionProtoType>();
267
268 CallArgList DeleteArgs;
269
270 QualType ArgTy = DeleteFTy->getArgType(0);
271 llvm::Value *DeletePtr = Builder.CreateBitCast(Ptr, ConvertType(ArgTy));
272 DeleteArgs.push_back(std::make_pair(RValue::get(DeletePtr), ArgTy));
273
274 // Emit the call to delete.
275 EmitCall(CGM.getTypes().getFunctionInfo(DeleteFTy->getResultType(),
276 DeleteArgs),
277 CGM.GetAddrOfFunction(DeleteFD),
278 DeleteArgs, DeleteFD);
279
280 EmitBlock(DeleteEnd);
281}