void VBTableInfo::EmitVBTableDefinition( CodeGenModule &CGM, const CXXRecordDecl *RD, llvm::GlobalVariable::LinkageTypes Linkage) const { assert(RD->getNumVBases() && ReusingBase->getNumVBases() && "should only emit vbtables for classes with vbtables"); const ASTRecordLayout &BaseLayout = CGM.getContext().getASTRecordLayout(VBPtrSubobject.getBase()); const ASTRecordLayout &DerivedLayout = CGM.getContext().getASTRecordLayout(RD); SmallVector<llvm::Constant *, 4> Offsets; // The offset from ReusingBase's vbptr to itself always leads. CharUnits VBPtrOffset = BaseLayout.getVBPtrOffset(); Offsets.push_back( llvm::ConstantInt::get(CGM.IntTy, -VBPtrOffset.getQuantity())); // These are laid out in the same order as in Itanium, which is the same as // the order of the vbase iterator. for (CXXRecordDecl::base_class_const_iterator I = ReusingBase->vbases_begin(), E = ReusingBase->vbases_end(); I != E; ++I) { const CXXRecordDecl *VBase = I->getType()->getAsCXXRecordDecl(); CharUnits Offset = DerivedLayout.getVBaseClassOffset(VBase); assert(!Offset.isNegative()); // Make it relative to the subobject vbptr. Offset -= VBPtrSubobject.getBaseOffset() + VBPtrOffset; Offsets.push_back(llvm::ConstantInt::get(CGM.IntTy, Offset.getQuantity())); } assert(Offsets.size() == cast<llvm::ArrayType>(cast<llvm::PointerType>(GV->getType()) ->getElementType())->getNumElements()); llvm::ArrayType *VBTableType = llvm::ArrayType::get(CGM.IntTy, Offsets.size()); llvm::Constant *Init = llvm::ConstantArray::get(VBTableType, Offsets); GV->setInitializer(Init); // Set the correct linkage. GV->setLinkage(Linkage); // Set the right visibility. CGM.setTypeVisibility(GV, RD, CodeGenModule::TVK_ForVTable); }