aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGCXX.cpp
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@mac.com>2009-09-22 22:53:17 +0000
committerAnders Carlsson <andersca@mac.com>2009-09-22 22:53:17 +0000
commit16d81b8db39593b5f1a38b077757272a09c12da8 (patch)
tree717db0d371e22f999d01eb21df3bc57c95026677 /lib/CodeGen/CGCXX.cpp
parent45504e568c6f8fedc4457ed563eab65d8ab7f87d (diff)
Move codegen of new and delete to CGCXXExpr.cpp
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@82585 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGCXX.cpp')
-rw-r--r--lib/CodeGen/CGCXX.cpp187
1 files changed, 0 insertions, 187 deletions
diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp
index 91b984ac2c..0e5b8f6a37 100644
--- a/lib/CodeGen/CGCXX.cpp
+++ b/lib/CodeGen/CGCXX.cpp
@@ -453,193 +453,6 @@ CodeGenFunction::EmitCXXConstructExpr(llvm::Value *Dest,
E->arg_begin(), E->arg_end());
}
-llvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) {
- if (E->isArray()) {
- ErrorUnsupported(E, "new[] expression");
- return llvm::UndefValue::get(ConvertType(E->getType()));
- }
-
- QualType AllocType = E->getAllocatedType();
- FunctionDecl *NewFD = E->getOperatorNew();
- const FunctionProtoType *NewFTy = NewFD->getType()->getAs<FunctionProtoType>();
-
- CallArgList NewArgs;
-
- // The allocation size is the first argument.
- QualType SizeTy = getContext().getSizeType();
- llvm::Value *AllocSize =
- llvm::ConstantInt::get(ConvertType(SizeTy),
- getContext().getTypeSize(AllocType) / 8);
-
- NewArgs.push_back(std::make_pair(RValue::get(AllocSize), SizeTy));
-
- // Emit the rest of the arguments.
- // FIXME: Ideally, this should just use EmitCallArgs.
- CXXNewExpr::const_arg_iterator NewArg = E->placement_arg_begin();
-
- // First, use the types from the function type.
- // We start at 1 here because the first argument (the allocation size)
- // has already been emitted.
- for (unsigned i = 1, e = NewFTy->getNumArgs(); i != e; ++i, ++NewArg) {
- QualType ArgType = NewFTy->getArgType(i);
-
- assert(getContext().getCanonicalType(ArgType.getNonReferenceType()).
- getTypePtr() ==
- getContext().getCanonicalType(NewArg->getType()).getTypePtr() &&
- "type mismatch in call argument!");
-
- NewArgs.push_back(std::make_pair(EmitCallArg(*NewArg, ArgType),
- ArgType));
-
- }
-
- // Either we've emitted all the call args, or we have a call to a
- // variadic function.
- assert((NewArg == E->placement_arg_end() || NewFTy->isVariadic()) &&
- "Extra arguments in non-variadic function!");
-
- // If we still have any arguments, emit them using the type of the argument.
- for (CXXNewExpr::const_arg_iterator NewArgEnd = E->placement_arg_end();
- NewArg != NewArgEnd; ++NewArg) {
- QualType ArgType = NewArg->getType();
- NewArgs.push_back(std::make_pair(EmitCallArg(*NewArg, ArgType),
- ArgType));
- }
-
- // Emit the call to new.
- RValue RV =
- EmitCall(CGM.getTypes().getFunctionInfo(NewFTy->getResultType(), NewArgs),
- CGM.GetAddrOfFunction(NewFD), NewArgs, NewFD);
-
- // If an allocation function is declared with an empty exception specification
- // it returns null to indicate failure to allocate storage. [expr.new]p13.
- // (We don't need to check for null when there's no new initializer and
- // we're allocating a POD type).
- bool NullCheckResult = NewFTy->hasEmptyExceptionSpec() &&
- !(AllocType->isPODType() && !E->hasInitializer());
-
- llvm::BasicBlock *NewNull = 0;
- llvm::BasicBlock *NewNotNull = 0;
- llvm::BasicBlock *NewEnd = 0;
-
- llvm::Value *NewPtr = RV.getScalarVal();
-
- if (NullCheckResult) {
- NewNull = createBasicBlock("new.null");
- NewNotNull = createBasicBlock("new.notnull");
- NewEnd = createBasicBlock("new.end");
-
- llvm::Value *IsNull =
- Builder.CreateICmpEQ(NewPtr,
- llvm::Constant::getNullValue(NewPtr->getType()),
- "isnull");
-
- Builder.CreateCondBr(IsNull, NewNull, NewNotNull);
- EmitBlock(NewNotNull);
- }
-
- NewPtr = Builder.CreateBitCast(NewPtr, ConvertType(E->getType()));
-
- if (AllocType->isPODType()) {
- if (E->getNumConstructorArgs() > 0) {
- assert(E->getNumConstructorArgs() == 1 &&
- "Can only have one argument to initializer of POD type.");
-
- const Expr *Init = E->getConstructorArg(0);
-
- if (!hasAggregateLLVMType(AllocType))
- Builder.CreateStore(EmitScalarExpr(Init), NewPtr);
- else if (AllocType->isAnyComplexType())
- EmitComplexExprIntoAddr(Init, NewPtr, AllocType.isVolatileQualified());
- else
- EmitAggExpr(Init, NewPtr, AllocType.isVolatileQualified());
- }
- } else {
- // Call the constructor.
- CXXConstructorDecl *Ctor = E->getConstructor();
-
- EmitCXXConstructorCall(Ctor, Ctor_Complete, NewPtr,
- E->constructor_arg_begin(),
- E->constructor_arg_end());
- }
-
- if (NullCheckResult) {
- Builder.CreateBr(NewEnd);
- EmitBlock(NewNull);
- Builder.CreateBr(NewEnd);
- EmitBlock(NewEnd);
-
- llvm::PHINode *PHI = Builder.CreatePHI(NewPtr->getType());
- PHI->reserveOperandSpace(2);
- PHI->addIncoming(NewPtr, NewNotNull);
- PHI->addIncoming(llvm::Constant::getNullValue(NewPtr->getType()), NewNull);
-
- NewPtr = PHI;
- }
-
- return NewPtr;
-}
-
-void CodeGenFunction::EmitCXXDeleteExpr(const CXXDeleteExpr *E) {
- if (E->isArrayForm()) {
- ErrorUnsupported(E, "delete[] expression");
- return;
- };
-
- QualType DeleteTy =
- E->getArgument()->getType()->getAs<PointerType>()->getPointeeType();
-
- llvm::Value *Ptr = EmitScalarExpr(E->getArgument());
-
- // Null check the pointer.
- llvm::BasicBlock *DeleteNotNull = createBasicBlock("delete.notnull");
- llvm::BasicBlock *DeleteEnd = createBasicBlock("delete.end");
-
- llvm::Value *IsNull =
- Builder.CreateICmpEQ(Ptr, llvm::Constant::getNullValue(Ptr->getType()),
- "isnull");
-
- Builder.CreateCondBr(IsNull, DeleteEnd, DeleteNotNull);
- EmitBlock(DeleteNotNull);
-
- // Call the destructor if necessary.
- if (const RecordType *RT = DeleteTy->getAs<RecordType>()) {
- if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl())) {
- if (!RD->hasTrivialDestructor()) {
- const CXXDestructorDecl *Dtor = RD->getDestructor(getContext());
- if (Dtor->isVirtual()) {
- const llvm::Type *Ty =
- CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(Dtor),
- /*isVariadic=*/false);
-
- llvm::Value *Callee = BuildVirtualCall(Dtor, Ptr, Ty);
- EmitCXXMemberCall(Dtor, Callee, Ptr, 0, 0);
- } else
- EmitCXXDestructorCall(Dtor, Dtor_Complete, Ptr);
- }
- }
- }
-
- // Call delete.
- FunctionDecl *DeleteFD = E->getOperatorDelete();
- const FunctionProtoType *DeleteFTy =
- DeleteFD->getType()->getAs<FunctionProtoType>();
-
- CallArgList DeleteArgs;
-
- QualType ArgTy = DeleteFTy->getArgType(0);
- llvm::Value *DeletePtr = Builder.CreateBitCast(Ptr, ConvertType(ArgTy));
- DeleteArgs.push_back(std::make_pair(RValue::get(DeletePtr), ArgTy));
-
- // Emit the call to delete.
- EmitCall(CGM.getTypes().getFunctionInfo(DeleteFTy->getResultType(),
- DeleteArgs),
- CGM.GetAddrOfFunction(DeleteFD),
- DeleteArgs, DeleteFD);
-
- EmitBlock(DeleteEnd);
-}
-
void CodeGenModule::EmitCXXConstructors(const CXXConstructorDecl *D) {
EmitGlobal(GlobalDecl(D, Ctor_Complete));
EmitGlobal(GlobalDecl(D, Ctor_Base));