diff options
| author | Roman Divacky <rdivacky@FreeBSD.org> | 2010-04-02 08:55:10 +0000 | 
|---|---|---|
| committer | Roman Divacky <rdivacky@FreeBSD.org> | 2010-04-02 08:55:10 +0000 | 
| commit | 11d2b2d2bb706fca0656f2760839721bb7f6cb6f (patch) | |
| tree | d374cdca417e76f1bf101f139dba2db1d10ee8f7 /lib/CodeGen/CGCXX.cpp | |
| parent | c0c7bca4e5b8d12699dc93a0da49e9e4bb79671b (diff) | |
Notes
Diffstat (limited to 'lib/CodeGen/CGCXX.cpp')
| -rw-r--r-- | lib/CodeGen/CGCXX.cpp | 315 | 
1 files changed, 5 insertions, 310 deletions
| diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp index b88001c81e9fa..93a182f5cc471 100644 --- a/lib/CodeGen/CGCXX.cpp +++ b/lib/CodeGen/CGCXX.cpp @@ -297,311 +297,6 @@ void CodeGenModule::getMangledCXXDtorName(MangleBuffer &Name,    getMangleContext().mangleCXXDtor(D, Type, Name.getBuffer());  } -llvm::Constant * -CodeGenFunction::GenerateThunk(llvm::Function *Fn, GlobalDecl GD, -                               bool Extern,  -                               const ThunkAdjustment &ThisAdjustment) { -  return GenerateCovariantThunk(Fn, GD, Extern, -                                CovariantThunkAdjustment(ThisAdjustment, -                                                         ThunkAdjustment())); -} - -llvm::Value * -CodeGenFunction::DynamicTypeAdjust(llvm::Value *V,  -                                   const ThunkAdjustment &Adjustment) { -  const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(VMContext); - -  const llvm::Type *OrigTy = V->getType(); -  if (Adjustment.NonVirtual) { -    // Do the non-virtual adjustment -    V = Builder.CreateBitCast(V, Int8PtrTy); -    V = Builder.CreateConstInBoundsGEP1_64(V, Adjustment.NonVirtual); -    V = Builder.CreateBitCast(V, OrigTy); -  } -   -  if (!Adjustment.Virtual) -    return V; - -  assert(Adjustment.Virtual % (LLVMPointerWidth / 8) == 0 &&  -         "vtable entry unaligned"); - -  // Do the virtual this adjustment -  const llvm::Type *PtrDiffTy = ConvertType(getContext().getPointerDiffType()); -  const llvm::Type *PtrDiffPtrTy = PtrDiffTy->getPointerTo(); -   -  llvm::Value *ThisVal = Builder.CreateBitCast(V, Int8PtrTy); -  V = Builder.CreateBitCast(V, PtrDiffPtrTy->getPointerTo()); -  V = Builder.CreateLoad(V, "vtable"); -   -  llvm::Value *VTablePtr = V; -  uint64_t VirtualAdjustment = Adjustment.Virtual / (LLVMPointerWidth / 8); -  V = Builder.CreateConstInBoundsGEP1_64(VTablePtr, VirtualAdjustment); -  V = Builder.CreateLoad(V); -  V = Builder.CreateGEP(ThisVal, V); -   -  return Builder.CreateBitCast(V, OrigTy); -} - -llvm::Constant * -CodeGenFunction::GenerateCovariantThunk(llvm::Function *Fn, -                                   GlobalDecl GD, bool Extern, -                                   const CovariantThunkAdjustment &Adjustment) { -  const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl()); -  const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>(); -  QualType ResultType = FPT->getResultType(); - -  FunctionArgList Args; -  ImplicitParamDecl *ThisDecl = -    ImplicitParamDecl::Create(getContext(), 0, SourceLocation(), 0, -                              MD->getThisType(getContext())); -  Args.push_back(std::make_pair(ThisDecl, ThisDecl->getType())); -  for (FunctionDecl::param_const_iterator i = MD->param_begin(), -         e = MD->param_end(); -       i != e; ++i) { -    ParmVarDecl *D = *i; -    Args.push_back(std::make_pair(D, D->getType())); -  } -  IdentifierInfo *II -    = &CGM.getContext().Idents.get("__thunk_named_foo_"); -  FunctionDecl *FD = FunctionDecl::Create(getContext(), -                                          getContext().getTranslationUnitDecl(), -                                          SourceLocation(), II, ResultType, 0, -                                          Extern -                                            ? FunctionDecl::Extern -                                            : FunctionDecl::Static, -                                          false, true); -  StartFunction(FD, ResultType, Fn, Args, SourceLocation()); - -  // generate body -  const llvm::Type *Ty = -    CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD), -                                   FPT->isVariadic()); -  llvm::Value *Callee = CGM.GetAddrOfFunction(GD, Ty); - -  CallArgList CallArgs; - -  bool ShouldAdjustReturnPointer = true; -  QualType ArgType = MD->getThisType(getContext()); -  llvm::Value *Arg = Builder.CreateLoad(LocalDeclMap[ThisDecl], "this"); -  if (!Adjustment.ThisAdjustment.isEmpty()) { -    // Do the this adjustment. -    const llvm::Type *OrigTy = Callee->getType(); -    Arg = DynamicTypeAdjust(Arg, Adjustment.ThisAdjustment); -     -    if (!Adjustment.ReturnAdjustment.isEmpty()) { -      const CovariantThunkAdjustment &ReturnAdjustment =  -        CovariantThunkAdjustment(ThunkAdjustment(), -                                 Adjustment.ReturnAdjustment); -       -      Callee = CGM.BuildCovariantThunk(GD, Extern, ReturnAdjustment); -       -      Callee = Builder.CreateBitCast(Callee, OrigTy); -      ShouldAdjustReturnPointer = false; -    } -  }     - -  CallArgs.push_back(std::make_pair(RValue::get(Arg), ArgType)); - -  for (FunctionDecl::param_const_iterator i = MD->param_begin(), -         e = MD->param_end(); -       i != e; ++i) { -    ParmVarDecl *D = *i; -    QualType ArgType = D->getType(); - -    // llvm::Value *Arg = CGF.GetAddrOfLocalVar(Dst); -    Expr *Arg = new (getContext()) DeclRefExpr(D, ArgType.getNonReferenceType(), -                                               SourceLocation()); -    CallArgs.push_back(std::make_pair(EmitCallArg(Arg, ArgType), ArgType)); -  } - -  RValue RV = EmitCall(CGM.getTypes().getFunctionInfo(ResultType, CallArgs, -                                                      FPT->getCallConv(), -                                                      FPT->getNoReturnAttr()), -                       Callee, ReturnValueSlot(), CallArgs, MD); -  if (ShouldAdjustReturnPointer && !Adjustment.ReturnAdjustment.isEmpty()) { -    bool CanBeZero = !(ResultType->isReferenceType() -    // FIXME: attr nonnull can't be zero either -                       /* || ResultType->hasAttr<NonNullAttr>() */ ); -    // Do the return result adjustment. -    if (CanBeZero) { -      llvm::BasicBlock *NonZeroBlock = createBasicBlock(); -      llvm::BasicBlock *ZeroBlock = createBasicBlock(); -      llvm::BasicBlock *ContBlock = createBasicBlock(); - -      const llvm::Type *Ty = RV.getScalarVal()->getType(); -      llvm::Value *Zero = llvm::Constant::getNullValue(Ty); -      Builder.CreateCondBr(Builder.CreateICmpNE(RV.getScalarVal(), Zero), -                           NonZeroBlock, ZeroBlock); -      EmitBlock(NonZeroBlock); -      llvm::Value *NZ =  -        DynamicTypeAdjust(RV.getScalarVal(), Adjustment.ReturnAdjustment); -      EmitBranch(ContBlock); -      EmitBlock(ZeroBlock); -      llvm::Value *Z = RV.getScalarVal(); -      EmitBlock(ContBlock); -      llvm::PHINode *RVOrZero = Builder.CreatePHI(Ty); -      RVOrZero->reserveOperandSpace(2); -      RVOrZero->addIncoming(NZ, NonZeroBlock); -      RVOrZero->addIncoming(Z, ZeroBlock); -      RV = RValue::get(RVOrZero); -    } else -      RV = RValue::get(DynamicTypeAdjust(RV.getScalarVal(),  -                                         Adjustment.ReturnAdjustment)); -  } - -  if (!ResultType->isVoidType()) -    EmitReturnOfRValue(RV, ResultType); - -  FinishFunction(); -  return Fn; -} - -llvm::Constant * -CodeGenModule::GetAddrOfThunk(GlobalDecl GD, -                              const ThunkAdjustment &ThisAdjustment) { -  const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl()); - -  // Compute mangled name -  llvm::SmallString<256> OutName; -  if (const CXXDestructorDecl* DD = dyn_cast<CXXDestructorDecl>(MD)) -    getMangleContext().mangleCXXDtorThunk(DD, GD.getDtorType(), ThisAdjustment, -                                          OutName); -  else -    getMangleContext().mangleThunk(MD, ThisAdjustment, OutName); - -  // Get function for mangled name -  const llvm::Type *Ty = getTypes().GetFunctionTypeForVtable(MD); -  return GetOrCreateLLVMFunction(OutName, Ty, GlobalDecl()); -} - -llvm::Constant * -CodeGenModule::GetAddrOfCovariantThunk(GlobalDecl GD, -                                   const CovariantThunkAdjustment &Adjustment) { -  const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl()); - -  // Compute mangled name -  llvm::SmallString<256> Name; -  getMangleContext().mangleCovariantThunk(MD, Adjustment, Name); - -  // Get function for mangled name -  const llvm::Type *Ty = getTypes().GetFunctionTypeForVtable(MD); -  return GetOrCreateLLVMFunction(Name, Ty, GlobalDecl()); -} - -void CodeGenModule::BuildThunksForVirtual(GlobalDecl GD) { -  CGVtableInfo::AdjustmentVectorTy *AdjPtr = getVtableInfo().getAdjustments(GD); -  if (!AdjPtr) -    return; -  CGVtableInfo::AdjustmentVectorTy &Adj = *AdjPtr; -  const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl()); -  for (unsigned i = 0; i < Adj.size(); i++) { -    GlobalDecl OGD = Adj[i].first; -    const CXXMethodDecl *OMD = cast<CXXMethodDecl>(OGD.getDecl()); -    QualType nc_oret = OMD->getType()->getAs<FunctionType>()->getResultType(); -    CanQualType oret = getContext().getCanonicalType(nc_oret); -    QualType nc_ret = MD->getType()->getAs<FunctionType>()->getResultType(); -    CanQualType ret = getContext().getCanonicalType(nc_ret); -    ThunkAdjustment ReturnAdjustment; -    if (oret != ret) { -      QualType qD = nc_ret->getPointeeType(); -      QualType qB = nc_oret->getPointeeType(); -      CXXRecordDecl *D = cast<CXXRecordDecl>(qD->getAs<RecordType>()->getDecl()); -      CXXRecordDecl *B = cast<CXXRecordDecl>(qB->getAs<RecordType>()->getDecl()); -      ReturnAdjustment = ComputeThunkAdjustment(D, B); -    } -    ThunkAdjustment ThisAdjustment = Adj[i].second; -    bool Extern = !cast<CXXRecordDecl>(OMD->getDeclContext())->isInAnonymousNamespace(); -    if (!ReturnAdjustment.isEmpty() || !ThisAdjustment.isEmpty()) { -      CovariantThunkAdjustment CoAdj(ThisAdjustment, ReturnAdjustment); -      llvm::Constant *FnConst; -      if (!ReturnAdjustment.isEmpty()) -        FnConst = GetAddrOfCovariantThunk(GD, CoAdj); -      else -        FnConst = GetAddrOfThunk(GD, ThisAdjustment); -      if (!isa<llvm::Function>(FnConst)) { -        llvm::Constant *SubExpr = -            cast<llvm::ConstantExpr>(FnConst)->getOperand(0); -        llvm::Function *OldFn = cast<llvm::Function>(SubExpr); -        llvm::Constant *NewFnConst; -        if (!ReturnAdjustment.isEmpty()) -          NewFnConst = GetAddrOfCovariantThunk(GD, CoAdj); -        else -          NewFnConst = GetAddrOfThunk(GD, ThisAdjustment); -        llvm::Function *NewFn = cast<llvm::Function>(NewFnConst); -        NewFn->takeName(OldFn); -        llvm::Constant *NewPtrForOldDecl = -            llvm::ConstantExpr::getBitCast(NewFn, OldFn->getType()); -        OldFn->replaceAllUsesWith(NewPtrForOldDecl); -        OldFn->eraseFromParent(); -        FnConst = NewFn; -      } -      llvm::Function *Fn = cast<llvm::Function>(FnConst); -      if (Fn->isDeclaration()) { -        llvm::GlobalVariable::LinkageTypes linktype; -        linktype = llvm::GlobalValue::WeakAnyLinkage; -        if (!Extern) -          linktype = llvm::GlobalValue::InternalLinkage; -        Fn->setLinkage(linktype); -        if (!Features.Exceptions && !Features.ObjCNonFragileABI) -          Fn->addFnAttr(llvm::Attribute::NoUnwind); -        Fn->setAlignment(2); -        CodeGenFunction(*this).GenerateCovariantThunk(Fn, GD, Extern, CoAdj); -      } -    } -  } -} - -llvm::Constant * -CodeGenModule::BuildThunk(GlobalDecl GD, bool Extern, -                          const ThunkAdjustment &ThisAdjustment) { -  const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl()); -  llvm::SmallString<256> OutName; -  if (const CXXDestructorDecl *D = dyn_cast<CXXDestructorDecl>(MD)) { -    getMangleContext().mangleCXXDtorThunk(D, GD.getDtorType(), ThisAdjustment, -                                          OutName); -  } else  -    getMangleContext().mangleThunk(MD, ThisAdjustment, OutName); -   -  llvm::GlobalVariable::LinkageTypes linktype; -  linktype = llvm::GlobalValue::WeakAnyLinkage; -  if (!Extern) -    linktype = llvm::GlobalValue::InternalLinkage; -  llvm::Type *Ptr8Ty=llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext),0); -  const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>(); -  const llvm::FunctionType *FTy = -    getTypes().GetFunctionType(getTypes().getFunctionInfo(MD), -                               FPT->isVariadic()); - -  llvm::Function *Fn = llvm::Function::Create(FTy, linktype, OutName.str(), -                                              &getModule()); -  CodeGenFunction(*this).GenerateThunk(Fn, GD, Extern, ThisAdjustment); -  llvm::Constant *m = llvm::ConstantExpr::getBitCast(Fn, Ptr8Ty); -  return m; -} - -llvm::Constant * -CodeGenModule::BuildCovariantThunk(const GlobalDecl &GD, bool Extern, -                                   const CovariantThunkAdjustment &Adjustment) { -  const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl()); -  llvm::SmallString<256> OutName; -  getMangleContext().mangleCovariantThunk(MD, Adjustment, OutName); -  llvm::GlobalVariable::LinkageTypes linktype; -  linktype = llvm::GlobalValue::WeakAnyLinkage; -  if (!Extern) -    linktype = llvm::GlobalValue::InternalLinkage; -  llvm::Type *Ptr8Ty=llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext),0); -  const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>(); -  const llvm::FunctionType *FTy = -    getTypes().GetFunctionType(getTypes().getFunctionInfo(MD), -                               FPT->isVariadic()); - -  llvm::Function *Fn = llvm::Function::Create(FTy, linktype, OutName.str(), -                                              &getModule()); -  CodeGenFunction(*this).GenerateCovariantThunk(Fn, MD, Extern, Adjustment); -  llvm::Constant *m = llvm::ConstantExpr::getBitCast(Fn, Ptr8Ty); -  return m; -} -  static llvm::Value *BuildVirtualCall(CodeGenFunction &CGF, uint64_t VtableIndex,                                        llvm::Value *This, const llvm::Type *Ty) {    Ty = Ty->getPointerTo()->getPointerTo()->getPointerTo(); @@ -618,17 +313,17 @@ llvm::Value *  CodeGenFunction::BuildVirtualCall(const CXXMethodDecl *MD, llvm::Value *This,                                    const llvm::Type *Ty) {    MD = MD->getCanonicalDecl(); -  uint64_t VtableIndex = CGM.getVtableInfo().getMethodVtableIndex(MD); +  uint64_t VTableIndex = CGM.getVTables().getMethodVtableIndex(MD); -  return ::BuildVirtualCall(*this, VtableIndex, This, Ty); +  return ::BuildVirtualCall(*this, VTableIndex, This, Ty);  }  llvm::Value *  CodeGenFunction::BuildVirtualCall(const CXXDestructorDecl *DD, CXXDtorType Type,                                     llvm::Value *&This, const llvm::Type *Ty) {    DD = cast<CXXDestructorDecl>(DD->getCanonicalDecl()); -  uint64_t VtableIndex =  -    CGM.getVtableInfo().getMethodVtableIndex(GlobalDecl(DD, Type)); +  uint64_t VTableIndex =  +    CGM.getVTables().getMethodVtableIndex(GlobalDecl(DD, Type)); -  return ::BuildVirtualCall(*this, VtableIndex, This, Ty); +  return ::BuildVirtualCall(*this, VTableIndex, This, Ty);  } | 
