From 31bc3ad2759f7ae2e6a2728d03a08c20fcb0a164 Mon Sep 17 00:00:00 2001 From: Eli Friedman Date: Mon, 7 Dec 2009 23:56:34 +0000 Subject: A bunch more thunk fixes from misc testing. (Yes, I do intend to commit some tests for this.) llvm-svn: 90818 --- clang/lib/CodeGen/CGCXX.cpp | 46 +++++++++++++++++++++++++-------------------- 1 file changed, 26 insertions(+), 20 deletions(-) (limited to 'clang/lib/CodeGen/CGCXX.cpp') diff --git a/clang/lib/CodeGen/CGCXX.cpp b/clang/lib/CodeGen/CGCXX.cpp index 77bee48b58b..d82f9359716 100644 --- a/clang/lib/CodeGen/CGCXX.cpp +++ b/clang/lib/CodeGen/CGCXX.cpp @@ -1030,23 +1030,14 @@ CodeGenModule::GetAddrOfCovariantThunk(GlobalDecl GD, } void CodeGenModule::BuildThunksForVirtual(GlobalDecl GD) { - BuildThunksForVirtualRecursive(GD, GD); -} - -void -CodeGenModule::BuildThunksForVirtualRecursive(GlobalDecl GD, - GlobalDecl BaseOGD) { + CGVtableInfo::AdjustmentVectorTy *AdjPtr = getVtableInfo().getAdjustments(GD); + if (!AdjPtr) + return; + CGVtableInfo::AdjustmentVectorTy &Adj = *AdjPtr; const CXXMethodDecl *MD = cast(GD.getDecl()); - const CXXMethodDecl *BaseOMD = cast(BaseOGD.getDecl()); - for (CXXMethodDecl::method_iterator mi = BaseOMD->begin_overridden_methods(), - e = BaseOMD->end_overridden_methods(); - mi != e; ++mi) { - GlobalDecl OGD; - const CXXMethodDecl *OMD = *mi; - if (const CXXDestructorDecl *DD = dyn_cast(OMD)) - OGD = GlobalDecl(DD, GD.getDtorType()); - else - OGD = GlobalDecl(OMD); + for (unsigned i = 0; i < Adj.size(); i++) { + GlobalDecl OGD = Adj[i].first; + const CXXMethodDecl *OMD = cast(OGD.getDecl()); QualType nc_oret = OMD->getType()->getAs()->getResultType(); CanQualType oret = getContext().getCanonicalType(nc_oret); QualType nc_ret = MD->getType()->getAs()->getResultType(); @@ -1059,8 +1050,7 @@ CodeGenModule::BuildThunksForVirtualRecursive(GlobalDecl GD, CXXRecordDecl *B = cast(qB->getAs()->getDecl()); ReturnAdjustment = ComputeThunkAdjustment(D, B); } - ThunkAdjustment ThisAdjustment = - getVtableInfo().getThisAdjustment(GD, OGD); + ThunkAdjustment ThisAdjustment = Adj[i].second; bool Extern = !cast(OMD->getDeclContext())->isInAnonymousNamespace(); if (!ReturnAdjustment.isEmpty() || !ThisAdjustment.isEmpty()) { CovariantThunkAdjustment CoAdj(ThisAdjustment, ReturnAdjustment); @@ -1070,7 +1060,24 @@ CodeGenModule::BuildThunksForVirtualRecursive(GlobalDecl GD, else FnConst = GetAddrOfThunk(GD, ThisAdjustment); if (!isa(FnConst)) { - assert(0 && "Figure out how to handle incomplete-type cases!"); + llvm::Constant *SubExpr = + cast(FnConst)->getOperand(0); + llvm::Function *OldFn = cast(SubExpr); + std::string Name = OldFn->getNameStr(); + GlobalDeclMap.erase(UniqueMangledName(Name.data(), + Name.data() + Name.size() + 1)); + llvm::Constant *NewFnConst; + if (!ReturnAdjustment.isEmpty()) + NewFnConst = GetAddrOfCovariantThunk(GD, CoAdj); + else + NewFnConst = GetAddrOfThunk(GD, ThisAdjustment); + llvm::Function *NewFn = cast(NewFnConst); + NewFn->takeName(OldFn); + llvm::Constant *NewPtrForOldDecl = + llvm::ConstantExpr::getBitCast(NewFn, OldFn->getType()); + OldFn->replaceAllUsesWith(NewPtrForOldDecl); + OldFn->eraseFromParent(); + FnConst = NewFn; } llvm::Function *Fn = cast(FnConst); if (Fn->isDeclaration()) { @@ -1085,7 +1092,6 @@ CodeGenModule::BuildThunksForVirtualRecursive(GlobalDecl GD, CodeGenFunction(*this).GenerateCovariantThunk(Fn, GD, Extern, CoAdj); } } - BuildThunksForVirtualRecursive(GD, OGD); } } -- cgit v1.2.3