diff options
author | Eli Friedman <eli.friedman@gmail.com> | 2009-12-07 23:56:34 +0000 |
---|---|---|
committer | Eli Friedman <eli.friedman@gmail.com> | 2009-12-07 23:56:34 +0000 |
commit | b455f0e74be0144ab9738ef574d07bd661959525 (patch) | |
tree | fe85af62b94205320c712f6347a48604ecee9075 /lib/CodeGen/CGCXX.cpp | |
parent | cce3d4f9812182ed4e551b7cf0fc86576be8d9c5 (diff) |
A bunch more thunk fixes from misc testing.
(Yes, I do intend to commit some tests for this.)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@90818 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGCXX.cpp')
-rw-r--r-- | lib/CodeGen/CGCXX.cpp | 46 |
1 files changed, 26 insertions, 20 deletions
diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp index 77bee48b58..d82f935971 100644 --- a/lib/CodeGen/CGCXX.cpp +++ b/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<CXXMethodDecl>(GD.getDecl()); - const CXXMethodDecl *BaseOMD = cast<CXXMethodDecl>(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<CXXDestructorDecl>(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<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(); @@ -1059,8 +1050,7 @@ CodeGenModule::BuildThunksForVirtualRecursive(GlobalDecl GD, CXXRecordDecl *B = cast<CXXRecordDecl>(qB->getAs<RecordType>()->getDecl()); ReturnAdjustment = ComputeThunkAdjustment(D, B); } - ThunkAdjustment ThisAdjustment = - getVtableInfo().getThisAdjustment(GD, OGD); + ThunkAdjustment ThisAdjustment = Adj[i].second; bool Extern = !cast<CXXRecordDecl>(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<llvm::Function>(FnConst)) { - assert(0 && "Figure out how to handle incomplete-type cases!"); + llvm::Constant *SubExpr = + cast<llvm::ConstantExpr>(FnConst)->getOperand(0); + llvm::Function *OldFn = cast<llvm::Function>(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<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()) { @@ -1085,7 +1092,6 @@ CodeGenModule::BuildThunksForVirtualRecursive(GlobalDecl GD, CodeGenFunction(*this).GenerateCovariantThunk(Fn, GD, Extern, CoAdj); } } - BuildThunksForVirtualRecursive(GD, OGD); } } |