diff options
Diffstat (limited to 'lib/CodeGen/CGCXX.cpp')
-rw-r--r-- | lib/CodeGen/CGCXX.cpp | 612 |
1 files changed, 306 insertions, 306 deletions
diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp index f610de8276..e311912d95 100644 --- a/lib/CodeGen/CGCXX.cpp +++ b/lib/CodeGen/CGCXX.cpp @@ -11,7 +11,7 @@ // //===----------------------------------------------------------------------===// -// We might split this into multiple files if it gets too unwieldy +// We might split this into multiple files if it gets too unwieldy #include "CodeGenFunction.h" #include "CodeGenModule.h" @@ -25,54 +25,54 @@ using namespace clang; using namespace CodeGen; -void +void CodeGenFunction::EmitCXXGlobalDtorRegistration(const CXXDestructorDecl *Dtor, llvm::Constant *DeclPtr) { // FIXME: This is ABI dependent and we use the Itanium ABI. - - const llvm::Type *Int8PtrTy = + + const llvm::Type *Int8PtrTy = llvm::PointerType::getUnqual(llvm::Type::getInt8Ty(VMContext)); - + std::vector<const llvm::Type *> Params; Params.push_back(Int8PtrTy); - + // Get the destructor function type - const llvm::Type *DtorFnTy = + const llvm::Type *DtorFnTy = llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), Params, false); DtorFnTy = llvm::PointerType::getUnqual(DtorFnTy); - + Params.clear(); Params.push_back(DtorFnTy); Params.push_back(Int8PtrTy); Params.push_back(Int8PtrTy); - + // Get the __cxa_atexit function type // extern "C" int __cxa_atexit ( void (*f)(void *), void *p, void *d ); - const llvm::FunctionType *AtExitFnTy = + const llvm::FunctionType *AtExitFnTy = llvm::FunctionType::get(ConvertType(getContext().IntTy), Params, false); - + llvm::Constant *AtExitFn = CGM.CreateRuntimeFunction(AtExitFnTy, "__cxa_atexit"); - + llvm::Constant *Handle = CGM.CreateRuntimeVariable(Int8PtrTy, "__dso_handle"); - + llvm::Constant *DtorFn = CGM.GetAddrOfCXXDestructor(Dtor, Dtor_Complete); - + llvm::Value *Args[3] = { llvm::ConstantExpr::getBitCast(DtorFn, DtorFnTy), llvm::ConstantExpr::getBitCast(DeclPtr, Int8PtrTy), llvm::ConstantExpr::getBitCast(Handle, Int8PtrTy) }; Builder.CreateCall(AtExitFn, &Args[0], llvm::array_endof(Args)); } -void CodeGenFunction::EmitCXXGlobalVarDeclInit(const VarDecl &D, +void CodeGenFunction::EmitCXXGlobalVarDeclInit(const VarDecl &D, llvm::Constant *DeclPtr) { assert(D.hasGlobalStorage() && "VarDecl must have global storage!"); - + const Expr *Init = D.getInit(); QualType T = D.getType(); - + if (T->isReferenceType()) { ErrorUnsupported(Init, "global variable that binds to a reference"); } else if (!hasAggregateLLVMType(T)) { @@ -82,7 +82,7 @@ void CodeGenFunction::EmitCXXGlobalVarDeclInit(const VarDecl &D, EmitComplexExprIntoAddr(Init, DeclPtr, T.isVolatileQualified()); } else { EmitAggExpr(Init, DeclPtr, T.isVolatileQualified()); - + if (const RecordType *RT = T->getAs<RecordType>()) { CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl()); if (!RD->hasTrivialDestructor()) @@ -95,16 +95,16 @@ void CodeGenModule::EmitCXXGlobalInitFunc() { if (CXXGlobalInits.empty()) return; - + const llvm::FunctionType *FTy = llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), false); - + // Create our global initialization function. // FIXME: Should this be tweakable by targets? - llvm::Function *Fn = + llvm::Function *Fn = llvm::Function::Create(FTy, llvm::GlobalValue::InternalLinkage, "__cxx_global_initialization", &TheModule); - + CodeGenFunction(*this).GenerateCXXGlobalInitFunc(Fn, &CXXGlobalInits[0], CXXGlobalInits.size()); @@ -114,20 +114,20 @@ CodeGenModule::EmitCXXGlobalInitFunc() { void CodeGenFunction::GenerateCXXGlobalInitFunc(llvm::Function *Fn, const VarDecl **Decls, unsigned NumDecls) { - StartFunction(0, getContext().VoidTy, Fn, FunctionArgList(), + StartFunction(0, getContext().VoidTy, Fn, FunctionArgList(), SourceLocation()); - + for (unsigned i = 0; i != NumDecls; ++i) { const VarDecl *D = Decls[i]; - + llvm::Constant *DeclPtr = CGM.GetAddrOfGlobalVar(D); EmitCXXGlobalVarDeclInit(*D, DeclPtr); } FinishFunction(); } -void -CodeGenFunction::EmitStaticCXXBlockVarDeclInit(const VarDecl &D, +void +CodeGenFunction::EmitStaticCXXBlockVarDeclInit(const VarDecl &D, llvm::GlobalVariable *GV) { // FIXME: This should use __cxa_guard_{acquire,release}? @@ -137,36 +137,36 @@ CodeGenFunction::EmitStaticCXXBlockVarDeclInit(const VarDecl &D, llvm::SmallString<256> GuardVName; llvm::raw_svector_ostream GuardVOut(GuardVName); mangleGuardVariable(&D, getContext(), GuardVOut); - + // Create the guard variable. - llvm::GlobalValue *GuardV = + llvm::GlobalValue *GuardV = new llvm::GlobalVariable(CGM.getModule(), llvm::Type::getInt64Ty(VMContext), false, GV->getLinkage(), llvm::Constant::getNullValue(llvm::Type::getInt64Ty(VMContext)), GuardVName.str()); - + // Load the first byte of the guard variable. const llvm::Type *PtrTy = llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext), 0); - llvm::Value *V = Builder.CreateLoad(Builder.CreateBitCast(GuardV, PtrTy), + llvm::Value *V = Builder.CreateLoad(Builder.CreateBitCast(GuardV, PtrTy), "tmp"); - + // Compare it against 0. llvm::Value *nullValue = llvm::Constant::getNullValue(llvm::Type::getInt8Ty(VMContext)); llvm::Value *ICmp = Builder.CreateICmpEQ(V, nullValue , "tobool"); - + llvm::BasicBlock *InitBlock = createBasicBlock("init"); llvm::BasicBlock *EndBlock = createBasicBlock("init.end"); // If the guard variable is 0, jump to the initializer code. Builder.CreateCondBr(ICmp, InitBlock, EndBlock); - + EmitBlock(InitBlock); EmitCXXGlobalVarDeclInit(D, GV); Builder.CreateStore(llvm::ConstantInt::get(llvm::Type::getInt8Ty(VMContext), 1), Builder.CreateBitCast(GuardV, PtrTy)); - + EmitBlock(EndBlock); } @@ -175,25 +175,25 @@ RValue CodeGenFunction::EmitCXXMemberCall(const CXXMethodDecl *MD, llvm::Value *This, CallExpr::const_arg_iterator ArgBeg, CallExpr::const_arg_iterator ArgEnd) { - assert(MD->isInstance() && + assert(MD->isInstance() && "Trying to emit a member call expr on a static method!"); // A call to a trivial destructor requires no code generation. if (const CXXDestructorDecl *Destructor = dyn_cast<CXXDestructorDecl>(MD)) if (Destructor->isTrivial()) return RValue::get(0); - + const FunctionProtoType *FPT = MD->getType()->getAsFunctionProtoType(); - + CallArgList Args; - + // Push the this ptr. Args.push_back(std::make_pair(RValue::get(This), MD->getThisType(getContext()))); - + // And the rest of the call args EmitCallArgs(Args, FPT, ArgBeg, ArgEnd); - + QualType ResultType = MD->getType()->getAsFunctionType()->getResultType(); return EmitCall(CGM.getTypes().getFunctionInfo(ResultType, Args), Callee, Args, MD); @@ -205,11 +205,11 @@ RValue CodeGenFunction::EmitCXXMemberCallExpr(const CXXMemberCallExpr *CE) { const FunctionProtoType *FPT = MD->getType()->getAsFunctionProtoType(); - const llvm::Type *Ty = - CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD), + const llvm::Type *Ty = + CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD), FPT->isVariadic()); llvm::Value *This; - + if (ME->isArrow()) This = EmitScalarExpr(ME->getBase()); else { @@ -218,27 +218,27 @@ RValue CodeGenFunction::EmitCXXMemberCallExpr(const CXXMemberCallExpr *CE) { } // C++ [class.virtual]p12: - // Explicit qualification with the scope operator (5.1) suppresses the + // Explicit qualification with the scope operator (5.1) suppresses the // virtual call mechanism. llvm::Value *Callee; if (MD->isVirtual() && !ME->hasQualifier()) Callee = BuildVirtualCall(MD, This, Ty); - else if (const CXXDestructorDecl *Destructor + else if (const CXXDestructorDecl *Destructor = dyn_cast<CXXDestructorDecl>(MD)) Callee = CGM.GetAddrOfFunction(GlobalDecl(Destructor, Dtor_Complete), Ty); else Callee = CGM.GetAddrOfFunction(GlobalDecl(MD), Ty); - - return EmitCXXMemberCall(MD, Callee, This, + + return EmitCXXMemberCall(MD, Callee, This, CE->arg_begin(), CE->arg_end()); } -RValue +RValue CodeGenFunction::EmitCXXOperatorMemberCallExpr(const CXXOperatorCallExpr *E, const CXXMethodDecl *MD) { - assert(MD->isInstance() && + assert(MD->isInstance() && "Trying to emit a member call expr on a static method!"); - + if (MD->isCopyAssignment()) { const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(MD->getDeclContext()); if (ClassDecl->hasTrivialCopyAssignment()) { @@ -251,15 +251,15 @@ CodeGenFunction::EmitCXXOperatorMemberCallExpr(const CXXOperatorCallExpr *E, return RValue::get(This); } } - + const FunctionProtoType *FPT = MD->getType()->getAsFunctionProtoType(); - const llvm::Type *Ty = - CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD), + const llvm::Type *Ty = + CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD), FPT->isVariadic()); llvm::Constant *Callee = CGM.GetAddrOfFunction(GlobalDecl(MD), Ty); - + llvm::Value *This = EmitLValue(E->getArg(0)).getAddress(); - + return EmitCXXMemberCall(MD, Callee, This, E->arg_begin() + 1, E->arg_end()); } @@ -268,30 +268,30 @@ RValue CodeGenFunction::EmitCXXFunctionalCastExpr(const CXXFunctionalCastExpr *E) { assert((E->getCastKind() == CastExpr::CK_UserDefinedConversion) && "EmitCXXFunctionalCastExpr - called with wrong cast"); - + CXXMethodDecl *MD = E->getTypeConversionMethod(); assert(MD && "EmitCXXFunctionalCastExpr - null conversion method"); assert(isa<CXXConversionDecl>(MD) && "EmitCXXFunctionalCastExpr - not" " method decl"); const FunctionProtoType *FPT = MD->getType()->getAsFunctionProtoType(); - - const llvm::Type *Ty = - CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD), + + const llvm::Type *Ty = + CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD), FPT->isVariadic()); llvm::Constant *Callee = CGM.GetAddrOfFunction(GlobalDecl(MD), Ty); llvm::Value *This = EmitLValue(E->getSubExpr()).getAddress(); RValue RV = EmitCXXMemberCall(MD, Callee, This, 0, 0); if (RV.isAggregate()) - RV = RValue::get(RV.getAggregateAddr()); + RV = RValue::get(RV.getAggregateAddr()); return RV; } llvm::Value *CodeGenFunction::LoadCXXThis() { - assert(isa<CXXMethodDecl>(CurFuncDecl) && + assert(isa<CXXMethodDecl>(CurFuncDecl) && "Must be in a C++ member function decl to load 'this'"); assert(cast<CXXMethodDecl>(CurFuncDecl)->isInstance() && "Must be in a C++ member function decl to load 'this'"); - + // FIXME: What if we're inside a block? // ans: See how CodeGenFunction::LoadObjCSelf() uses // CodeGenFunction::BlockForwardSelf() for how to do this. @@ -306,7 +306,7 @@ GetNestedPaths(llvm::SmallVectorImpl<const CXXRecordDecl *> &NestedBasePaths, e = ClassDecl->bases_end(); i != e; ++i) { if (i->isVirtual()) continue; - const CXXRecordDecl *Base = + const CXXRecordDecl *Base = cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl()); if (Base == BaseClassDecl) { NestedBasePaths.push_back(BaseClassDecl); @@ -318,7 +318,7 @@ GetNestedPaths(llvm::SmallVectorImpl<const CXXRecordDecl *> &NestedBasePaths, e = ClassDecl->bases_end(); i != e; ++i) { if (i->isVirtual()) continue; - const CXXRecordDecl *Base = + const CXXRecordDecl *Base = cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl()); if (GetNestedPaths(NestedBasePaths, Base, BaseClassDecl)) { NestedBasePaths.push_back(Base); @@ -329,34 +329,34 @@ GetNestedPaths(llvm::SmallVectorImpl<const CXXRecordDecl *> &NestedBasePaths, } llvm::Value *CodeGenFunction::AddressCXXOfBaseClass(llvm::Value *BaseValue, - const CXXRecordDecl *ClassDecl, + const CXXRecordDecl *ClassDecl, const CXXRecordDecl *BaseClassDecl) { if (ClassDecl == BaseClassDecl) return BaseValue; - + llvm::Type *I8Ptr = llvm::PointerType::getUnqual(llvm::Type::getInt8Ty(VMContext)); llvm::SmallVector<const CXXRecordDecl *, 16> NestedBasePaths; GetNestedPaths(NestedBasePaths, ClassDecl, BaseClassDecl); - assert(NestedBasePaths.size() > 0 && + assert(NestedBasePaths.size() > 0 && "AddressCXXOfBaseClass - inheritence path failed"); NestedBasePaths.push_back(ClassDecl); uint64_t Offset = 0; - + // Accessing a member of the base class. Must add delata to // the load of 'this'. for (unsigned i = NestedBasePaths.size()-1; i > 0; i--) { const CXXRecordDecl *DerivedClass = NestedBasePaths[i]; const CXXRecordDecl *BaseClass = NestedBasePaths[i-1]; - const ASTRecordLayout &Layout = + const ASTRecordLayout &Layout = getContext().getASTRecordLayout(DerivedClass); Offset += Layout.getBaseClassOffset(BaseClass) / 8; } - llvm::Value *OffsetVal = + llvm::Value *OffsetVal = llvm::ConstantInt::get( CGM.getTypes().ConvertType(CGM.getContext().LongTy), Offset); BaseValue = Builder.CreateBitCast(BaseValue, I8Ptr); BaseValue = Builder.CreateGEP(BaseValue, OffsetVal, "add.ptr"); - QualType BTy = + QualType BTy = getContext().getCanonicalType( getContext().getTypeDeclType(const_cast<CXXRecordDecl*>(BaseClassDecl))); const llvm::Type *BasePtr = ConvertType(BTy); @@ -377,52 +377,52 @@ CodeGenFunction::EmitCXXAggrConstructorCall(const CXXConstructorDecl *D, llvm::Value *This) { const ConstantArrayType *CA = dyn_cast<ConstantArrayType>(Array); assert(CA && "Do we support VLA for construction ?"); - + // Create a temporary for the loop index and initialize it with 0. llvm::Value *IndexPtr = CreateTempAlloca(llvm::Type::getInt64Ty(VMContext), "loop.index"); - llvm::Value* zeroConstant = + llvm::Value* zeroConstant = llvm::Constant::getNullValue(llvm::Type::getInt64Ty(VMContext)); Builder.CreateStore(zeroConstant, IndexPtr, false); - + // Start the loop with a block that tests the condition. llvm::BasicBlock *CondBlock = createBasicBlock("for.cond"); llvm::BasicBlock *AfterFor = createBasicBlock("for.end"); - + EmitBlock(CondBlock); - + llvm::BasicBlock *ForBody = createBasicBlock("for.body"); - + // Generate: if (loop-index < number-of-elements fall to the loop body, // otherwise, go to the block after the for-loop. uint64_t NumElements = getContext().getConstantArrayElementCount(CA); - llvm::Value * NumElementsPtr = + llvm::Value * NumElementsPtr = llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), NumElements); llvm::Value *Counter = Builder.CreateLoad(IndexPtr); - llvm::Value *IsLess = Builder.CreateICmpULT(Counter, NumElementsPtr, + llvm::Value *IsLess = Builder.CreateICmpULT(Counter, NumElementsPtr, "isless"); // If the condition is true, execute the body. Builder.CreateCondBr(IsLess, ForBody, AfterFor); - + EmitBlock(ForBody); - + llvm::BasicBlock *ContinueBlock = createBasicBlock("for.inc"); // Inside the loop body, emit the constructor call on the array element. Counter = Builder.CreateLoad(IndexPtr); llvm::Value *Address = Builder.CreateInBoundsGEP(This, Counter, "arrayidx"); EmitCXXConstructorCall(D, Ctor_Complete, Address, 0, 0); - + EmitBlock(ContinueBlock); - + // Emit the increment of the loop counter. llvm::Value *NextVal = llvm::ConstantInt::get(Counter->getType(), 1); Counter = Builder.CreateLoad(IndexPtr); NextVal = Builder.CreateAdd(Counter, NextVal, "inc"); Builder.CreateStore(NextVal, IndexPtr, false); - + // Finally, branch back up to the condition for the next iteration. EmitBranch(CondBlock); - + // Emit the fall-through block. EmitBlock(AfterFor, true); } @@ -435,7 +435,7 @@ CodeGenFunction::EmitCXXAggrDestructorCall(const CXXDestructorDecl *D, llvm::Value *This) { const ConstantArrayType *CA = dyn_cast<ConstantArrayType>(Array); assert(CA && "Do we support VLA for destruction ?"); - llvm::Value *One = llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), + llvm::Value *One = llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), 1); uint64_t ElementCount = getContext().getConstantArrayElementCount(CA); // Create a temporary for the loop index and initialize it with count of @@ -443,54 +443,54 @@ CodeGenFunction::EmitCXXAggrDestructorCall(const CXXDestructorDecl *D, llvm::Value *IndexPtr = CreateTempAlloca(llvm::Type::getInt64Ty(VMContext), "loop.index"); // Index = ElementCount; - llvm::Value* UpperCount = + llvm::Value* UpperCount = llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), ElementCount); Builder.CreateStore(UpperCount, IndexPtr, false); - + // Start the loop with a block that tests the condition. llvm::BasicBlock *CondBlock = createBasicBlock("for.cond"); llvm::BasicBlock *AfterFor = createBasicBlock("for.end"); - + EmitBlock(CondBlock); - + llvm::BasicBlock *ForBody = createBasicBlock("for.body"); - + // Generate: if (loop-index != 0 fall to the loop body, // otherwise, go to the block after the for-loop. - llvm::Value* zeroConstant = + llvm::Value* zeroConstant = llvm::Constant::getNullValue(llvm::Type::getInt64Ty(VMContext)); llvm::Value *Counter = Builder.CreateLoad(IndexPtr); llvm::Value *IsNE = Builder.CreateICmpNE(Counter, zeroConstant, "isne"); // If the condition is true, execute the body. Builder.CreateCondBr(IsNE, ForBody, AfterFor); - + EmitBlock(ForBody); - + llvm::BasicBlock *ContinueBlock = createBasicBlock("for.inc"); // Inside the loop body, emit the constructor call on the array element. Counter = Builder.CreateLoad(IndexPtr); Counter = Builder.CreateSub(Counter, One); llvm::Value *Address = Builder.CreateInBoundsGEP(This, Counter, "arrayidx"); EmitCXXDestructorCall(D, Dtor_Complete, Address); - + EmitBlock(ContinueBlock); - + // Emit the decrement of the loop counter. Counter = Builder.CreateLoad(IndexPtr); Counter = Builder.CreateSub(Counter, One, "dec"); Builder.CreateStore(Counter, IndexPtr, false); - + // Finally, branch back up to the condition for the next iteration. EmitBranch(CondBlock); - + // Emit the fall-through block. EmitBlock(AfterFor, true); } void -CodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D, - CXXCtorType Type, +CodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D, + CXXCtorType Type, llvm::Value *This, CallExpr::const_arg_iterator ArgBeg, CallExpr::const_arg_iterator ArgEnd) { @@ -506,31 +506,31 @@ CodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D, return; } } - + llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(D, Type); EmitCXXMemberCall(D, Callee, This, ArgBeg, ArgEnd); } -void CodeGenFunction::EmitCXXDestructorCall(const CXXDestructorDecl *D, +void CodeGenFunction::EmitCXXDestructorCall(const CXXDestructorDecl *D, CXXDtorType Type, llvm::Value *This) { llvm::Value *Callee = CGM.GetAddrOfCXXDestructor(D, Type); - + EmitCXXMemberCall(D, Callee, This, 0, 0); } -void -CodeGenFunction::EmitCXXConstructExpr(llvm::Value *Dest, +void +CodeGenFunction::EmitCXXConstructExpr(llvm::Value *Dest, const CXXConstructExpr *E) { assert(Dest && "Must have a destination!"); - - const CXXRecordDecl *RD = + + const CXXRecordDecl *RD = cast<CXXRecordDecl>(E->getType()->getAs<RecordType>()->getDecl()); if (RD->hasTrivialConstructor()) return; - // Code gen optimization to eliminate copy constructor and return + // Code gen optimization to eliminate copy constructor and return // its first argument instead. if (getContext().getLangOptions().ElideConstructors && E->isElidable()) { CXXConstructExpr::const_arg_iterator i = E->arg_begin(); @@ -538,7 +538,7 @@ CodeGenFunction::EmitCXXConstructExpr(llvm::Value *Dest, return; } // Call the constructor. - EmitCXXConstructorCall(E->getConstructor(), Ctor_Complete, Dest, + EmitCXXConstructorCall(E->getConstructor(), Ctor_Complete, Dest, E->arg_begin(), E->arg_end()); } @@ -547,21 +547,21 @@ llvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) { ErrorUnsupported(E, "new[] expression"); return llvm::UndefValue::get(ConvertType(E->getType())); } - + QualType AllocType = E->getAllocatedType(); FunctionDecl *NewFD = E->getOperatorNew(); const FunctionProtoType *NewFTy = NewFD->getType()->getAsFunctionProtoType(); - + CallArgList NewArgs; // The allocation size is the first argument. QualType SizeTy = getContext().getSizeType(); - llvm::Value *AllocSize = - llvm::ConstantInt::get(ConvertType(SizeTy), + 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(); @@ -571,24 +571,24 @@ llvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) { // 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() && + getTypePtr() == + getContext().getCanonicalType(NewArg->getType()).getTypePtr() && "type mismatch in call argument!"); - - NewArgs.push_back(std::make_pair(EmitCallArg(*NewArg, ArgType), + + 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 + + // 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()) && + 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(); + 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), @@ -596,7 +596,7 @@ llvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) { } // Emit the call to new. - RValue RV = + RValue RV = EmitCall(CGM.getTypes().getFunctionInfo(NewFTy->getResultType(), NewArgs), CGM.GetAddrOfFunction(GlobalDecl(NewFD)), NewArgs, NewFD); @@ -618,26 +618,26 @@ llvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) { NewNull = createBasicBlock("new.null"); NewNotNull = createBasicBlock("new.notnull"); NewEnd = createBasicBlock("new.end"); - - llvm::Value *IsNull = - Builder.CreateICmpEQ(NewPtr, + + 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 && + assert(E->getNumConstructorArgs() == 1 && "Can only have one argument to initializer of POD type."); const Expr *Init = E->getConstructorArg(0); - - if (!hasAggregateLLVMType(AllocType)) + + if (!hasAggregateLLVMType(AllocType)) Builder.CreateStore(EmitScalarExpr(Init), NewPtr); else if (AllocType->isAnyComplexType()) EmitComplexExprIntoAddr(Init, NewPtr, AllocType.isVolatileQualified()); @@ -645,11 +645,11 @@ llvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) { EmitAggExpr(Init, NewPtr, AllocType.isVolatileQualified()); } } else { - // Call the constructor. + // Call the constructor. CXXConstructorDecl *Ctor = E->getConstructor(); - - EmitCXXConstructorCall(Ctor, Ctor_Complete, NewPtr, - E->constructor_arg_begin(), + + EmitCXXConstructorCall(Ctor, Ctor_Complete, NewPtr, + E->constructor_arg_begin(), E->constructor_arg_end()); } @@ -658,15 +658,15 @@ llvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) { 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; } @@ -676,22 +676,22 @@ void CodeGenFunction::EmitCXXDeleteExpr(const CXXDeleteExpr *E) { return; }; - QualType DeleteTy = + 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 = + 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())) { @@ -701,29 +701,29 @@ void CodeGenFunction::EmitCXXDeleteExpr(const CXXDeleteExpr *E) { ErrorUnsupported(E, "delete expression with virtual destructor"); return; } - + EmitCXXDestructorCall(Dtor, Dtor_Complete, Ptr); } } } - + // Call delete. FunctionDecl *DeleteFD = E->getOperatorDelete(); - const FunctionProtoType *DeleteFTy = + const FunctionProtoType *DeleteFTy = DeleteFD->getType()->getAsFunctionProtoType(); - + 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(), + EmitCall(CGM.getTypes().getFunctionInfo(DeleteFTy->getResultType(), DeleteArgs), CGM.GetAddrOfFunction(GlobalDecl(DeleteFD)), DeleteArgs, DeleteFD); - + EmitBlock(DeleteEnd); } @@ -732,34 +732,34 @@ void CodeGenModule::EmitCXXConstructors(const CXXConstructorDecl *D) { EmitGlobal(GlobalDecl(D, Ctor_Base)); } -void CodeGenModule::EmitCXXConstructor(const CXXConstructorDecl *D, +void CodeGenModule::EmitCXXConstructor(const CXXConstructorDecl *D, CXXCtorType Type) { - + llvm::Function *Fn = GetAddrOfCXXConstructor(D, Type); - + CodeGenFunction(*this).GenerateCode(D, Fn); - + SetFunctionDefinitionAttributes(D, Fn); SetLLVMFunctionAttributesForDefinition(D, Fn); } llvm::Function * -CodeGenModule::GetAddrOfCXXConstructor(const CXXConstructorDecl *D, +CodeGenModule::GetAddrOfCXXConstructor(const CXXConstructorDecl *D, CXXCtorType Type) { const llvm::FunctionType *FTy = getTypes().GetFunctionType(getTypes().getFunctionInfo(D), false); - + const char *Name = getMangledCXXCtorName(D, Type); return cast<llvm::Function>( GetOrCreateLLVMFunction(Name, FTy, GlobalDecl(D, Type))); } -const char *CodeGenModule::getMangledCXXCtorName(const CXXConstructorDecl *D, +const char *CodeGenModule::getMangledCXXCtorName(const CXXConstructorDecl *D, CXXCtorType Type) { llvm::SmallString<256> Name; llvm::raw_svector_ostream Out(Name); mangleCXXCtor(D, Type, Context, Out); - + Name += '\0'; return UniqueMangledName(Name.begin(), Name.end()); } @@ -769,33 +769,33 @@ void CodeGenModule::EmitCXXDestructors(const CXXDestructorDecl *D) { EmitCXXDestructor(D, Dtor_Base); } -void CodeGenModule::EmitCXXDestructor(const CXXDestructorDecl *D, +void CodeGenModule::EmitCXXDestructor(const CXXDestructorDecl *D, CXXDtorType Type) { llvm::Function *Fn = GetAddrOfCXXDestructor(D, Type); - + CodeGenFunction(*this).GenerateCode(D, Fn); - + SetFunctionDefinitionAttributes(D, Fn); SetLLVMFunctionAttributesForDefinition(D, Fn); } llvm::Function * -CodeGenModule::GetAddrOfCXXDestructor(const CXXDestructorDecl *D, +CodeGenModule::GetAddrOfCXXDestructor(const CXXDestructorDecl *D, CXXDtorType Type) { const llvm::FunctionType *FTy = getTypes().GetFunctionType(getTypes().getFunctionInfo(D), false); - + const char *Name = getMangledCXXDtorName(D, Type); return cast<llvm::Function>( GetOrCreateLLVMFunction(Name, FTy, GlobalDecl(D, Type))); } -const char *CodeGenModule::getMangledCXXDtorName(const CXXDestructorDecl *D, +const char *CodeGenModule::getMangledCXXDtorName(const CXXDestructorDecl *D, CXXDtorType Type) { llvm::SmallString<256> Name; llvm::raw_svector_ostream Out(Name); mangleCXXDtor(D, Type, Context, Out); - + Name += '\0'; return UniqueMangledName(Name.begin(), Name.end()); } @@ -891,7 +891,7 @@ public: const CXXRecordDecl *RD, uint64_t Offset) { for (CXXRecordDecl::base_class_const_iterator i =RD->bases_begin(), e = RD->bases_end(); i != e; ++i) { - const CXXRecordDecl *Base = + const CXXRecordDecl *Base = cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl()); if (i->isVirtual() && !SeenVBase.count(Base)) { SeenVBase.insert(Base); @@ -998,7 +998,7 @@ public: // If we can find a previously allocated slot for this, reuse it. if (OverrideMethod(MD, m, MorallyVirtual, Offset)) return; - + // else allocate a new slot. Index[MD] = submethods.size(); submethods.push_back(m); @@ -1029,7 +1029,7 @@ public: e = RD->bases_end(); i != e; ++i) { if (i->isVirtual()) continue; - const CXXRecordDecl *Base = + const CXXRecordDecl *Base = cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl()); if (Base != PrimaryBase || PrimaryBaseWasVirtual) { uint64_t o = Offset + Layout.getBaseClassOffset(Base); @@ -1090,7 +1090,7 @@ public: return; const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD); - const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase(); + const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase(); const bool PrimaryBaseWasVirtual = Layout.getPrimaryBaseWasVirtual(); // vtables are composed from the chain of primaries. @@ -1113,7 +1113,7 @@ public: return 0; const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD); - const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase(); + const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase(); const bool PrimaryBaseWasVirtual = Layout.getPrimaryBaseWasVirtual(); std::vector<llvm::Constant *> offsets; @@ -1154,7 +1154,7 @@ public: Path->push_back(std::make_pair(RD, Offset)); for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(), e = RD->bases_end(); i != e; ++i) { - const CXXRecordDecl *Base = + const CXXRecordDecl *Base = cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl()); if (i->isVirtual() && !IndirectPrimary.count(Base)) { // Mark it so we don't output it twice. @@ -1306,7 +1306,7 @@ llvm::Value * CodeGenFunction::BuildVirtualCall(const CXXMethodDecl *MD, llvm::Value *&This, const llvm::Type *Ty) { // FIXME: If we know the dynamic type, we don't have to do a virtual dispatch. - + // FIXME: move to Context if (vtableinfo == 0) vtableinfo = new VtableInfo(CGM); @@ -1328,39 +1328,39 @@ CodeGenFunction::BuildVirtualCall(const CXXMethodDecl *MD, llvm::Value *&This, /// array of objects from SrcValue to DestValue. Copying can be either a bitwise /// copy or via a copy constructor call. // FIXME. Consolidate this with EmitCXXAggrConstructorCall. -void CodeGenFunction::EmitClassAggrMemberwiseCopy(llvm::Value *Dest, +void CodeGenFunction::EmitClassAggrMemberwiseCopy(llvm::Value *Dest, llvm::Value *Src, const ArrayType *Array, - const CXXRecordDecl *BaseClassDecl, + const CXXRecordDecl *BaseClassDecl, QualType Ty) { const ConstantArrayType *CA = dyn_cast<ConstantArrayType>(Array); assert(CA && "VLA cannot be copied over"); bool BitwiseCopy = BaseClassDecl->hasTrivialCopyConstructor(); - + // Create a temporary for the loop index and initialize it with 0. llvm::Value *IndexPtr = CreateTempAlloca(llvm::Type::getInt64Ty(VMContext), "loop.index"); - llvm::Value* zeroConstant = + llvm::Value* zeroConstant = llvm::Constant::getNullValue(llvm::Type::getInt64Ty(VMContext)); Builder.CreateStore(zeroConstant, IndexPtr, false); // Start the loop with a block that tests the condition. llvm::BasicBlock *CondBlock = createBasicBlock("for.cond"); llvm::BasicBlock *AfterFor = createBasicBlock("for.end"); - + EmitBlock(CondBlock); - + llvm::BasicBlock *ForBody = createBasicBlock("for.body"); // Generate: if (loop-index < number-of-elements fall to the loop body, // otherwise, go to the block after the for-loop. uint64_t NumElements = getContext().getConstantArrayElementCount(CA); - llvm::Value * NumElementsPtr = + llvm::Value * NumElementsPtr = llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), NumElements); llvm::Value *Counter = Builder.CreateLoad(IndexPtr); - llvm::Value *IsLess = Builder.CreateICmpULT(Counter, NumElementsPtr, + llvm::Value *IsLess = Builder.CreateICmpULT(Counter, NumElementsPtr, "isless"); // If the condition is true, execute the body. Builder.CreateCondBr(IsLess, ForBody, AfterFor); - + EmitBlock(ForBody); llvm::BasicBlock *ContinueBlock = createBasicBlock("for.inc"); // Inside the loop body, emit |