diff options
Diffstat (limited to 'clang/lib/AST/VTableBuilder.cpp')
-rw-r--r-- | clang/lib/AST/VTableBuilder.cpp | 566 |
1 files changed, 283 insertions, 283 deletions
diff --git a/clang/lib/AST/VTableBuilder.cpp b/clang/lib/AST/VTableBuilder.cpp index 0a3da024f14..dfc5774ab49 100644 --- a/clang/lib/AST/VTableBuilder.cpp +++ b/clang/lib/AST/VTableBuilder.cpp @@ -35,14 +35,14 @@ namespace { struct BaseOffset { /// DerivedClass - The derived class. const CXXRecordDecl *DerivedClass; - + /// VirtualBase - If the path from the derived class to the base class /// involves virtual base classes, this holds the declaration of the last /// virtual base in this path (i.e. closest to the base class). const CXXRecordDecl *VirtualBase; /// NonVirtualOffset - The offset from the derived class to the base class. - /// (Or the offset from the virtual base class to the base class, if the + /// (Or the offset from the virtual base class to the base class, if the /// path from the derived class to the base class involves a virtual base /// class. CharUnits NonVirtualOffset; @@ -51,7 +51,7 @@ struct BaseOffset { NonVirtualOffset(CharUnits::Zero()) { } BaseOffset(const CXXRecordDecl *DerivedClass, const CXXRecordDecl *VirtualBase, CharUnits NonVirtualOffset) - : DerivedClass(DerivedClass), VirtualBase(VirtualBase), + : DerivedClass(DerivedClass), VirtualBase(VirtualBase), NonVirtualOffset(NonVirtualOffset) { } bool isEmpty() const { return NonVirtualOffset.isZero() && !VirtualBase; } @@ -81,19 +81,19 @@ private: /// MostDerivedClass - The most derived class for which the final overriders /// are stored. const CXXRecordDecl *MostDerivedClass; - - /// MostDerivedClassOffset - If we're building final overriders for a + + /// MostDerivedClassOffset - If we're building final overriders for a /// construction vtable, this holds the offset from the layout class to the /// most derived class. const CharUnits MostDerivedClassOffset; - /// LayoutClass - The class we're using for layout information. Will be + /// LayoutClass - The class we're using for layout information. Will be /// different than the most derived class if the final overriders are for a - /// construction vtable. - const CXXRecordDecl *LayoutClass; + /// construction vtable. + const CXXRecordDecl *LayoutClass; ASTContext &Context; - + /// MostDerivedClassLayout - the AST record layout of the most derived class. const ASTRecordLayout &MostDerivedClassLayout; @@ -103,19 +103,19 @@ private: typedef llvm::DenseMap<MethodBaseOffsetPairTy, OverriderInfo> OverridersMapTy; - - /// OverridersMap - The final overriders for all virtual member functions of + + /// OverridersMap - The final overriders for all virtual member functions of /// all the base subobjects of the most derived class. OverridersMapTy OverridersMap; - + /// SubobjectsToOffsetsMapTy - A mapping from a base subobject (represented /// as a record decl and a subobject number) and its offsets in the most /// derived class as well as the layout class. - typedef llvm::DenseMap<std::pair<const CXXRecordDecl *, unsigned>, + typedef llvm::DenseMap<std::pair<const CXXRecordDecl *, unsigned>, CharUnits> SubobjectOffsetMapTy; typedef llvm::DenseMap<const CXXRecordDecl *, unsigned> SubobjectCountMapTy; - + /// ComputeBaseOffsets - Compute the offsets for all base subobjects of the /// given base. void ComputeBaseOffsets(BaseSubobject Base, bool IsVirtual, @@ -125,40 +125,40 @@ private: SubobjectCountMapTy &SubobjectCounts); typedef llvm::SmallPtrSet<const CXXRecordDecl *, 4> VisitedVirtualBasesSetTy; - + /// dump - dump the final overriders for a base subobject, and all its direct /// and indirect base subobjects. void dump(raw_ostream &Out, BaseSubobject Base, VisitedVirtualBasesSetTy& VisitedVirtualBases); - + public: FinalOverriders(const CXXRecordDecl *MostDerivedClass, CharUnits MostDerivedClassOffset, const CXXRecordDecl *LayoutClass); /// getOverrider - Get the final overrider for the given method declaration in - /// the subobject with the given base offset. - OverriderInfo getOverrider(const CXXMethodDecl *MD, + /// the subobject with the given base offset. + OverriderInfo getOverrider(const CXXMethodDecl *MD, CharUnits BaseOffset) const { - assert(OverridersMap.count(std::make_pair(MD, BaseOffset)) && + assert(OverridersMap.count(std::make_pair(MD, BaseOffset)) && "Did not find overrider!"); - + return OverridersMap.lookup(std::make_pair(MD, BaseOffset)); } - + /// dump - dump the final overriders. void dump() { VisitedVirtualBasesSetTy VisitedVirtualBases; - dump(llvm::errs(), BaseSubobject(MostDerivedClass, CharUnits::Zero()), + dump(llvm::errs(), BaseSubobject(MostDerivedClass, CharUnits::Zero()), VisitedVirtualBases); } - + }; FinalOverriders::FinalOverriders(const CXXRecordDecl *MostDerivedClass, CharUnits MostDerivedClassOffset, const CXXRecordDecl *LayoutClass) - : MostDerivedClass(MostDerivedClass), + : MostDerivedClass(MostDerivedClass), MostDerivedClassOffset(MostDerivedClassOffset), LayoutClass(LayoutClass), Context(MostDerivedClass->getASTContext()), MostDerivedClassLayout(Context.getASTRecordLayout(MostDerivedClass)) { @@ -167,10 +167,10 @@ FinalOverriders::FinalOverriders(const CXXRecordDecl *MostDerivedClass, SubobjectOffsetMapTy SubobjectOffsets; SubobjectOffsetMapTy SubobjectLayoutClassOffsets; SubobjectCountMapTy SubobjectCounts; - ComputeBaseOffsets(BaseSubobject(MostDerivedClass, CharUnits::Zero()), + ComputeBaseOffsets(BaseSubobject(MostDerivedClass, CharUnits::Zero()), /*IsVirtual=*/false, - MostDerivedClassOffset, - SubobjectOffsets, SubobjectLayoutClassOffsets, + MostDerivedClassOffset, + SubobjectOffsets, SubobjectLayoutClassOffsets, SubobjectCounts); // Get the final overriders. @@ -183,10 +183,10 @@ FinalOverriders::FinalOverriders(const CXXRecordDecl *MostDerivedClass, for (const auto &M : Methods) { unsigned SubobjectNumber = M.first; - assert(SubobjectOffsets.count(std::make_pair(MD->getParent(), + assert(SubobjectOffsets.count(std::make_pair(MD->getParent(), SubobjectNumber)) && "Did not find subobject offset!"); - + CharUnits BaseOffset = SubobjectOffsets[std::make_pair(MD->getParent(), SubobjectNumber)]; @@ -198,12 +198,12 @@ FinalOverriders::FinalOverriders(const CXXRecordDecl *MostDerivedClass, std::make_pair(OverriderRD, Method.Subobject)) && "Did not find subobject offset!"); CharUnits OverriderOffset = - SubobjectLayoutClassOffsets[std::make_pair(OverriderRD, + SubobjectLayoutClassOffsets[std::make_pair(OverriderRD, Method.Subobject)]; OverriderInfo& Overrider = OverridersMap[std::make_pair(MD, BaseOffset)]; assert(!Overrider.Method && "Overrider should not exist yet!"); - + Overrider.Offset = OverriderOffset; Overrider.Method = Method.Method; Overrider.VirtualBase = Method.InVirtualSubobject; @@ -235,11 +235,11 @@ static BaseOffset ComputeBaseOffset(const ASTContext &Context, break; } } - + // Now compute the non-virtual offset. for (unsigned I = NonVirtualStart, E = Path.size(); I != E; ++I) { const CXXBasePathElement &Element = Path[I]; - + // Check the base class offset. const ASTRecordLayout &Layout = Context.getASTRecordLayout(Element.Class); @@ -247,12 +247,12 @@ static BaseOffset ComputeBaseOffset(const ASTContext &Context, NonVirtualOffset += Layout.getBaseClassOffset(Base); } - + // FIXME: This should probably use CharUnits or something. Maybe we should - // even change the base offsets in ASTRecordLayout to be specified in + // even change the base offsets in ASTRecordLayout to be specified in // CharUnits. return BaseOffset(DerivedRD, VirtualBase, NonVirtualOffset); - + } static BaseOffset ComputeBaseOffset(const ASTContext &Context, @@ -268,67 +268,67 @@ static BaseOffset ComputeBaseOffset(const ASTContext &Context, } static BaseOffset -ComputeReturnAdjustmentBaseOffset(ASTContext &Context, +ComputeReturnAdjustmentBaseOffset(ASTContext &Context, const CXXMethodDecl *DerivedMD, const CXXMethodDecl *BaseMD) { const FunctionType *BaseFT = BaseMD->getType()->getAs<FunctionType>(); const FunctionType *DerivedFT = DerivedMD->getType()->getAs<FunctionType>(); - + // Canonicalize the return types. CanQualType CanDerivedReturnType = Context.getCanonicalType(DerivedFT->getReturnType()); CanQualType CanBaseReturnType = Context.getCanonicalType(BaseFT->getReturnType()); - assert(CanDerivedReturnType->getTypeClass() == - CanBaseReturnType->getTypeClass() && + assert(CanDerivedReturnType->getTypeClass() == + CanBaseReturnType->getTypeClass() && "Types must have same type class!"); - + if (CanDerivedReturnType == CanBaseReturnType) { // No adjustment needed. return BaseOffset(); } - + if (isa<ReferenceType>(CanDerivedReturnType)) { - CanDerivedReturnType = + CanDerivedReturnType = CanDerivedReturnType->getAs<ReferenceType>()->getPointeeType(); - CanBaseReturnType = + CanBaseReturnType = CanBaseReturnType->getAs<ReferenceType>()->getPointeeType(); } else if (isa<PointerType>(CanDerivedReturnType)) { - CanDerivedReturnType = + CanDerivedReturnType = CanDerivedReturnType->getAs<PointerType>()->getPointeeType(); - CanBaseReturnType = + CanBaseReturnType = CanBaseReturnType->getAs<PointerType>()->getPointeeType(); } else { llvm_unreachable("Unexpected return type!"); } - + // We need to compare unqualified types here; consider // const T *Base::foo(); // T *Derived::foo(); - if (CanDerivedReturnType.getUnqualifiedType() == + if (CanDerivedReturnType.getUnqualifiedType() == CanBaseReturnType.getUnqualifiedType()) { // No adjustment needed. return BaseOffset(); } - - const CXXRecordDecl *DerivedRD = + + const CXXRecordDecl *DerivedRD = cast<CXXRecordDecl>(cast<RecordType>(CanDerivedReturnType)->getDecl()); - - const CXXRecordDecl *BaseRD = + + const CXXRecordDecl *BaseRD = cast<CXXRecordDecl>(cast<RecordType>(CanBaseReturnType)->getDecl()); return ComputeBaseOffset(Context, BaseRD, DerivedRD); } -void +void FinalOverriders::ComputeBaseOffsets(BaseSubobject Base, bool IsVirtual, CharUnits OffsetInLayoutClass, SubobjectOffsetMapTy &SubobjectOffsets, SubobjectOffsetMapTy &SubobjectLayoutClassOffsets, SubobjectCountMapTy &SubobjectCounts) { const CXXRecordDecl *RD = Base.getBase(); - + unsigned SubobjectNumber = 0; if (!IsVirtual) SubobjectNumber = ++SubobjectCounts[RD]; @@ -336,13 +336,13 @@ FinalOverriders::ComputeBaseOffsets(BaseSubobject Base, bool IsVirtual, // Set up the subobject to offset mapping. assert(!SubobjectOffsets.count(std::make_pair(RD, SubobjectNumber)) && "Subobject offset already exists!"); - assert(!SubobjectLayoutClassOffsets.count(std::make_pair(RD, SubobjectNumber)) + assert(!SubobjectLayoutClassOffsets.count(std::make_pair(RD, SubobjectNumber)) && "Subobject offset already exists!"); SubobjectOffsets[std::make_pair(RD, SubobjectNumber)] = Base.getBaseOffset(); SubobjectLayoutClassOffsets[std::make_pair(RD, SubobjectNumber)] = OffsetInLayoutClass; - + // Traverse our bases. for (const auto &B : RD->bases()) { const CXXRecordDecl *BaseDecl = B.getType()->getAsCXXRecordDecl(); @@ -358,19 +358,19 @@ FinalOverriders::ComputeBaseOffsets(BaseSubobject Base, bool IsVirtual, Context.getASTRecordLayout(LayoutClass); BaseOffset = MostDerivedClassLayout.getVBaseClassOffset(BaseDecl); - BaseOffsetInLayoutClass = + BaseOffsetInLayoutClass = LayoutClassLayout.getVBaseClassOffset(BaseDecl); } else { const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); CharUnits Offset = Layout.getBaseClassOffset(BaseDecl); - + BaseOffset = Base.getBaseOffset() + Offset; BaseOffsetInLayoutClass = OffsetInLayoutClass + Offset; } - ComputeBaseOffsets(BaseSubobject(BaseDecl, BaseOffset), - B.isVirtual(), BaseOffsetInLayoutClass, - SubobjectOffsets, SubobjectLayoutClassOffsets, + ComputeBaseOffsets(BaseSubobject(BaseDecl, BaseOffset), + B.isVirtual(), BaseOffsetInLayoutClass, + SubobjectOffsets, SubobjectLayoutClassOffsets, SubobjectCounts); } } @@ -382,7 +382,7 @@ void FinalOverriders::dump(raw_ostream &Out, BaseSubobject Base, for (const auto &B : RD->bases()) { const CXXRecordDecl *BaseDecl = B.getType()->getAsCXXRecordDecl(); - + // Ignore bases that don't have any virtual member functions. if (!BaseDecl->isPolymorphic()) continue; @@ -393,7 +393,7 @@ void FinalOverriders::dump(raw_ostream &Out, BaseSubobject Base, // We've visited this base before. continue; } - + BaseOffset = MostDerivedClassLayout.getVBaseClassOffset(BaseDecl); } else { BaseOffset = Layout.getBaseClassOffset(BaseDecl) + Base.getBaseOffset(); @@ -431,19 +431,19 @@ void FinalOverriders::dump(raw_ostream &Out, BaseSubobject Base, Offset.VirtualBase->printQualifiedName(Out); Out << " vbase, "; } - + Out << Offset.NonVirtualOffset.getQuantity() << " nv]"; } - + Out << "\n"; - } + } } /// VCallOffsetMap - Keeps track of vcall offsets when building a vtable. struct VCallOffsetMap { - + typedef std::pair<const CXXMethodDecl *, CharUnits> MethodAndOffsetPairTy; - + /// Offsets - Keeps track of methods and their offsets. // FIXME: This should be a real map and not a vector. SmallVector<MethodAndOffsetPairTy, 16> Offsets; @@ -458,11 +458,11 @@ public: /// add was successful, or false if there was already a member function with /// the same signature in the map. bool AddVCallOffset(const CXXMethodDecl *MD, CharUnits OffsetOffset); - + /// getVCallOffsetOffset - Returns the vcall offset offset (relative to the /// vtable address point) for the given virtual member function. CharUnits getVCallOffsetOffset(const CXXMethodDecl *MD); - + // empty - Return whether the offset map is empty or not. bool empty() const { return Offsets.empty(); } }; @@ -489,13 +489,13 @@ bool VCallOffsetMap::MethodsCanShareVCallOffset(const CXXMethodDecl *LHS, const CXXMethodDecl *RHS) { assert(LHS->isVirtual() && "LHS must be virtual!"); assert(RHS->isVirtual() && "LHS must be virtual!"); - + // A destructor can share a vcall offset with another destructor. if (isa<CXXDestructorDecl>(LHS)) return isa<CXXDestructorDecl>(RHS); // FIXME: We need to check more things here. - + // The methods must have the same name. DeclarationName LHSName = LHS->getDeclName(); DeclarationName RHSName = RHS->getDeclName(); @@ -506,14 +506,14 @@ bool VCallOffsetMap::MethodsCanShareVCallOffset(const CXXMethodDecl *LHS, return HasSameVirtualSignature(LHS, RHS); } -bool VCallOffsetMap::AddVCallOffset(const CXXMethodDecl *MD, +bool VCallOffsetMap::AddVCallOffset(const CXXMethodDecl *MD, CharUnits OffsetOffset) { // Check if we can reuse an offset. for (const auto &OffsetPair : Offsets) { if (MethodsCanShareVCallOffset(OffsetPair.first, MD)) return false; } - + // Add the offset. Offsets.push_back(MethodAndOffsetPairTy(MD, OffsetOffset)); return true; @@ -525,36 +525,36 @@ CharUnits VCallOffsetMap::getVCallOffsetOffset(const CXXMethodDecl *MD) { if (MethodsCanShareVCallOffset(OffsetPair.first, MD)) return OffsetPair.second; } - + llvm_unreachable("Should always find a vcall offset offset!"); } /// VCallAndVBaseOffsetBuilder - Class for building vcall and vbase offsets. class VCallAndVBaseOffsetBuilder { public: - typedef llvm::DenseMap<const CXXRecordDecl *, CharUnits> + typedef llvm::DenseMap<const CXXRecordDecl *, CharUnits> VBaseOffsetOffsetsMapTy; private: /// MostDerivedClass - The most derived class for which we're building vcall /// and vbase offsets. const CXXRecordDecl *MostDerivedClass; - - /// LayoutClass - The class we're using for layout information. Will be + + /// LayoutClass - The class we're using for layout information. Will be /// different than the most derived class if we're building a construction /// vtable. const CXXRecordDecl *LayoutClass; - + /// Context - The ASTContext which we will use for layout information. ASTContext &Context; /// Components - vcall and vbase offset components typedef SmallVector<VTableComponent, 64> VTableComponentVectorTy; VTableComponentVectorTy Components; - + /// VisitedVirtualBases - Visited virtual bases. llvm::SmallPtrSet<const CXXRecordDecl *, 4> VisitedVirtualBases; - + /// VCallOffsets - Keeps track of vcall offsets. VCallOffsetMap VCallOffsets; @@ -562,7 +562,7 @@ private: /// VBaseOffsetOffsets - Contains the offsets of the virtual base offsets, /// relative to the address point. VBaseOffsetOffsetsMapTy VBaseOffsetOffsets; - + /// FinalOverriders - The final overriders of the most derived class. /// (Can be null when we're not building a vtable of the most derived class). const FinalOverriders *Overriders; @@ -571,48 +571,48 @@ private: /// given base subobject. void AddVCallAndVBaseOffsets(BaseSubobject Base, bool BaseIsVirtual, CharUnits RealBaseOffset); - + /// AddVCallOffsets - Add vcall offsets for the given base subobject. void AddVCallOffsets(BaseSubobject Base, CharUnits VBaseOffset); - + /// AddVBaseOffsets - Add vbase offsets for the given class. - void AddVBaseOffsets(const CXXRecordDecl *Base, + void AddVBaseOffsets(const CXXRecordDecl *Base, CharUnits OffsetInLayoutClass); - + /// getCurrentOffsetOffset - Get the current vcall or vbase offset offset in /// chars, relative to the vtable address point. CharUnits getCurrentOffsetOffset() const; - + public: VCallAndVBaseOffsetBuilder(const CXXRecordDecl *MostDerivedClass, const CXXRecordDecl *LayoutClass, const FinalOverriders *Overriders, BaseSubobject Base, bool BaseIsVirtual, CharUnits OffsetInLayoutClass) - : MostDerivedClass(MostDerivedClass), LayoutClass(LayoutClass), + : MostDerivedClass(MostDerivedClass), LayoutClass(LayoutClass), Context(MostDerivedClass->getASTContext()), Overriders(Overriders) { - + // Add vcall and vbase offsets. AddVCallAndVBaseOffsets(Base, BaseIsVirtual, OffsetInLayoutClass); } - + /// Methods for iterating over the components. typedef VTableComponentVectorTy::const_reverse_iterator const_iterator; const_iterator components_begin() const { return Components.rbegin(); } const_iterator components_end() const { return Components.rend(); } - + const VCallOffsetMap &getVCallOffsets() const { return VCallOffsets; } const VBaseOffsetOffsetsMapTy &getVBaseOffsetOffsets() const { return VBaseOffsetOffsets; } }; - -void + +void VCallAndVBaseOffsetBuilder::AddVCallAndVBaseOffsets(BaseSubobject Base, bool BaseIsVirtual, CharUnits RealBaseOffset) { const ASTRecordLayout &Layout = Context.getASTRecordLayout(Base.getBase()); - + // Itanium C++ ABI 2.5.2: // ..in classes sharing a virtual table with a primary base class, the vcall // and vbase offsets added by the derived class all come before the vcall @@ -626,16 +626,16 @@ VCallAndVBaseOffsetBuilder::AddVCallAndVBaseOffsets(BaseSubobject Base, bool PrimaryBaseIsVirtual = Layout.isPrimaryBaseVirtual(); CharUnits PrimaryBaseOffset; - + // Get the base offset of the primary base. if (PrimaryBaseIsVirtual) { assert(Layout.getVBaseClassOffset(PrimaryBase).isZero() && "Primary vbase should have a zero offset!"); - + const ASTRecordLayout &MostDerivedClassLayout = Context.getASTRecordLayout(MostDerivedClass); - - PrimaryBaseOffset = + + PrimaryBaseOffset = MostDerivedClassLayout.getVBaseClassOffset(PrimaryBase); } else { assert(Layout.getBaseClassOffset(PrimaryBase).isZero() && @@ -657,19 +657,19 @@ VCallAndVBaseOffsetBuilder::AddVCallAndVBaseOffsets(BaseSubobject Base, } CharUnits VCallAndVBaseOffsetBuilder::getCurrentOffsetOffset() const { - // OffsetIndex is the index of this vcall or vbase offset, relative to the + // OffsetIndex is the index of this vcall or vbase offset, relative to the // vtable address point. (We subtract 3 to account for the information just // above the address point, the RTTI info, the offset to top, and the // vcall offset itself). int64_t OffsetIndex = -(int64_t)(3 + Components.size()); - - CharUnits PointerWidth = + + CharUnits PointerWidth = Context.toCharUnitsFromBits(Context.getTargetInfo().getPointerWidth(0)); CharUnits OffsetOffset = PointerWidth * OffsetIndex; return OffsetOffset; } -void VCallAndVBaseOffsetBuilder::AddVCallOffsets(BaseSubobject Base, +void VCallAndVBaseOffsetBuilder::AddVCallOffsets(BaseSubobject Base, CharUnits VBaseOffset) { const CXXRecordDecl *RD = Base.getBase(); const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); @@ -687,7 +687,7 @@ void VCallAndVBaseOffsetBuilder::AddVCallOffsets(BaseSubobject Base, AddVCallOffsets(BaseSubobject(PrimaryBase, Base.getBaseOffset()), VBaseOffset); } - + // Add the vcall offsets. for (const auto *MD : RD->methods()) { if (!MD->isVirtual()) @@ -695,7 +695,7 @@ void VCallAndVBaseOffsetBuilder::AddVCallOffsets(BaseSubobject Base, MD = MD->getCanonicalDecl(); CharUnits OffsetOffset = getCurrentOffsetOffset(); - + // Don't add a vcall offset if we already have one for this member function // signature. if (!VCallOffsets.AddVCallOffset(MD, OffsetOffset)) @@ -705,20 +705,20 @@ void VCallAndVBaseOffsetBuilder::AddVCallOffsets(BaseSubobject Base, if (Overriders) { // Get the final overrider. - FinalOverriders::OverriderInfo Overrider = + FinalOverriders::OverriderInfo Overrider = Overriders->getOverrider(MD, Base.getBaseOffset()); - - /// The vcall offset is the offset from the virtual base to the object + + /// The vcall offset is the offset from the virtual base to the object /// where the function was overridden. Offset = Overrider.Offset - VBaseOffset; } - + Components.push_back( VTableComponent::MakeVCallOffset(Offset)); } // And iterate over all non-virtual bases (ignoring the primary base). - for (const auto &B : RD->bases()) { + for (const auto &B : RD->bases()) { if (B.isVirtual()) continue; @@ -727,18 +727,18 @@ void VCallAndVBaseOffsetBuilder::AddVCallOffsets(BaseSubobject Base, continue; // Get the base offset of this base. - CharUnits BaseOffset = Base.getBaseOffset() + + CharUnits BaseOffset = Base.getBaseOffset() + Layout.getBaseClassOffset(BaseDecl); - - AddVCallOffsets(BaseSubobject(BaseDecl, BaseOffset), + + AddVCallOffsets(BaseSubobject(BaseDecl, BaseOffset), VBaseOffset); } } -void +void VCallAndVBaseOffsetBuilder::AddVBaseOffsets(const CXXRecordDecl *RD, CharUnits OffsetInLayoutClass) { - const ASTRecordLayout &LayoutClassLayout = + const ASTRecordLayout &LayoutClassLayout = Context.getASTRecordLayout(LayoutClass); // Add vbase offsets. @@ -747,7 +747,7 @@ VCallAndVBaseOffsetBuilder::AddVBaseOffsets(const CXXRecordDecl *RD, // Check if this is a virtual base that we haven't visited before. if (B.isVirtual() && VisitedVirtualBases.insert(BaseDecl).second) { - CharUnits Offset = + CharUnits Offset = LayoutClassLayout.getVBaseClassOffset(BaseDecl) - OffsetInLayoutClass; // Add the vbase offset offset. @@ -770,12 +770,12 @@ VCallAndVBaseOffsetBuilder::AddVBaseOffsets(const CXXRecordDecl *RD, /// ItaniumVTableBuilder - Class for building vtable layout information. class ItaniumVTableBuilder { public: - /// PrimaryBasesSetVectorTy - A set vector of direct and indirect + /// PrimaryBasesSetVectorTy - A set vector of direct and indirect /// primary bases. - typedef llvm::SmallSetVector<const CXXRecordDecl *, 8> + typedef llvm::SmallSetVector<const CXXRecordDecl *, 8> PrimaryBasesSetVectorTy; - - typedef llvm::DenseMap<const CXXRecordDecl *, CharUnits> + + typedef llvm::DenseMap<const CXXRecordDecl *, CharUnits> VBaseOffsetOffsetsMapTy; typedef VTableLayout::AddressPointsMapTy AddressPointsMapTy; @@ -785,7 +785,7 @@ public: private: /// VTables - Global vtable information. ItaniumVTableContext &VTables; - + /// MostDerivedClass - The most derived class for which we're building this /// vtable. const CXXRecordDecl *MostDerivedClass; @@ -793,19 +793,19 @@ private: /// MostDerivedClassOffset - If we're building a construction vtable, this /// holds the offset from the layout class to the most derived class. const CharUnits MostDerivedClassOffset; - - /// MostDerivedClassIsVirtual - Whether the most derived class is a virtual + + /// MostDerivedClassIsVirtual - Whether the most derived class is a virtual /// base. (This only makes sense when building a construction vtable). bool MostDerivedClassIsVirtual; - - /// LayoutClass - The class we're using for layout information. Will be + + /// LayoutClass - The class we're using for layout information. Will be /// different than the most derived class if we're building a construction /// vtable. const CXXRecordDecl *LayoutClass; - + /// Context - The ASTContext which we will use for layout information. ASTContext &Context; - + /// FinalOverriders - The final overriders of the most derived class. const FinalOverriders Overriders; @@ -828,29 +828,29 @@ private: struct MethodInfo { /// BaseOffset - The base offset of this method. const CharUnits BaseOffset; - + /// BaseOffsetInLayoutClass - The base offset in the layout class of this /// method. const CharUnits BaseOffsetInLayoutClass; - + /// VTableIndex - The index in the vtable that this method has. /// (For destructors, this is the index of the complete destructor). const uint64_t VTableIndex; - - MethodInfo(CharUnits BaseOffset, CharUnits BaseOffsetInLayoutClass, + + MethodInfo(CharUnits BaseOffset, CharUnits BaseOffsetInLayoutClass, uint64_t VTableIndex) - : BaseOffset(BaseOffset), + : BaseOffset(BaseOffset), BaseOffsetInLayoutClass(BaseOffsetInLayoutClass), VTableIndex(VTableIndex) { } - - MethodInfo() - : BaseOffset(CharUnits::Zero()), - BaseOffsetInLayoutClass(CharUnits::Zero()), + + MethodInfo() + : BaseOffset(CharUnits::Zero()), + BaseOffsetInLayoutClass(CharUnits::Zero()), VTableIndex(0) { } }; - + typedef llvm::DenseMap<const CXXMethodDecl *, MethodInfo> MethodInfoMapTy; - + /// MethodInfoMap - The information for all methods in the vtable we're /// currently building. MethodInfoMapTy MethodInfoMap; @@ -860,25 +860,25 @@ private: MethodVTableIndicesTy MethodVTableIndices; typedef llvm::DenseMap<uint64_t, ThunkInfo> VTableThunksMapTy; - - /// VTableThunks - The thunks by vtable index in the vtable currently being + + /// VTableThunks - The thunks by vtable index in the vtable currently being /// built. VTableThunksMapTy VTableThunks; typedef SmallVector<ThunkInfo, 1> ThunkInfoVectorTy; typedef llvm::DenseMap<const CXXMethodDecl *, ThunkInfoVectorTy> ThunksMapTy; - + /// Thunks - A map that contains all the thunks needed for all methods in the /// most derived class for which the vtable is currently being built. ThunksMapTy Thunks; - + /// AddThunk - Add a thunk for the given method. void AddThunk(const CXXMethodDecl *MD, const ThunkInfo &Thunk); - + /// ComputeThisAdjustments - Compute the 'this' pointer adjustments for the /// part of the vtable we're currently building. void ComputeThisAdjustments(); - + typedef llvm::SmallPtrSet<const CXXRecordDecl *, 4> VisitedVirtualBasesSetTy; /// PrimaryVirtualBases - All known virtual bases who are a primary base of @@ -888,7 +888,7 @@ private: /// ComputeReturnAdjustment - Compute the return adjustment given a return /// adjustment base offset. ReturnAdjustment ComputeReturnAdjustment(BaseOffset Offset); - + /// ComputeThisAdjustmentBaseOffset - Compute the base offset for adjusting /// the 'this' pointer from the base subobject to the derived subobject. BaseOffset ComputeThisAdjustmentBaseOffset(BaseSubobject Base, @@ -897,8 +897,8 @@ private: /// ComputeThisAdjustment - Compute the 'this' pointer adjustment for the /// given virtual member function, its offset in the layout class and its /// final overrider. - ThisAdjustment - ComputeThisAdjustment(const CXXMethodDecl *MD, + ThisAdjustment + ComputeThisAdjustment(const CXXMethodDecl *MD, CharUnits BaseOffsetInLayoutClass, FinalOverriders::OverriderInfo Overrider); @@ -907,7 +907,7 @@ private: void AddMethod(const CXXMethodDecl *MD, ReturnAdjustment ReturnAdjustment); /// IsOverriderUsed - Returns whether the overrider will ever be used in this - /// part of the vtable. + /// part of the vtable. /// /// Itanium C++ ABI 2.5.2: /// @@ -921,16 +921,16 @@ private: /// adjustment is required and no thunk is generated. However, inside D /// objects, A is no longer a primary base of C, so if we allowed calls to /// C::f() to use the copy of A's vtable in the C subobject, we would need - /// to adjust this from C* to B::A*, which would require a third-party - /// thunk. Since we require that a call to C::f() first convert to A*, - /// C-in-D's copy of A's vtable is never referenced, so this is not + /// to adjust this from C* to B::A*, which would require a third-party + /// thunk. Since we require that a call to C::f() first convert to A*, + /// C-in-D's copy of A's vtable is never referenced, so this is not /// necessary. bool IsOverriderUsed(const CXXMethodDecl *Overrider, CharUnits BaseOffsetInLayoutClass, const CXXRecordDecl *FirstBaseInPrimaryBaseChain, CharUnits FirstBaseOffsetInLayoutClass) const; - + /// AddMethods - Add the methods of this base subobject and all its /// primary bases to the vtable components vector. void AddMethods(BaseSubobject Base, CharUnits BaseOffsetInLayoutClass, @@ -949,12 +949,12 @@ private: /// or a direct or indirect base of a virtual base. /// /// \param BaseIsVirtualInLayoutClass - Whether the base subobject is virtual - /// in the layout class. + /// in the layout class. void LayoutPrimaryAndSecondaryVTables(BaseSubobject Base, bool BaseIsMorallyVirtual, bool BaseIsVirtualInLayoutClass, CharUnits OffsetInLayoutClass); - + /// LayoutSecondaryVTables - Layout the secondary vtables for the given base /// subobject. /// @@ -965,18 +965,18 @@ private: /// DeterminePrimaryVirtualBases - Determine the primary virtual bases in this /// class hierarchy. - void DeterminePrimaryVirtualBases(const CXXRecordDecl *RD, + void DeterminePrimaryVirtualBases(const CXXRecordDecl *RD, CharUnits OffsetInLayoutClass, VisitedVirtualBasesSetTy &VBases); /// LayoutVTablesForVirtualBases - Layout vtables for all virtual bases of the /// given base (excluding any primary bases). - void LayoutVTablesForVirtualBases(const CXXRecordDecl *RD, + void LayoutVTablesForVirtualBases(const CXXRecordDecl *RD, VisitedVirtualBasesSetTy &VBases); /// isBuildingConstructionVTable - Return whether this vtable builder is /// building a construction vtable. - bool isBuildingConstructorVTable() const { + bool isBuildingConstructorVTable() const { return MostDerivedClass != LayoutClass; } @@ -1055,16 +1055,16 @@ public: void ItaniumVTableBuilder::AddThunk(const CXXMethodDecl *MD, const ThunkInfo &Thunk) { - assert(!isBuildingConstructorVTable() && + assert(!isBuildingConstructorVTable() && "Can't add thunks for construction vtable"); SmallVectorImpl<ThunkInfo> &ThunksVector = Thunks[MD]; // Check if we have this thunk already. - if (std::find(ThunksVector.begin(), ThunksVector.end(), Thunk) != + if (std::find(ThunksVector.begin(), ThunksVector.end(), Thunk) != ThunksVector.end()) return; - + ThunksVector.push_back(Thunk); } @@ -1107,18 +1107,18 @@ void ItaniumVTableBuilder::ComputeThisAdjustments() { // Ignore adjustments for unused function pointers. uint64_t VTableIndex = MethodInfo.VTableIndex; - if (Components[VTableIndex].getKind() == + if (Components[VTableIndex].getKind() == VTableComponent::CK_UnusedFunctionPointer) continue; - + // Get the final overrider for this method. FinalOverriders::OverriderInfo Overrider = Overriders.getOverrider(MD, MethodInfo.BaseOffset); - + // Check if we need an adjustment at all. if (MethodInfo.BaseOffsetInLayoutClass == Overrider.Offset) { // When a return thunk is needed by a derived class that overrides a - // virtual base, gcc uses a virtual 'this' adjustment as well. + // virtual base, gcc uses a virtual 'this' adjustment as well. // While the thunk itself might be needed by vtables in subclasses or // in construction vtables, there doesn't seem to be a reason for using // the thunk in this vtable. Still, we do so to match gcc. @@ -1143,7 +1143,7 @@ void ItaniumVTableBuilder::ComputeThisAdjustments() { /// Clear the method info map. MethodInfoMap.clear(); - + if (isBuildingConstructorVTable()) { // We don't need to store thunk information for construction vtables. return; @@ -1153,7 +1153,7 @@ void ItaniumVTableBuilder::ComputeThisAdjustments() { const VTableComponent &Component = Components[TI.first]; const ThunkInfo &Thunk = TI.second; const CXXMethodDecl *MD; - + switch (Component.getKind()) { default: llvm_unreachable("Unexpected vtable component kind!"); @@ -1176,7 +1176,7 @@ void ItaniumVTableBuilder::ComputeThisAdjustments() { ReturnAdjustment ItaniumVTableBuilder::ComputeReturnAdjustment(BaseOffset Offset) { ReturnAdjustment Adjustment; - + if (!Offset.isEmpty()) { if (Offset.VirtualBase) { // Get the virtual base offset offset. @@ -1193,7 +1193,7 @@ ItaniumVTableBuilder::ComputeReturnAdjustment(BaseOffset Offset) { Adjustment.NonVirtual = Offset.NonVirtualOffset.getQuantity(); } - + return Adjustment; } @@ -1201,7 +1201,7 @@ BaseOffset ItaniumVTableBuilder::ComputeThisAdjustmentBaseOffset( BaseSubobject Base, BaseSubobject Derived) const { const CXXRecordDecl *BaseRD = Base.getBase(); const CXXRecordDecl *DerivedRD = Derived.getBase(); - + CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, /*DetectVirtual=*/true); @@ -1214,32 +1214,32 @@ BaseOffset ItaniumVTableBuilder::ComputeThisAdjustmentBaseOffset( BaseOffset Offset = ComputeBaseOffset(Context, DerivedRD, Path); CharUnits OffsetToBaseSubobject = Offset.NonVirtualOffset; - + if (Offset.VirtualBase) { // If we have a virtual base class, the non-virtual offset is relative // to the virtual base class offset. const ASTRecordLayout &LayoutClassLayout = Context.getASTRecordLayout(LayoutClass); - - /// Get the virtual base offset, relative to the most derived class + + /// Get the virtual base offset, relative to the most derived class /// layout. - OffsetToBaseSubobject += + OffsetToBaseSubobject += LayoutClassLayout.getVBaseClassOffset(Offset.VirtualBase); } else { - // Otherwise, the non-virtual offset is relative to the derived class + // Otherwise, the non-virtual offset is relative to the derived class // offset. OffsetToBaseSubobject += Derived.getBaseOffset(); } - + // Check if this path gives us the right base subobject. if (OffsetToBaseSubobject == Base.getBaseOffset()) { // Since we're going from the base class _to_ the derived class, we'll // invert the non-virtual offset here. Offset.NonVirtualOffset = -Offset.NonVirtualOffset; return Offset; - } + } } - + return BaseOffset(); } @@ -1249,13 +1249,13 @@ ThisAdjustment ItaniumVTableBuilder::ComputeThisAdjustment( // Ignore adjustments for pure virtual member functions. if (Overrider.Method->isPure()) return ThisAdjustment(); - - BaseSubobject OverriddenBaseSubobject(MD->getParent(), + + BaseSubobject OverriddenBaseSubobject(MD->getParent(), BaseOffsetInLayoutClass); - + BaseSubobject OverriderBaseSubobject(Overrider.Method->getParent(), Overrider.Offset); - + // Compute the adjustment offset. BaseOffset Offset = ComputeThisAdjustmentBaseOffset(OverriddenBaseSubobject, OverriderBaseSubobject); @@ -1263,7 +1263,7 @@ ThisAdjustment ItaniumVTableBuilder::ComputeThisAdjustment( return ThisAdjustment(); ThisAdjustment Adjustment; - + if (Offset.VirtualBase) { // Get the vcall offset map for this virtual base. VCallOffsetMap &VCallOffsets = VCallOffsetsForVBases[Offset.VirtualBase]; @@ -1278,24 +1278,24 @@ ThisAdjustment ItaniumVTableBuilder::ComputeThisAdjustment( /*BaseIsVirtual=*/true, /*OffsetInLayoutClass=*/ CharUnits::Zero()); - + VCallOffsets = Builder.getVCallOffsets(); } - + Adjustment.Virtual.Itanium.VCallOffsetOffset = VCallOffsets.getVCallOffsetOffset(MD).getQuantity(); } // Set the non-virtual part of the adjustment. Adjustment.NonVirtual = Offset.NonVirtualOffset.getQuantity(); - + return Adjustment; } void ItaniumVTableBuilder::AddMethod(const CXXMethodDecl *MD, ReturnAdjustment ReturnAdjustment) { if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) { - assert(ReturnAdjustment.isEmpty() && + assert(ReturnAdjustment.isEmpty() && "Destructor can't have return adjustment!"); // Add both the complete destructor and the deleting destructor. @@ -1312,7 +1312,7 @@ void ItaniumVTableBuilder::AddMethod(const CXXMethodDecl *MD, } /// OverridesIndirectMethodInBase - Return whether the given member function -/// overrides any methods in the set of given bases. +/// overrides any methods in the set of given bases. /// Unlike OverridesMethodInBase, this checks "overriders of overriders". /// For example, if we have: /// @@ -1320,7 +1320,7 @@ void ItaniumVTableBuilder::AddMethod(const CXXMethodDecl *MD, /// struct B : A { virtual void f(); } /// struct C : B { virtual void f(); } /// -/// OverridesIndirectMethodInBase will return true if given C::f as the method +/// OverridesIndirectMethodInBase will return true if given C::f as the method /// and { A } as the set of bases. static bool OverridesIndirectMethodInBases( const CXXMethodDecl *MD, @@ -1333,7 +1333,7 @@ static bool OverridesIndirectMethodInBases( if (OverridesIndirectMethodInBases(OverriddenMD, Bases)) return true; } - + return false; } @@ -1347,9 +1347,9 @@ bool ItaniumVTableBuilder::IsOverriderUsed( return true; // We know now that Base (or a direct or indirect base of it) is a primary - // base in part of the class hierarchy, but not a primary base in the most + // base in part of the class hierarchy, but not a primary base in the most // derived class. - + // If the overrider is the first base in the primary base chain, we know // that the overrider will be used. if (Overrider->getParent() == FirstBaseInPrimaryBaseChain) @@ -1365,10 +1365,10 @@ bool ItaniumVTableBuilder::IsOverriderUsed( while (true) { const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase(); - + if (!PrimaryBase) break; - + if (Layout.isPrimaryBaseVirtual()) { assert(Layout.getVBaseClassOffset(PrimaryBase).isZero() && "Primary base should always be at offset 0!"); @@ -1387,13 +1387,13 @@ bool ItaniumVTableBuilder::IsOverriderUsed( assert(Layout.getBaseClassOffset(PrimaryBase).isZero() && "Primary base should always be at offset 0!"); } - + if (!PrimaryBases.insert(PrimaryBase)) llvm_unreachable("Found a duplicate primary base!"); RD = PrimaryBase; } - + // If the final overrider is an override of one of the primary bases, // then we know that it will be used. return OverridesIndirectMethodInBases(Overrider, PrimaryBases); @@ -1446,13 +1446,13 @@ void ItaniumVTableBuilder::AddMethods( if (Layout.isPrimaryBaseVirtual()) { assert(Layout.getVBaseClassOffset(PrimaryBase).isZero() && "Primary vbase should have a zero offset!"); - + const ASTRecordLayout &MostDerivedClassLayout = Context.getASTRecordLayout(MostDerivedClass); - - PrimaryBaseOffset = + + PrimaryBaseOffset = MostDerivedClassLayout.getVBaseClassOffset(PrimaryBase); - + const ASTRecordLayout &LayoutClassLayout = Context.getASTRecordLayout(LayoutClass); @@ -1467,9 +1467,9 @@ void ItaniumVTableBuilder::AddMethods( } AddMethods(BaseSubobject(PrimaryBase, PrimaryBaseOffset), - PrimaryBaseOffsetInLayoutClass, FirstBaseInPrimaryBaseChain, + PrimaryBaseOffsetInLayoutClass, FirstBaseInPrimaryBaseChain, FirstBaseOffsetInLayoutClass, PrimaryBases); - + if (!PrimaryBases.insert(PrimaryBase)) llvm_unreachable("Found a duplicate primary base!"); } @@ -1486,31 +1486,31 @@ void ItaniumVTableBuilder::AddMethods( MD = MD->getCanonicalDecl(); // Get the final overrider. - FinalOverriders::OverriderInfo Overrider = + FinalOverriders::OverriderInfo Overrider = Overriders.getOverrider(MD, Base.getBaseOffset()); // Check if this virtual member function overrides a method in a primary // base. If this is the case, and the return type doesn't require adjustment // then we can just use the member function from the primary base. - if (const CXXMethodDecl *OverriddenMD = + if (const CXXMethodDecl *OverriddenMD = FindNearestOverriddenMethod(MD, PrimaryBases)) { - if (ComputeReturnAdjustmentBaseOffset(Context, MD, + if (ComputeReturnAdjustmentBaseOffset(Context, MD, OverriddenMD).isEmpty()) { // Replace the method info of the overridden method with our own // method. - assert(MethodInfoMap.count(OverriddenMD) && + assert(MethodInfoMap.count(OverriddenMD) && "Did not find the overridden method!"); MethodInfo &OverriddenMethodInfo = MethodInfoMap[OverriddenMD]; - + MethodInfo MethodInfo(Base.getBaseOffset(), BaseOffsetInLayoutClass, OverriddenMethodInfo.VTableIndex); assert(!MethodInfoMap.count(MD) && "Should not have method info for this method yet!"); - + MethodInfoMap.insert(std::make_pair(MD, MethodInfo)); MethodInfoMap.erase(OverriddenMD); - + // If the overridden method exists in a virtual base class or a direct // or indirect base class of a virtual base class, we need to emit a // thunk if we ever have a class hierarchy where the base class is not @@ -1529,11 +1529,11 @@ void ItaniumVTableBuilder::AddMethods( // the final overrider. BaseOffset ReturnAdjustmentOffset = ComputeReturnAdjustmentBaseOffset(Context, Overrider.Method, MD); - ReturnAdjustment ReturnAdjustment = + ReturnAdjustment ReturnAdjustment = ComputeReturnAdjustment(ReturnAdjustmentOffset); // This is a virtual thunk for the most derived class, add it. - AddThunk(Overrider.Method, + AddThunk(Overrider.Method, ThunkInfo(ThisAdjustment, ReturnAdjustment)); } } @@ -1577,7 +1577,7 @@ void ItaniumVTableBuilder::AddMethods( // Check if this overrider is going to be used. const CXXMethodDecl *OverriderMD = Overrider.Method; if (!IsOverriderUsed(OverriderMD, BaseOffsetInLayoutClass, - FirstBaseInPrimaryBaseChain, + FirstBaseInPrimaryBaseChain, FirstBaseOffsetInLayoutClass)) { Components.push_back(VTableComponent::MakeUnusedFunction(OverriderMD)); continue; @@ -1587,13 +1587,13 @@ void ItaniumVTableBuilder::AddMethods( // We don't want to do this for pure virtual member functions. BaseOffset ReturnAdjustmentOffset; if (!OverriderMD->isPure()) { - ReturnAdjustmentOffset = + ReturnAdjustmentOffset = ComputeReturnAdjustmentBaseOffset(Context, OverriderMD, MD); } - ReturnAdjustment ReturnAdjustment = + ReturnAdjustment ReturnAdjustment = ComputeReturnAdjustment(ReturnAdjustmentOffset); - + AddMethod(Overrider.Method, ReturnAdjustment); } } @@ -1604,14 +1604,14 @@ void ItaniumVTableBuilder::LayoutVTable() { /*BaseIsMorallyVirtual=*/false, MostDerivedClassIsVirtual, MostDerivedClassOffset); - + VisitedVirtualBasesSetTy VBases; - + // Determine the primary virtual bases. - DeterminePrimaryVirtualBases(MostDerivedClass, MostDerivedClassOffset, + DeterminePrimaryVirtualBases(MostDerivedClass, MostDerivedClassOffset, VBases); VBases.clear(); - + LayoutVTablesForVirtualBases(MostDerivedClass, VBases); // -fapple-kext adds an extra entry at end of vtbl. @@ -1630,14 +1630,14 @@ void ItaniumVTableBuilder::LayoutPrimaryAndSecondaryVTables( // Add vcall and vbase offsets for this vtable. VCallAndVBaseOffsetBuilder Builder(MostDerivedClass, LayoutClass, &Overriders, - Base, BaseIsVirtualInLayoutClass, + Base, BaseIsVirtualInLayoutClass, OffsetInLayoutClass); Components.append(Builder.components_begin(), Builder.components_end()); - + // Check if we need to add these vcall offsets. if (BaseIsVirtualInLayoutClass && !Builder.getVCallOffsets().empty()) { VCallOffsetMap &VCallOffsets = VCallOffsetsForVBases[Base.getBase()]; - + if (VCallOffsets.empty()) VCallOffsets = Builder.getVCallOffsets(); } @@ -1659,7 +1659,7 @@ void ItaniumVTableBuilder::LayoutPrimaryAndSecondaryVTables( // Now go through all virtual member functions and add them. PrimaryBasesSetVectorTy PrimaryBases; AddMethods(Base, OffsetInLayoutClass, - Base.getBase(), OffsetInLayoutClass, + Base.getBase(), OffsetInLayoutClass, PrimaryBases); const CXXRecordDecl *RD = Base.getBase(); @@ -1692,10 +1692,10 @@ void ItaniumVTableBuilder::LayoutPrimaryAndSecondaryVTables( const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase(); - + if (!PrimaryBase) break; - + if (Layout.isPrimaryBaseVirtual()) { // Check if this virtual primary base is a primary base in the layout // class. If it's not, we don't want to add it. @@ -1721,19 +1721,19 @@ ItaniumVTableBuilder::LayoutSecondaryVTables(BaseSubobject Base, bool BaseIsMorallyVirtual, CharUnits OffsetInLayoutClass) { // Itanium C++ ABI 2.5.2: - // Following the primary virtual table of a derived class are secondary + // Following the primary virtual table of a derived class are secondary // virtual tables for each of its proper base classes, except any primary // base(s) with which it shares its primary virtual table. const CXXRecordDecl *RD = Base.getBase(); const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase(); - + for (const auto &B : RD->bases()) { // Ignore virtual bases, we'll emit them later. if (B.isVirtual()) continue; - + const CXXRecordDecl *BaseDecl = B.getType()->getAsCXXRecordDecl(); // Ignore bases that don't have a vtable. @@ -1753,11 +1753,11 @@ ItaniumVTableBuilder::LayoutSecondaryVTables(BaseSubobject Base, // Get the base offset of this base. CharUnits RelativeBaseOffset = Layout.getBaseClassOffset(BaseDecl); CharUnits BaseOffset = Base.getBaseOffset() + RelativeBaseOffset; - - CharUnits BaseOffsetInLayoutClass = + + CharUnits BaseOffsetInLayoutClass = OffsetInLayoutClass + RelativeBaseOffset; - - // Don't emit a secondary vtable for a primary base. We might however want + + // Don't emit a secondary vtable for a primary base. We might however want // to emit secondary vtables for other bases of this base. if (BaseDecl == PrimaryBase) { LayoutSecondaryVTables(BaseSubobject(BaseDecl, BaseOffset), @@ -1778,7 +1778,7 @@ void ItaniumVTableBuilder::DeterminePrimaryVirtualBases( const CXXRecordDecl *RD, CharUnits OffsetInLayoutClass, VisitedVirtualBasesSetTy &VBases) { const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); - + // Check if this base has a primary base. if (const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase()) { @@ -1794,13 +1794,13 @@ void ItaniumVTableBuilder::DeterminePrimaryVirtualBases( CharUnits PrimaryBaseOffsetInLayoutClass = LayoutClassLayout.getVBaseClassOffset(PrimaryBase); - - // We know that the base is not a primary base in the layout class if + + // We know that the base is not a primary base in the layout class if // the base offsets are different. if (PrimaryBaseOffsetInLayoutClass != OffsetInLayoutClass) IsPrimaryVirtualBase = false; } - + if (IsPrimaryVirtualBase) PrimaryVirtualBases.insert(PrimaryBase); } @@ -1811,18 +1811,18 @@ void ItaniumVTableBuilder::DeterminePrimaryVirtualBases( const CXXRecordDecl *BaseDecl = B.getType()->getAsCXXRecordDecl(); CharUnits BaseOffsetInLayoutClass; - + if (B.isVirtual()) { if (!VBases.insert(BaseDecl).second) continue; - + const ASTRecordLayout &LayoutClassLayout = Context.getASTRecordLayout(LayoutClass); - BaseOffsetInLayoutClass = + BaseOffsetInLayoutClass = LayoutClassLayout.getVBaseClassOffset(BaseDecl); } else { - BaseOffsetInLayoutClass = + BaseOffsetInLayoutClass = OffsetInLayoutClass + Layout.getBaseClassOffset(BaseDecl); } @@ -1846,12 +1846,12 @@ void ItaniumVTableBuilder::LayoutVTablesForVirtualBases( VBases.insert(BaseDecl).second) { const ASTRecordLayout &MostDerivedClassLayout = Context.getASTRecordLayout(MostDerivedClass); - CharUnits BaseOffset = + CharUnits BaseOffset = MostDerivedClassLayout.getVBaseClassOffset(BaseDecl); - + const ASTRecordLayout &LayoutClassLayout = Context.getASTRecordLayout(LayoutClass); - CharUnits BaseOffsetInLayoutClass = + CharUnits BaseOffsetInLayoutClass = LayoutClassLayout.getVBaseClassOffset(BaseDecl); LayoutPrimaryAndSecondaryVTables( @@ -1860,7 +1860,7 @@ void ItaniumVTableBuilder::LayoutVTablesForVirtualBases( /*BaseIsVirtualInLayoutClass=*/true, BaseOffsetInLayoutClass); } - + // We only need to check the base for virtual base vtables if it actually // has virtual bases. if (BaseDecl->getNumVBases()) @@ -1897,7 +1897,7 @@ void ItaniumVTableBuilder::dumpLayout(raw_ostream &Out) { AddressPointsByIndex.insert(std::make_pair(Index, Base)); } - + for (unsigned I = 0, E = Components.size(); I != E; ++I) { uint64_t Index = I; @@ -1910,7 +1910,7 @@ void ItaniumVTableBuilder::dumpLayout(raw_ostream &Out) { case VTableComponent::CK_VCallOffset: Out << "vcall_offset (" - << Component.getVCallOffset().getQuantity() + << Component.getVCallOffset().getQuantity() << ")"; break; @@ -1925,17 +1925,17 @@ void ItaniumVTableBuilder::dumpLayout(raw_ostream &Out) { << Component.getOffsetToTop().getQuantity() << ")"; break; - + case VTableComponent::CK_RTTI: Component.getRTTIDecl()->printQualifiedName(Out); Out << " RTTI"; break; - + case VTableComponent::CK_FunctionPointer: { const CXXMethodDecl *MD = Component.getFunctionDecl(); - std::string Str = - PredefinedExpr::ComputeName(PredefinedExpr::PrettyFunctionNoVirtual, + std::string Str = + PredefinedExpr::ComputeName(PredefinedExpr::PrettyFunctionNoVirtual, MD); Out << Str; if (MD->isPure()) @@ -1950,7 +1950,7 @@ void ItaniumVTableBuilder::dumpLayout(raw_ostream &Out) { if (!Thunk.Return.isEmpty()) { Out << "\n [return adjustment: "; Out << Thunk.Return.NonVirtual << " non-virtual"; - + if (Thunk.Return.Virtual.Itanium.VBaseOffsetOffset) { Out << ", " << Thunk.Return.Virtual.Itanium.VBaseOffsetOffset; Out << " vbase offset offset"; @@ -1963,26 +1963,26 @@ void ItaniumVTableBuilder::dumpLayout(raw_ostream &Out) { if (!Thunk.This.isEmpty()) { Out << "\n [this adjustment: "; Out << Thunk.This.NonVirtual << " non-virtual"; - + if (Thunk.This.Virtual.Itanium.VCallOffsetOffset) { Out << ", " << Thunk.This.Virtual.Itanium.VCallOffsetOffset; Out << " vcall offset offset"; } Out << ']'; - } + } } break; } - case VTableComponent::CK_CompleteDtorPointer: + case VTableComponent::CK_CompleteDtorPointer: case VTableComponent::CK_DeletingDtorPointer: { - bool IsComplete = + bool IsComplete = Component.getKind() == VTableComponent::CK_CompleteDtorPointer; - + const CXXDestructorDecl *DD = Component.getDestructorDecl(); - + DD->printQualifiedName(Out); if (IsComplete) Out << "() [complete]"; @@ -1998,15 +1998,15 @@ void ItaniumVTableBuilder::dumpLayout(raw_ostream &Out) { if (!Thunk.This.isEmpty()) { Out << "\n [this adjustment: "; Out << Thunk.This.NonVirtual << " non-virtual"; - + if (Thunk.This.Virtual.Itanium.VCallOffsetOffset) { Out << ", " << Thunk.This.Virtual.Itanium.VCallOffsetOffset; Out << " vcall offset offset"; } - + Out << ']'; - } - } + } + } break; } @@ -2014,8 +2014,8 @@ void ItaniumVTableBuilder::dumpLayout(raw_ostream &Out) { case VTableComponent::CK_UnusedFunctionPointer: { const CXXMethodDecl *MD = Component.getUnusedFunctionDecl(); - std::string Str = - PredefinedExpr::ComputeName(PredefinedExpr::PrettyFunctionNoVirtual, + std::string Str = + PredefinedExpr::ComputeName(PredefinedExpr::PrettyFunctionNoVirtual, MD); Out << "[unused] " << Str; if (MD->isPure()) @@ -2025,14 +2025,14 @@ void ItaniumVTableBuilder::dumpLayout(raw_ostream &Out) { } Out << '\n'; - + // Dump the next address point. uint64_t NextIndex = Index + 1; if (AddressPointsByIndex.count(NextIndex)) { if (AddressPointsByIndex.count(NextIndex) == 1) { - const BaseSubobject &Base = + const BaseSubobject &Base = AddressPointsByIndex.find(NextIndex)->second; - + Out << " -- ("; Base.getBase()->printQualifiedName(Out); Out << ", " << Base.getBaseOffset().getQuantity(); @@ -2040,7 +2040,7 @@ void ItaniumVTableBuilder::dumpLayout(raw_ostream &Out) { } else { CharUnits BaseOffset = AddressPointsByIndex.lower_bound(NextIndex)->second.getBaseOffset(); - + // We store the class names in a set to get a stable order. std::set<std::string> ClassNames; for (const auto &I : @@ -2060,10 +2060,10 @@ void ItaniumVTableBuilder::dumpLayout(raw_ostream &Out) { } Out << '\n'; - + if (isBuildingConstructorVTable()) return; - + if (MostDerivedClass->getNumVBases()) { // We store the virtual base class names and their offsets in a map to get // a stable order. @@ -2074,7 +2074,7 @@ void ItaniumVTableBuilder::dumpLayout(raw_ostream &Out) { CharUnits OffsetOffset = I.second; ClassNamesAndOffsets.insert(std::make_pair(ClassName, OffsetOffset)); } - + Out << "Virtual base offset offsets for '"; MostDerivedClass->printQualifiedName(Out); Out << "' ("; @@ -2086,17 +2086,17 @@ void ItaniumVTableBuilder::dumpLayout(raw_ostream &Out) { Out << "\n"; } - + if (!Thunks.empty()) { // We store the method names in a map to get a stable order. std::map<std::string, const CXXMethodDecl *> MethodNamesAndDecls; for (const auto &I : Thunks) { const CXXMethodDecl *MD = I.first; - std::string MethodName = + std::string MethodName = PredefinedExpr::ComputeName(PredefinedExpr::PrettyFunctionNoVirtual, MD); - + MethodNamesAndDecls.insert(std::make_pair(MethodName, MD)); } @@ -2113,12 +2113,12 @@ void ItaniumVTableBuilder::dumpLayout(raw_ostream &Out) { Out << "Thunks for '" << MethodName << "' (" << ThunksVector.size(); Out << (ThunksVector.size() == 1 ? " entry" : " entries") << ").\n"; - + for (unsigned I = 0, E = ThunksVector.size(); I != E; ++I) { const ThunkInfo &Thunk = ThunksVector[I]; Out << llvm::format("%4d | ", I); - + // If this function pointer has a return pointer adjustment, dump it. if (!Thunk.Return.isEmpty()) { Out << "return adjustment: " << Thunk.Return.NonVirtual; @@ -2136,16 +2136,16 @@ void ItaniumVTableBuilder::dumpLayout(raw_ostream &Out) { if (!Thunk.This.isEmpty()) { Out << "this adjustment: "; Out << Thunk.This.NonVirtual << " non-virtual"; - + if (Thunk.This.Virtual.Itanium.VCallOffsetOffset) { Out << ", " << Thunk.This.Virtual.Itanium.VCallOffsetOffset; Out << " vcall offset offset"; } } - + Out << '\n'; } - + Out << '\n'; } } @@ -2227,7 +2227,7 @@ uint64_t ItaniumVTableContext::getMethodVTableIndex(GlobalDecl GD) { MethodVTableIndicesTy::iterator I = MethodVTableIndices.find(GD); if (I != MethodVTableIndices.end()) return I->second; - + const CXXRecordDecl *RD = cast<CXXMethodDecl>(GD.getDecl())->getParent(); computeVTableRelatedInformation(RD); @@ -2241,8 +2241,8 @@ CharUnits ItaniumVTableContext::getVirtualBaseOffsetOffset(const CXXRecordDecl *RD, const CXXRecordDecl *VBase) { ClassPairTy ClassPair(RD, VBase); - - VirtualBaseClassOffsetOffsetsMapTy::iterator I = + + VirtualBaseClassOffsetOffsetsMapTy::iterator I = VirtualBaseClassOffsetOffsets.find(ClassPair); if (I != VirtualBaseClassOffsetOffsets.end()) return I->second; @@ -2258,10 +2258,10 @@ ItaniumVTableContext::getVirtualBaseOffsetOffset(const CXXRecordDecl *RD, VirtualBaseClassOffsetOffsets.insert(std::make_pair(ClassPair, I.second)); } - + I = VirtualBaseClassOffsetOffsets.find(ClassPair); assert(I != VirtualBaseClassOffsetOffsets.end() && "Did not find index!"); - + return I->second; } @@ -2298,10 +2298,10 @@ ItaniumVTableContext::computeVTableRelatedInformation(const CXXRecordDecl *RD) { // the rest of the vtable related information. if (!RD->getNumVBases()) return; - + const CXXRecordDecl *VBase = RD->vbases_begin()->getType()->getAsCXXRecordDecl(); - + if (VirtualBaseClassOffsetOffsets.count(std::make_pair(RD, VBase))) return; |