diff options
author | Reid Kleckner <reid@kleckner.net> | 2013-06-04 21:32:29 +0000 |
---|---|---|
committer | Reid Kleckner <reid@kleckner.net> | 2013-06-04 21:32:29 +0000 |
commit | 3758f9d0f14d7d6faa010bb4c4ac0b3e57a011dc (patch) | |
tree | 0cc3f48afa9f112f1c27e1ba37ab8bf903a984c7 /clang/lib/CodeGen/MicrosoftCXXABI.cpp | |
parent | e86cef633bd1506f10223d9e1c6393b5be888772 (diff) | |
download | bcm5719-llvm-3758f9d0f14d7d6faa010bb4c4ac0b3e57a011dc.tar.gz bcm5719-llvm-3758f9d0f14d7d6faa010bb4c4ac0b3e57a011dc.zip |
[ms-cxxabi] Factor out some loops into helpers for readability
No functionality change, covered by the existing virtual base adjustment
tests.
llvm-svn: 183251
Diffstat (limited to 'clang/lib/CodeGen/MicrosoftCXXABI.cpp')
-rw-r--r-- | clang/lib/CodeGen/MicrosoftCXXABI.cpp | 62 |
1 files changed, 33 insertions, 29 deletions
diff --git a/clang/lib/CodeGen/MicrosoftCXXABI.cpp b/clang/lib/CodeGen/MicrosoftCXXABI.cpp index c6614f28fff..7a8a0a6eea6 100644 --- a/clang/lib/CodeGen/MicrosoftCXXABI.cpp +++ b/clang/lib/CodeGen/MicrosoftCXXABI.cpp @@ -233,6 +233,18 @@ llvm::Value *MicrosoftCXXABI::adjustToCompleteObject(CodeGenFunction &CGF, return ptr; } +/// \brief Finds the first non-virtual base of RD that has virtual bases. If RD +/// doesn't have a vbptr, it will reuse the vbptr of the returned class. +static const CXXRecordDecl *FindFirstNVBaseWithVBases(const CXXRecordDecl *RD) { + for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), + E = RD->bases_end(); I != E; ++I) { + const CXXRecordDecl *Base = I->getType()->getAsCXXRecordDecl(); + if (!I->isVirtual() && Base->getNumVBases() > 0) + return Base; + } + llvm_unreachable("RD must have an nv base with vbases"); +} + CharUnits MicrosoftCXXABI::GetVBPtrOffsetFromBases(const CXXRecordDecl *RD) { assert(RD->getNumVBases()); CharUnits Total = CharUnits::Zero(); @@ -244,24 +256,30 @@ CharUnits MicrosoftCXXABI::GetVBPtrOffsetFromBases(const CXXRecordDecl *RD) { Total += VBPtrOffset; break; } - - // RD is reusing the vbptr of a non-virtual base. Find it and continue. - const CXXRecordDecl *FirstNVBaseWithVBases = 0; - for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), - E = RD->bases_end(); I != E; ++I) { - const CXXRecordDecl *Base = I->getType()->getAsCXXRecordDecl(); - if (!I->isVirtual() && Base->getNumVBases() > 0) { - FirstNVBaseWithVBases = Base; - break; - } - } - assert(FirstNVBaseWithVBases); - Total += RDLayout.getBaseClassOffset(FirstNVBaseWithVBases); - RD = FirstNVBaseWithVBases; + RD = FindFirstNVBaseWithVBases(RD); + Total += RDLayout.getBaseClassOffset(RD); } return Total; } +/// \brief Computes the index of BaseClassDecl in the vbtable of ClassDecl. +/// BaseClassDecl must be a morally virtual base of ClassDecl. The vbtable is +/// an array of i32 offsets. The first entry is a self entry, and the rest are +/// offsets from the vbptr to virtual bases. The bases are ordered the same way +/// our vbases are ordered: as they appear in a left-to-right depth-first search +/// of the hierarchy. +static unsigned GetVBTableIndex(const CXXRecordDecl *ClassDecl, + const CXXRecordDecl *BaseClassDecl) { + unsigned VBTableIndex = 1; // Start with one to skip the self entry. + for (CXXRecordDecl::base_class_const_iterator I = ClassDecl->vbases_begin(), + E = ClassDecl->vbases_end(); I != E; ++I) { + if (I->getType()->getAsCXXRecordDecl() == BaseClassDecl) + return VBTableIndex; + VBTableIndex++; + } + llvm_unreachable("BaseClassDecl must be a vbase of ClassDecl"); +} + llvm::Value * MicrosoftCXXABI::GetVirtualBaseClassOffset(CodeGenFunction &CGF, llvm::Value *This, @@ -269,22 +287,8 @@ MicrosoftCXXABI::GetVirtualBaseClassOffset(CodeGenFunction &CGF, const CXXRecordDecl *BaseClassDecl) { int64_t VBPtrChars = GetVBPtrOffsetFromBases(ClassDecl).getQuantity(); llvm::Value *VBPtrOffset = llvm::ConstantInt::get(CGM.PtrDiffTy, VBPtrChars); - - // The vbtable is an array of i32 offsets. The first entry is a self entry, - // and the rest are offsets from the vbptr to virtual bases. The bases are - // ordered the same way our vbases are ordered: as they appear in a - // left-to-right depth-first search of the hierarchy. - unsigned VBTableIndex = 1; // Start with one to skip the self entry. - for (CXXRecordDecl::base_class_const_iterator I = ClassDecl->vbases_begin(), - E = ClassDecl->vbases_end(); I != E; ++I) { - if (I->getType()->getAsCXXRecordDecl() == BaseClassDecl) - break; - VBTableIndex++; - } - assert(VBTableIndex != 1 + ClassDecl->getNumVBases() && - "BaseClassDecl must be a vbase of ClassDecl"); CharUnits IntSize = getContext().getTypeSizeInChars(getContext().IntTy); - CharUnits VBTableChars = IntSize * VBTableIndex; + CharUnits VBTableChars = IntSize * GetVBTableIndex(ClassDecl, BaseClassDecl); llvm::Value *VBTableOffset = llvm::ConstantInt::get(CGM.IntTy, VBTableChars.getQuantity()); |