diff options
author | Mike Stump <mrs@apple.com> | 2009-10-13 10:55:21 +0000 |
---|---|---|
committer | Mike Stump <mrs@apple.com> | 2009-10-13 10:55:21 +0000 |
commit | d9878a181f09ffc76b61d430aa3a001102fda5af (patch) | |
tree | 2a03d30287d332fdf1f283c7d740b6bba6298772 /lib/CodeGen/CGVtable.cpp | |
parent | 3c0ef8cc0dc246bd3083e8cdd63005e8873d36d2 (diff) |
Refine handling for return value conversions with respect to virtual
offsets for covariant thunks.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@83965 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGVtable.cpp')
-rw-r--r-- | lib/CodeGen/CGVtable.cpp | 34 |
1 files changed, 22 insertions, 12 deletions
diff --git a/lib/CodeGen/CGVtable.cpp b/lib/CodeGen/CGVtable.cpp index c3f6074982..2613300459 100644 --- a/lib/CodeGen/CGVtable.cpp +++ b/lib/CodeGen/CGVtable.cpp @@ -47,7 +47,8 @@ private: typedef llvm::DenseMap<const CXXMethodDecl *, CallOffset> Thunks_t; Thunks_t Thunks; typedef llvm::DenseMap<const CXXMethodDecl *, - std::pair<CallOffset, CallOffset> > CovariantThunks_t; + std::pair<std::pair<CallOffset, CallOffset>, + CanQualType> > CovariantThunks_t; CovariantThunks_t CovariantThunks; std::vector<Index_t> VCalls; typedef CXXRecordDecl::method_iterator method_iter; @@ -81,7 +82,8 @@ public: } void GenerateVBaseOffsets(std::vector<llvm::Constant *> &offsets, - const CXXRecordDecl *RD, uint64_t Offset) { + const CXXRecordDecl *RD, uint64_t Offset, + bool updateVBIndex) { for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(), e = RD->bases_end(); i != e; ++i) { const CXXRecordDecl *Base = @@ -91,11 +93,12 @@ public: int64_t BaseOffset = -(Offset/8) + BLayout.getVBaseClassOffset(Base)/8; llvm::Constant *m = wrap(BaseOffset); m = wrap((0?700:0) + BaseOffset); - VBIndex[Base] = -(offsets.size()*LLVMPointerWidth/8) - - 3*LLVMPointerWidth/8; + if (updateVBIndex) + VBIndex[Base] = -(offsets.size()*LLVMPointerWidth/8) + - 3*LLVMPointerWidth/8; offsets.push_back(m); } - GenerateVBaseOffsets(offsets, Base, Offset); + GenerateVBaseOffsets(offsets, Base, Offset, updateVBIndex); } } @@ -153,7 +156,12 @@ public: CallOffset ReturnOffset = std::make_pair(0, 0); if (oret != ret) { // FIXME: calculate offsets for covariance - ReturnOffset = std::make_pair(42,getVbaseOffset(oret, ret)); + Index_t nv = 0; + if (CovariantThunks.count(OMD)) { + oret = CovariantThunks[OMD].second; + CovariantThunks.erase(OMD); + } + ReturnOffset = std::make_pair(nv, getVbaseOffset(oret, ret)); } Index[MD] = i; submethods[i] = m; @@ -174,7 +182,9 @@ public: // FIXME: calculate non-virtual offset ThisOffset = std::make_pair(0, -((idx+extra+2)*LLVMPointerWidth/8)); if (ReturnOffset.first || ReturnOffset.second) - CovariantThunks[MD] = std::make_pair(ThisOffset, ReturnOffset); + CovariantThunks[MD] = std::make_pair(std::make_pair(ThisOffset, + ReturnOffset), + oret); else Thunks[MD] = ThisOffset; return true; @@ -208,10 +218,10 @@ public: i != e; ++i) { const CXXMethodDecl *MD = i->first; Index_t idx = Index[MD]; - Index_t nv_t = i->second.first.first; - Index_t v_t = i->second.first.second; - Index_t nv_r = i->second.second.first; - Index_t v_r = i->second.second.second; + Index_t nv_t = i->second.first.first.first; + Index_t v_t = i->second.first.first.second; + Index_t nv_r = i->second.first.second.first; + Index_t v_r = i->second.first.second.second; submethods[idx] = CGM.BuildCovariantThunk(MD, Extern, nv_t, v_t, nv_r, v_r); } @@ -385,7 +395,7 @@ public: std::vector<llvm::Constant *> offsets; extra = 0; - GenerateVBaseOffsets(offsets, RD, Offset); + GenerateVBaseOffsets(offsets, RD, Offset, !ForVirtualBase); if (ForVirtualBase) extra = offsets.size(); |