[cfe-commits] r89742 - in /cfe/trunk/lib/CodeGen: CGCXXClass.cpp CGCXXExpr.cpp CGCXXTemp.cpp CGClass.cpp CGExprCXX.cpp CGTemporaries.cpp CMakeLists.txt
Anders Carlsson
andersca at mac.com
Mon Nov 23 21:51:11 PST 2009
Author: andersca
Date: Mon Nov 23 23:51:11 2009
New Revision: 89742
URL: http://llvm.org/viewvc/llvm-project?rev=89742&view=rev
Log:
Get rid of the ugly CGCXX names and replace them with CGClass, CGExprCXX and CGTemporaries.
Added:
cfe/trunk/lib/CodeGen/CGClass.cpp
- copied, changed from r89734, cfe/trunk/lib/CodeGen/CGCXXClass.cpp
cfe/trunk/lib/CodeGen/CGExprCXX.cpp
- copied, changed from r89734, cfe/trunk/lib/CodeGen/CGCXXExpr.cpp
cfe/trunk/lib/CodeGen/CGTemporaries.cpp
- copied, changed from r89734, cfe/trunk/lib/CodeGen/CGCXXTemp.cpp
Removed:
cfe/trunk/lib/CodeGen/CGCXXClass.cpp
cfe/trunk/lib/CodeGen/CGCXXExpr.cpp
cfe/trunk/lib/CodeGen/CGCXXTemp.cpp
Modified:
cfe/trunk/lib/CodeGen/CMakeLists.txt
Removed: cfe/trunk/lib/CodeGen/CGCXXClass.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCXXClass.cpp?rev=89741&view=auto
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCXXClass.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCXXClass.cpp (removed)
@@ -1,239 +0,0 @@
-//===--- CGCXXClass.cpp - Emit LLVM Code for C++ classes ------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This contains code dealing with C++ code generation of classes
-//
-//===----------------------------------------------------------------------===//
-
-#include "CodeGenFunction.h"
-#include "clang/AST/CXXInheritance.h"
-#include "clang/AST/RecordLayout.h"
-
-using namespace clang;
-using namespace CodeGen;
-
-static uint64_t
-ComputeNonVirtualBaseClassOffset(ASTContext &Context, CXXBasePaths &Paths,
- unsigned Start) {
- uint64_t Offset = 0;
-
- const CXXBasePath &Path = Paths.front();
- for (unsigned i = Start, e = Path.size(); i != e; ++i) {
- const CXXBasePathElement& Element = Path[i];
-
- // Get the layout.
- const ASTRecordLayout &Layout = Context.getASTRecordLayout(Element.Class);
-
- const CXXBaseSpecifier *BS = Element.Base;
- // FIXME: enable test3 from virt.cc to not abort.
- if (BS->isVirtual())
- return 0;
- assert(!BS->isVirtual() && "Should not see virtual bases here!");
-
- const CXXRecordDecl *Base =
- cast<CXXRecordDecl>(BS->getType()->getAs<RecordType>()->getDecl());
-
- // Add the offset.
- Offset += Layout.getBaseClassOffset(Base) / 8;
- }
-
- return Offset;
-}
-
-llvm::Constant *
-CodeGenModule::GetCXXBaseClassOffset(const CXXRecordDecl *ClassDecl,
- const CXXRecordDecl *BaseClassDecl) {
- if (ClassDecl == BaseClassDecl)
- return 0;
-
- CXXBasePaths Paths(/*FindAmbiguities=*/false,
- /*RecordPaths=*/true, /*DetectVirtual=*/false);
- if (!const_cast<CXXRecordDecl *>(ClassDecl)->
- isDerivedFrom(const_cast<CXXRecordDecl *>(BaseClassDecl), Paths)) {
- assert(false && "Class must be derived from the passed in base class!");
- return 0;
- }
-
- uint64_t Offset = ComputeNonVirtualBaseClassOffset(getContext(), Paths, 0);
- if (!Offset)
- return 0;
-
- const llvm::Type *PtrDiffTy =
- Types.ConvertType(getContext().getPointerDiffType());
-
- return llvm::ConstantInt::get(PtrDiffTy, Offset);
-}
-
-static llvm::Value *GetCXXBaseClassOffset(CodeGenFunction &CGF,
- llvm::Value *BaseValue,
- const CXXRecordDecl *ClassDecl,
- const CXXRecordDecl *BaseClassDecl) {
- CXXBasePaths Paths(/*FindAmbiguities=*/false,
- /*RecordPaths=*/true, /*DetectVirtual=*/true);
- if (!const_cast<CXXRecordDecl *>(ClassDecl)->
- isDerivedFrom(const_cast<CXXRecordDecl *>(BaseClassDecl), Paths)) {
- assert(false && "Class must be derived from the passed in base class!");
- return 0;
- }
-
- unsigned Start = 0;
- llvm::Value *VirtualOffset = 0;
- if (const RecordType *RT = Paths.getDetectedVirtual()) {
- const CXXRecordDecl *VBase = cast<CXXRecordDecl>(RT->getDecl());
-
- VirtualOffset =
- CGF.GetVirtualCXXBaseClassOffset(BaseValue, ClassDecl, VBase);
-
- const CXXBasePath &Path = Paths.front();
- unsigned e = Path.size();
- for (Start = 0; Start != e; ++Start) {
- const CXXBasePathElement& Element = Path[Start];
-
- if (Element.Class == VBase)
- break;
- }
- }
-
- uint64_t Offset =
- ComputeNonVirtualBaseClassOffset(CGF.getContext(), Paths, Start);
-
- if (!Offset)
- return VirtualOffset;
-
- const llvm::Type *PtrDiffTy =
- CGF.ConvertType(CGF.getContext().getPointerDiffType());
- llvm::Value *NonVirtualOffset = llvm::ConstantInt::get(PtrDiffTy, Offset);
-
- if (VirtualOffset)
- return CGF.Builder.CreateAdd(VirtualOffset, NonVirtualOffset);
-
- return NonVirtualOffset;
-}
-
-llvm::Value *
-CodeGenFunction::GetAddressOfBaseClass(llvm::Value *Value,
- const CXXRecordDecl *ClassDecl,
- const CXXRecordDecl *BaseClassDecl,
- bool NullCheckValue) {
- QualType BTy =
- getContext().getCanonicalType(
- getContext().getTypeDeclType(const_cast<CXXRecordDecl*>(BaseClassDecl)));
- const llvm::Type *BasePtrTy = llvm::PointerType::getUnqual(ConvertType(BTy));
-
- if (ClassDecl == BaseClassDecl) {
- // Just cast back.
- return Builder.CreateBitCast(Value, BasePtrTy);
- }
-
- llvm::BasicBlock *CastNull = 0;
- llvm::BasicBlock *CastNotNull = 0;
- llvm::BasicBlock *CastEnd = 0;
-
- if (NullCheckValue) {
- CastNull = createBasicBlock("cast.null");
- CastNotNull = createBasicBlock("cast.notnull");
- CastEnd = createBasicBlock("cast.end");
-
- llvm::Value *IsNull =
- Builder.CreateICmpEQ(Value,
- llvm::Constant::getNullValue(Value->getType()));
- Builder.CreateCondBr(IsNull, CastNull, CastNotNull);
- EmitBlock(CastNotNull);
- }
-
- const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(VMContext);
-
- llvm::Value *Offset =
- GetCXXBaseClassOffset(*this, Value, ClassDecl, BaseClassDecl);
-
- if (Offset) {
- // Apply the offset.
- Value = Builder.CreateBitCast(Value, Int8PtrTy);
- Value = Builder.CreateGEP(Value, Offset, "add.ptr");
- }
-
- // Cast back.
- Value = Builder.CreateBitCast(Value, BasePtrTy);
-
- if (NullCheckValue) {
- Builder.CreateBr(CastEnd);
- EmitBlock(CastNull);
- Builder.CreateBr(CastEnd);
- EmitBlock(CastEnd);
-
- llvm::PHINode *PHI = Builder.CreatePHI(Value->getType());
- PHI->reserveOperandSpace(2);
- PHI->addIncoming(Value, CastNotNull);
- PHI->addIncoming(llvm::Constant::getNullValue(Value->getType()),
- CastNull);
- Value = PHI;
- }
-
- return Value;
-}
-
-llvm::Value *
-CodeGenFunction::GetAddressOfDerivedClass(llvm::Value *Value,
- const CXXRecordDecl *ClassDecl,
- const CXXRecordDecl *DerivedClassDecl,
- bool NullCheckValue) {
- QualType DerivedTy =
- getContext().getCanonicalType(
- getContext().getTypeDeclType(const_cast<CXXRecordDecl*>(DerivedClassDecl)));
- const llvm::Type *DerivedPtrTy = ConvertType(DerivedTy)->getPointerTo();
-
- if (ClassDecl == DerivedClassDecl) {
- // Just cast back.
- return Builder.CreateBitCast(Value, DerivedPtrTy);
- }
-
- llvm::BasicBlock *CastNull = 0;
- llvm::BasicBlock *CastNotNull = 0;
- llvm::BasicBlock *CastEnd = 0;
-
- if (NullCheckValue) {
- CastNull = createBasicBlock("cast.null");
- CastNotNull = createBasicBlock("cast.notnull");
- CastEnd = createBasicBlock("cast.end");
-
- llvm::Value *IsNull =
- Builder.CreateICmpEQ(Value,
- llvm::Constant::getNullValue(Value->getType()));
- Builder.CreateCondBr(IsNull, CastNull, CastNotNull);
- EmitBlock(CastNotNull);
- }
-
- llvm::Value *Offset = GetCXXBaseClassOffset(*this, Value, DerivedClassDecl,
- ClassDecl);
- if (Offset) {
- // Apply the offset.
- Value = Builder.CreatePtrToInt(Value, Offset->getType());
- Value = Builder.CreateSub(Value, Offset);
- Value = Builder.CreateIntToPtr(Value, DerivedPtrTy);
- } else {
- // Just cast.
- Value = Builder.CreateBitCast(Value, DerivedPtrTy);
- }
-
- if (NullCheckValue) {
- Builder.CreateBr(CastEnd);
- EmitBlock(CastNull);
- Builder.CreateBr(CastEnd);
- EmitBlock(CastEnd);
-
- llvm::PHINode *PHI = Builder.CreatePHI(Value->getType());
- PHI->reserveOperandSpace(2);
- PHI->addIncoming(Value, CastNotNull);
- PHI->addIncoming(llvm::Constant::getNullValue(Value->getType()),
- CastNull);
- Value = PHI;
- }
-
- return Value;
-}
Removed: cfe/trunk/lib/CodeGen/CGCXXExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCXXExpr.cpp?rev=89741&view=auto
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCXXExpr.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCXXExpr.cpp (removed)
@@ -1,525 +0,0 @@
-//===--- CGCXXExpr.cpp - Emit LLVM Code for C++ expressions ---------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This contains code dealing with code generation of C++ expressions
-//
-//===----------------------------------------------------------------------===//
-
-#include "CodeGenFunction.h"
-using namespace clang;
-using namespace CodeGen;
-
-static uint64_t CalculateCookiePadding(ASTContext &Ctx, const CXXNewExpr *E) {
- if (!E->isArray())
- return 0;
-
- QualType T = E->getAllocatedType();
-
- const RecordType *RT = T->getAs<RecordType>();
- if (!RT)
- return 0;
-
- const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl());
- if (!RD)
- return 0;
-
- // Check if the class has a trivial destructor.
- if (RD->hasTrivialDestructor()) {
- // FIXME: Check for a two-argument delete.
- return 0;
- }
-
- // Padding is the maximum of sizeof(size_t) and alignof(T)
- return std::max(Ctx.getTypeSize(Ctx.getSizeType()),
- static_cast<uint64_t>(Ctx.getTypeAlign(T))) / 8;
-}
-
-static llvm::Value *EmitCXXNewAllocSize(CodeGenFunction &CGF,
- const CXXNewExpr *E,
- llvm::Value *& NumElements) {
- QualType Type = E->getAllocatedType();
- uint64_t TypeSizeInBytes = CGF.getContext().getTypeSize(Type) / 8;
- const llvm::Type *SizeTy = CGF.ConvertType(CGF.getContext().getSizeType());
-
- if (!E->isArray())
- return llvm::ConstantInt::get(SizeTy, TypeSizeInBytes);
-
- uint64_t CookiePadding = CalculateCookiePadding(CGF.getContext(), E);
-
- Expr::EvalResult Result;
- if (E->getArraySize()->Evaluate(Result, CGF.getContext()) &&
- !Result.HasSideEffects && Result.Val.isInt()) {
-
- uint64_t AllocSize =
- Result.Val.getInt().getZExtValue() * TypeSizeInBytes + CookiePadding;
-
- NumElements =
- llvm::ConstantInt::get(SizeTy, Result.Val.getInt().getZExtValue());
-
- return llvm::ConstantInt::get(SizeTy, AllocSize);
- }
-
- // Emit the array size expression.
- NumElements = CGF.EmitScalarExpr(E->getArraySize());
-
- // Multiply with the type size.
- llvm::Value *V =
- CGF.Builder.CreateMul(NumElements,
- llvm::ConstantInt::get(SizeTy, TypeSizeInBytes));
-
- // And add the cookie padding if necessary.
- if (CookiePadding)
- V = CGF.Builder.CreateAdd(V, llvm::ConstantInt::get(SizeTy, CookiePadding));
-
- return V;
-}
-
-static void EmitNewInitializer(CodeGenFunction &CGF, const CXXNewExpr *E,
- llvm::Value *NewPtr,
- llvm::Value *NumElements) {
- QualType AllocType = E->getAllocatedType();
-
- if (!E->isArray()) {
- if (CXXConstructorDecl *Ctor = E->getConstructor()) {
- CGF.EmitCXXConstructorCall(Ctor, Ctor_Complete, NewPtr,
- E->constructor_arg_begin(),
- E->constructor_arg_end());
-
- return;
- }
-
- // We have a POD type.
- if (E->getNumConstructorArgs() == 0)
- return;
-
- assert(E->getNumConstructorArgs() == 1 &&
- "Can only have one argument to initializer of POD type.");
-
- const Expr *Init = E->getConstructorArg(0);
-
- if (!CGF.hasAggregateLLVMType(AllocType))
- CGF.EmitStoreOfScalar(CGF.EmitScalarExpr(Init), NewPtr,
- AllocType.isVolatileQualified(), AllocType);
- else if (AllocType->isAnyComplexType())
- CGF.EmitComplexExprIntoAddr(Init, NewPtr,
- AllocType.isVolatileQualified());
- else
- CGF.EmitAggExpr(Init, NewPtr, AllocType.isVolatileQualified());
- return;
- }
-
- if (CXXConstructorDecl *Ctor = E->getConstructor())
- CGF.EmitCXXAggrConstructorCall(Ctor, NumElements, NewPtr);
-}
-
-llvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) {
- 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 *NumElements = 0;
- llvm::Value *AllocSize = EmitCXXNewAllocSize(*this, E, NumElements);
-
- 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);
- }
-
- if (uint64_t CookiePadding = CalculateCookiePadding(getContext(), E)) {
- uint64_t CookieOffset =
- CookiePadding - getContext().getTypeSize(SizeTy) / 8;
-
- llvm::Value *NumElementsPtr =
- Builder.CreateConstInBoundsGEP1_64(NewPtr, CookieOffset);
-
- NumElementsPtr = Builder.CreateBitCast(NumElementsPtr,
- ConvertType(SizeTy)->getPointerTo());
- Builder.CreateStore(NumElements, NumElementsPtr);
-
- // Now add the padding to the new ptr.
- NewPtr = Builder.CreateConstInBoundsGEP1_64(NewPtr, CookiePadding);
- }
-
- NewPtr = Builder.CreateBitCast(NewPtr, ConvertType(E->getType()));
-
- EmitNewInitializer(*this, E, NewPtr, NumElements);
-
- if (NullCheckResult) {
- Builder.CreateBr(NewEnd);
- NewNotNull = Builder.GetInsertBlock();
- 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::EmitDeleteCall(const FunctionDecl *DeleteFD,
- llvm::Value *Ptr,
- QualType DeleteTy) {
- 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));
-
- if (DeleteFTy->getNumArgs() == 2) {
- QualType SizeTy = DeleteFTy->getArgType(1);
- uint64_t SizeVal = getContext().getTypeSize(DeleteTy) / 8;
- llvm::Constant *Size = llvm::ConstantInt::get(ConvertType(SizeTy),
- SizeVal);
- DeleteArgs.push_back(std::make_pair(RValue::get(Size), SizeTy));
- }
-
- // Emit the call to delete.
- EmitCall(CGM.getTypes().getFunctionInfo(DeleteFTy->getResultType(),
- DeleteArgs),
- CGM.GetAddrOfFunction(DeleteFD),
- DeleteArgs, DeleteFD);
-}
-
-void CodeGenFunction::EmitCXXDeleteExpr(const CXXDeleteExpr *E) {
-
- // Get at the argument before we performed the implicit conversion
- // to void*.
- const Expr *Arg = E->getArgument();
- while (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Arg)) {
- if (ICE->getCastKind() != CastExpr::CK_UserDefinedConversion &&
- ICE->getType()->isVoidPointerType())
- Arg = ICE->getSubExpr();
- else
- break;
- }
-
- QualType DeleteTy = Arg->getType()->getAs<PointerType>()->getPointeeType();
-
- llvm::Value *Ptr = EmitScalarExpr(Arg);
-
- // 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);
-
- bool ShouldCallDelete = true;
-
- // 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 (E->isArrayForm()) {
- QualType SizeTy = getContext().getSizeType();
- uint64_t CookiePadding = std::max(getContext().getTypeSize(SizeTy),
- static_cast<uint64_t>(getContext().getTypeAlign(DeleteTy))) / 8;
- if (CookiePadding) {
- llvm::Type *Ptr8Ty =
- llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext), 0);
- uint64_t CookieOffset =
- CookiePadding - getContext().getTypeSize(SizeTy) / 8;
- llvm::Value *AllocatedObjectPtr =
- Builder.CreateConstInBoundsGEP1_64(
- Builder.CreateBitCast(Ptr, Ptr8Ty), -CookiePadding);
- llvm::Value *NumElementsPtr =
- Builder.CreateConstInBoundsGEP1_64(AllocatedObjectPtr,
- CookieOffset);
- NumElementsPtr = Builder.CreateBitCast(NumElementsPtr,
- ConvertType(SizeTy)->getPointerTo());
-
- llvm::Value *NumElements =
- Builder.CreateLoad(NumElementsPtr);
- NumElements =
- Builder.CreateIntCast(NumElements,
- llvm::Type::getInt64Ty(VMContext), false,
- "count.tmp");
- EmitCXXAggrDestructorCall(Dtor, NumElements, Ptr);
- Ptr = AllocatedObjectPtr;
- }
- }
- else if (Dtor->isVirtual()) {
- const llvm::Type *Ty =
- CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(Dtor),
- /*isVariadic=*/false);
-
- llvm::Value *Callee = BuildVirtualCall(Dtor, Dtor_Deleting, Ptr, Ty);
- EmitCXXMemberCall(Dtor, Callee, Ptr, 0, 0);
-
- // The dtor took care of deleting the object.
- ShouldCallDelete = false;
- } else
- EmitCXXDestructorCall(Dtor, Dtor_Complete, Ptr);
- }
- }
- }
-
- if (ShouldCallDelete)
- EmitDeleteCall(E->getOperatorDelete(), Ptr, DeleteTy);
-
- EmitBlock(DeleteEnd);
-}
-
-llvm::Value * CodeGenFunction::EmitCXXTypeidExpr(const CXXTypeidExpr *E) {
- QualType Ty = E->getType();
- const llvm::Type *LTy = ConvertType(Ty)->getPointerTo();
- if (E->isTypeOperand()) {
- Ty = E->getTypeOperand();
- CanQualType CanTy = CGM.getContext().getCanonicalType(Ty);
- Ty = CanTy.getUnqualifiedType().getNonReferenceType();
- if (const RecordType *RT = Ty->getAs<RecordType>()) {
- const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
- if (RD->isPolymorphic())
- return Builder.CreateBitCast(CGM.GenerateRttiRef(RD), LTy);
- return Builder.CreateBitCast(CGM.GenerateRtti(RD), LTy);
- }
- return Builder.CreateBitCast(CGM.GenerateRtti(Ty), LTy);
- }
- Expr *subE = E->getExprOperand();
- Ty = subE->getType();
- CanQualType CanTy = CGM.getContext().getCanonicalType(Ty);
- Ty = CanTy.getUnqualifiedType().getNonReferenceType();
- if (const RecordType *RT = Ty->getAs<RecordType>()) {
- const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
- if (RD->isPolymorphic()) {
- // FIXME: if subE is an lvalue do
- LValue Obj = EmitLValue(subE);
- llvm::Value *This = Obj.getAddress();
- LTy = LTy->getPointerTo()->getPointerTo();
- llvm::Value *V = Builder.CreateBitCast(This, LTy);
- // We need to do a zero check for *p, unless it has NonNullAttr.
- // FIXME: PointerType->hasAttr<NonNullAttr>()
- bool CanBeZero = false;
- if (UnaryOperator *UO = dyn_cast<UnaryOperator>(subE->IgnoreParens()))
- if (UO->getOpcode() == UnaryOperator::Deref)
- CanBeZero = true;
- if (CanBeZero) {
- llvm::BasicBlock *NonZeroBlock = createBasicBlock();
- llvm::BasicBlock *ZeroBlock = createBasicBlock();
-
- llvm::Value *Zero = llvm::Constant::getNullValue(LTy);
- Builder.CreateCondBr(Builder.CreateICmpNE(V, Zero),
- NonZeroBlock, ZeroBlock);
- EmitBlock(ZeroBlock);
- /// Call __cxa_bad_typeid
- const llvm::Type *ResultType = llvm::Type::getVoidTy(VMContext);
- const llvm::FunctionType *FTy;
- FTy = llvm::FunctionType::get(ResultType, false);
- llvm::Value *F = CGM.CreateRuntimeFunction(FTy, "__cxa_bad_typeid");
- Builder.CreateCall(F)->setDoesNotReturn();
- Builder.CreateUnreachable();
- EmitBlock(NonZeroBlock);
- }
- V = Builder.CreateLoad(V, "vtable");
- V = Builder.CreateConstInBoundsGEP1_64(V, -1ULL);
- V = Builder.CreateLoad(V);
- return V;
- }
- return Builder.CreateBitCast(CGM.GenerateRtti(RD), LTy);
- }
- return Builder.CreateBitCast(CGM.GenerateRtti(Ty), LTy);
-}
-
-llvm::Value *CodeGenFunction::EmitDynamicCast(llvm::Value *V,
- const CXXDynamicCastExpr *DCE) {
- QualType CastTy = DCE->getTypeAsWritten();
- QualType InnerType = CastTy->getPointeeType();
- QualType ArgTy = DCE->getSubExpr()->getType();
- const llvm::Type *LArgTy = ConvertType(ArgTy);
- const llvm::Type *LTy = ConvertType(DCE->getType());
-
- bool CanBeZero = false;
- bool ToVoid = false;
- bool ThrowOnBad = false;
- if (CastTy->isPointerType()) {
- // FIXME: if PointerType->hasAttr<NonNullAttr>(), we don't set this
- CanBeZero = true;
- if (InnerType->isVoidType())
- ToVoid = true;
- } else {
- LTy = LTy->getPointerTo();
- ThrowOnBad = true;
- }
-
- CXXRecordDecl *SrcTy;
- QualType Ty = ArgTy;
- if (ArgTy.getTypePtr()->isPointerType()
- || ArgTy.getTypePtr()->isReferenceType())
- Ty = Ty.getTypePtr()->getPointeeType();
- CanQualType CanTy = CGM.getContext().getCanonicalType(Ty);
- Ty = CanTy.getUnqualifiedType();
- SrcTy = cast<CXXRecordDecl>(Ty->getAs<RecordType>()->getDecl());
-
- llvm::BasicBlock *ContBlock = createBasicBlock();
- llvm::BasicBlock *NullBlock = 0;
- llvm::BasicBlock *NonZeroBlock = 0;
- if (CanBeZero) {
- NonZeroBlock = createBasicBlock();
- NullBlock = createBasicBlock();
- llvm::Value *Zero = llvm::Constant::getNullValue(LArgTy);
- Builder.CreateCondBr(Builder.CreateICmpNE(V, Zero),
- NonZeroBlock, NullBlock);
- EmitBlock(NonZeroBlock);
- }
-
- llvm::BasicBlock *BadCastBlock = 0;
-
- const llvm::Type *PtrDiffTy = ConvertType(getContext().getSizeType());
-
- // See if this is a dynamic_cast(void*)
- if (ToVoid) {
- llvm::Value *This = V;
- V = Builder.CreateBitCast(This, PtrDiffTy->getPointerTo()->getPointerTo());
- V = Builder.CreateLoad(V, "vtable");
- V = Builder.CreateConstInBoundsGEP1_64(V, -2ULL);
- V = Builder.CreateLoad(V, "offset to top");
- This = Builder.CreateBitCast(This, llvm::Type::getInt8PtrTy(VMContext));
- V = Builder.CreateInBoundsGEP(This, V);
- V = Builder.CreateBitCast(V, LTy);
- } else {
- /// Call __dynamic_cast
- const llvm::Type *ResultType = llvm::Type::getInt8PtrTy(VMContext);
- const llvm::FunctionType *FTy;
- std::vector<const llvm::Type*> ArgTys;
- const llvm::Type *PtrToInt8Ty
- = llvm::Type::getInt8Ty(VMContext)->getPointerTo();
- ArgTys.push_back(PtrToInt8Ty);
- ArgTys.push_back(PtrToInt8Ty);
- ArgTys.push_back(PtrToInt8Ty);
- ArgTys.push_back(PtrDiffTy);
- FTy = llvm::FunctionType::get(ResultType, ArgTys, false);
- CXXRecordDecl *DstTy;
- Ty = CastTy.getTypePtr()->getPointeeType();
- CanTy = CGM.getContext().getCanonicalType(Ty);
- Ty = CanTy.getUnqualifiedType();
- DstTy = cast<CXXRecordDecl>(Ty->getAs<RecordType>()->getDecl());
-
- // FIXME: Calculate better hint.
- llvm::Value *hint = llvm::ConstantInt::get(PtrDiffTy, -1ULL);
- llvm::Value *SrcArg = CGM.GenerateRttiRef(SrcTy);
- llvm::Value *DstArg = CGM.GenerateRttiRef(DstTy);
- V = Builder.CreateBitCast(V, PtrToInt8Ty);
- V = Builder.CreateCall4(CGM.CreateRuntimeFunction(FTy, "__dynamic_cast"),
- V, SrcArg, DstArg, hint);
- V = Builder.CreateBitCast(V, LTy);
-
- if (ThrowOnBad) {
- BadCastBlock = createBasicBlock();
-
- llvm::Value *Zero = llvm::Constant::getNullValue(LTy);
- Builder.CreateCondBr(Builder.CreateICmpNE(V, Zero),
- ContBlock, BadCastBlock);
- EmitBlock(BadCastBlock);
- /// Call __cxa_bad_cast
- ResultType = llvm::Type::getVoidTy(VMContext);
- const llvm::FunctionType *FBadTy;
- FBadTy = llvm::FunctionType::get(ResultType, false);
- llvm::Value *F = CGM.CreateRuntimeFunction(FBadTy, "__cxa_bad_cast");
- Builder.CreateCall(F)->setDoesNotReturn();
- Builder.CreateUnreachable();
- }
- }
-
- if (CanBeZero) {
- Builder.CreateBr(ContBlock);
- EmitBlock(NullBlock);
- Builder.CreateBr(ContBlock);
- }
- EmitBlock(ContBlock);
- if (CanBeZero) {
- llvm::PHINode *PHI = Builder.CreatePHI(LTy);
- PHI->reserveOperandSpace(2);
- PHI->addIncoming(V, NonZeroBlock);
- PHI->addIncoming(llvm::Constant::getNullValue(LTy), NullBlock);
- V = PHI;
- }
-
- return V;
-}
Removed: cfe/trunk/lib/CodeGen/CGCXXTemp.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCXXTemp.cpp?rev=89741&view=auto
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCXXTemp.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCXXTemp.cpp (removed)
@@ -1,143 +0,0 @@
-//===--- CGCXXTemp.cpp - Emit LLVM Code for C++ temporaries ---------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This contains code dealing with C++ code generation of temporaries
-//
-//===----------------------------------------------------------------------===//
-
-#include "CodeGenFunction.h"
-using namespace clang;
-using namespace CodeGen;
-
-void CodeGenFunction::PushCXXTemporary(const CXXTemporary *Temporary,
- llvm::Value *Ptr) {
- llvm::BasicBlock *DtorBlock = createBasicBlock("temp.dtor");
-
- llvm::Value *CondPtr = 0;
-
- // Check if temporaries need to be conditional. If so, we'll create a
- // condition boolean, initialize it to 0 and
- if (ConditionalBranchLevel != 0) {
- CondPtr = CreateTempAlloca(llvm::Type::getInt1Ty(VMContext), "cond");
-
- // Initialize it to false. This initialization takes place right after
- // the alloca insert point.
- llvm::StoreInst *SI =
- new llvm::StoreInst(llvm::ConstantInt::getFalse(VMContext), CondPtr);
- llvm::BasicBlock *Block = AllocaInsertPt->getParent();
- Block->getInstList().insertAfter((llvm::Instruction *)AllocaInsertPt, SI);
-
- // Now set it to true.
- Builder.CreateStore(llvm::ConstantInt::getTrue(VMContext), CondPtr);
- }
-
- LiveTemporaries.push_back(CXXLiveTemporaryInfo(Temporary, Ptr, DtorBlock,
- CondPtr));
-
- PushCleanupBlock(DtorBlock);
-}
-
-void CodeGenFunction::PopCXXTemporary() {
- const CXXLiveTemporaryInfo& Info = LiveTemporaries.back();
-
- CleanupBlockInfo CleanupInfo = PopCleanupBlock();
- assert(CleanupInfo.CleanupBlock == Info.DtorBlock &&
- "Cleanup block mismatch!");
- assert(!CleanupInfo.SwitchBlock &&
- "Should not have a switch block for temporary cleanup!");
- assert(!CleanupInfo.EndBlock &&
- "Should not have an end block for temporary cleanup!");
-
- llvm::BasicBlock *CurBB = Builder.GetInsertBlock();
- if (CurBB && !CurBB->getTerminator() &&
- Info.DtorBlock->getNumUses() == 0) {
- CurBB->getInstList().splice(CurBB->end(), Info.DtorBlock->getInstList());
- delete Info.DtorBlock;
- } else
- EmitBlock(Info.DtorBlock);
-
- llvm::BasicBlock *CondEnd = 0;
-
- // If this is a conditional temporary, we need to check the condition
- // boolean and only call the destructor if it's true.
- if (Info.CondPtr) {
- llvm::BasicBlock *CondBlock = createBasicBlock("cond.dtor.call");
- CondEnd = createBasicBlock("cond.dtor.end");
-
- llvm::Value *Cond = Builder.CreateLoad(Info.CondPtr);
- Builder.CreateCondBr(Cond, CondBlock, CondEnd);
- EmitBlock(CondBlock);
- }
-
- EmitCXXDestructorCall(Info.Temporary->getDestructor(),
- Dtor_Complete, Info.ThisPtr);
-
- if (CondEnd) {
- // Reset the condition. to false.
- Builder.CreateStore(llvm::ConstantInt::getFalse(VMContext), Info.CondPtr);
- EmitBlock(CondEnd);
- }
-
- LiveTemporaries.pop_back();
-}
-
-RValue
-CodeGenFunction::EmitCXXExprWithTemporaries(const CXXExprWithTemporaries *E,
- llvm::Value *AggLoc,
- bool IsAggLocVolatile,
- bool IsInitializer) {
- // If we shouldn't destroy the temporaries, just emit the
- // child expression.
- if (!E->shouldDestroyTemporaries())
- return EmitAnyExpr(E->getSubExpr(), AggLoc, IsAggLocVolatile,
- /*IgnoreResult=*/false, IsInitializer);
-
- // Keep track of the current cleanup stack depth.
- size_t CleanupStackDepth = CleanupEntries.size();
- (void) CleanupStackDepth;
-
- unsigned OldNumLiveTemporaries = LiveTemporaries.size();
-
- RValue RV = EmitAnyExpr(E->getSubExpr(), AggLoc, IsAggLocVolatile,
- /*IgnoreResult=*/false, IsInitializer);
-
- // Pop temporaries.
- while (LiveTemporaries.size() > OldNumLiveTemporaries)
- PopCXXTemporary();
-
- assert(CleanupEntries.size() == CleanupStackDepth &&
- "Cleanup size mismatch!");
-
- return RV;
-}
-
-LValue CodeGenFunction::EmitCXXExprWithTemporariesLValue(
- const CXXExprWithTemporaries *E) {
- // If we shouldn't destroy the temporaries, just emit the
- // child expression.
- if (!E->shouldDestroyTemporaries())
- return EmitLValue(E->getSubExpr());
-
- // Keep track of the current cleanup stack depth.
- size_t CleanupStackDepth = CleanupEntries.size();
- (void) CleanupStackDepth;
-
- unsigned OldNumLiveTemporaries = LiveTemporaries.size();
-
- LValue LV = EmitLValue(E->getSubExpr());
-
- // Pop temporaries.
- while (LiveTemporaries.size() > OldNumLiveTemporaries)
- PopCXXTemporary();
-
- assert(CleanupEntries.size() == CleanupStackDepth &&
- "Cleanup size mismatch!");
-
- return LV;
-}
Copied: cfe/trunk/lib/CodeGen/CGClass.cpp (from r89734, cfe/trunk/lib/CodeGen/CGCXXClass.cpp)
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGClass.cpp?p2=cfe/trunk/lib/CodeGen/CGClass.cpp&p1=cfe/trunk/lib/CodeGen/CGCXXClass.cpp&r1=89734&r2=89742&rev=89742&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCXXClass.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGClass.cpp Mon Nov 23 23:51:11 2009
@@ -1,4 +1,4 @@
-//===--- CGCXXClass.cpp - Emit LLVM Code for C++ classes ------------------===//
+//===--- CGClass.cpp - Emit LLVM Code for C++ classes ---------------------===//
//
// The LLVM Compiler Infrastructure
//
Copied: cfe/trunk/lib/CodeGen/CGExprCXX.cpp (from r89734, cfe/trunk/lib/CodeGen/CGCXXExpr.cpp)
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprCXX.cpp?p2=cfe/trunk/lib/CodeGen/CGExprCXX.cpp&p1=cfe/trunk/lib/CodeGen/CGCXXExpr.cpp&r1=89734&r2=89742&rev=89742&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCXXExpr.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprCXX.cpp Mon Nov 23 23:51:11 2009
@@ -1,4 +1,4 @@
-//===--- CGCXXExpr.cpp - Emit LLVM Code for C++ expressions ---------------===//
+//===--- CGExprCXX.cpp - Emit LLVM Code for C++ expressions ---------------===//
//
// The LLVM Compiler Infrastructure
//
Copied: cfe/trunk/lib/CodeGen/CGTemporaries.cpp (from r89734, cfe/trunk/lib/CodeGen/CGCXXTemp.cpp)
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGTemporaries.cpp?p2=cfe/trunk/lib/CodeGen/CGTemporaries.cpp&p1=cfe/trunk/lib/CodeGen/CGCXXTemp.cpp&r1=89734&r2=89742&rev=89742&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCXXTemp.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGTemporaries.cpp Mon Nov 23 23:51:11 2009
@@ -1,4 +1,4 @@
-//===--- CGCXXTemp.cpp - Emit LLVM Code for C++ temporaries ---------------===//
+//===--- CGTemporaries.cpp - Emit LLVM Code for C++ temporaries -----------===//
//
// The LLVM Compiler Infrastructure
//
Modified: cfe/trunk/lib/CodeGen/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CMakeLists.txt?rev=89742&r1=89741&r2=89742&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CMakeLists.txt (original)
+++ cfe/trunk/lib/CodeGen/CMakeLists.txt Mon Nov 23 23:51:11 2009
@@ -3,11 +3,9 @@
add_clang_library(clangCodeGen
CGBlocks.cpp
CGBuiltin.cpp
- CGCXX.cpp
- CGCXXClass.cpp
- CGCXXExpr.cpp
- CGCXXTemp.cpp
CGCall.cpp
+ CGClass.cpp
+ CGCXX.cpp
CGDebugInfo.cpp
CGDecl.cpp
CGException.cpp
@@ -15,6 +13,7 @@
CGExprAgg.cpp
CGExprComplex.cpp
CGExprConstant.cpp
+ CGExprCXX.cpp
CGExprScalar.cpp
CGObjC.cpp
CGObjCGNU.cpp
@@ -22,6 +21,7 @@
CGRecordLayoutBuilder.cpp
CGRtti.cpp
CGStmt.cpp
+ CGTemporaries.cpp
CGVtable.cpp
CodeGenFunction.cpp
CodeGenModule.cpp
More information about the cfe-commits
mailing list