static uint64_t ComputeNonVirtualBaseClassOffset(ASTContext &Context, CXXBasePaths &Paths, unsigned Start) { uint64_t Offset = 0; const CXXBasePath &Path = Paths.front(); for (unsigned i = Start, e = Path.size(); i != e; ++i) { const CXXBasePathElement& Element = Path[i]; // Get the layout. const ASTRecordLayout &Layout = Context.getASTRecordLayout(Element.Class); const CXXBaseSpecifier *BS = Element.Base; // FIXME: enable test3 from virt.cc to not abort. if (BS->isVirtual()) return 0; assert(!BS->isVirtual() && "Should not see virtual bases here!"); const CXXRecordDecl *Base = cast<CXXRecordDecl>(BS->getType()->getAs<RecordType>()->getDecl()); // Add the offset. Offset += Layout.getBaseClassOffset(Base) / 8; } return Offset; }
VTTBuilder::VTTBuilder(ASTContext &Ctx, const CXXRecordDecl *MostDerivedClass, bool GenerateDefinition) : Ctx(Ctx), MostDerivedClass(MostDerivedClass), MostDerivedClassLayout(Ctx.getASTRecordLayout(MostDerivedClass)), GenerateDefinition(GenerateDefinition) { // Lay out this VTT. LayoutVTT(BaseSubobject(MostDerivedClass, CharUnits::Zero()), /*BaseIsVirtual=*/false); }
static void AddIndirectPrimaryBases(const CXXRecordDecl *RD, ASTContext &Context, CXXIndirectPrimaryBaseSet& Bases) { // If the record has a virtual primary base class, add it to our set. const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); if (Layout.isPrimaryBaseVirtual()) Bases.insert(Layout.getPrimaryBase()); for (const auto &I : RD->bases()) { assert(!I.getType()->isDependentType() && "Cannot get indirect primary bases for class with dependent bases."); const CXXRecordDecl *BaseDecl = cast<CXXRecordDecl>(I.getType()->castAs<RecordType>()->getDecl()); // Only bases with virtual bases participate in computing the // indirect primary virtual base classes. if (BaseDecl->getNumVBases()) AddIndirectPrimaryBases(BaseDecl, Context, Bases); } }