diff options
Diffstat (limited to 'lib/AST/VTableBuilder.cpp')
-rw-r--r-- | lib/AST/VTableBuilder.cpp | 62 |
1 files changed, 40 insertions, 22 deletions
diff --git a/lib/AST/VTableBuilder.cpp b/lib/AST/VTableBuilder.cpp index 347c516ef6a5e..0a3da024f1477 100644 --- a/lib/AST/VTableBuilder.cpp +++ b/lib/AST/VTableBuilder.cpp @@ -2105,8 +2105,8 @@ void ItaniumVTableBuilder::dumpLayout(raw_ostream &Out) { const CXXMethodDecl *MD = I.second; ThunkInfoVectorTy ThunksVector = Thunks[MD]; - std::sort(ThunksVector.begin(), ThunksVector.end(), - [](const ThunkInfo &LHS, const ThunkInfo &RHS) { + llvm::sort(ThunksVector.begin(), ThunksVector.end(), + [](const ThunkInfo &LHS, const ThunkInfo &RHS) { assert(LHS.Method == nullptr && RHS.Method == nullptr); return std::tie(LHS.This, LHS.Return) < std::tie(RHS.This, RHS.Return); }); @@ -2206,9 +2206,9 @@ VTableLayout::VTableLayout(ArrayRef<size_t> VTableIndices, else this->VTableIndices = OwningArrayRef<size_t>(VTableIndices); - std::sort(this->VTableThunks.begin(), this->VTableThunks.end(), - [](const VTableLayout::VTableThunkTy &LHS, - const VTableLayout::VTableThunkTy &RHS) { + llvm::sort(this->VTableThunks.begin(), this->VTableThunks.end(), + [](const VTableLayout::VTableThunkTy &LHS, + const VTableLayout::VTableThunkTy &RHS) { assert((LHS.first != RHS.first || LHS.second == RHS.second) && "Different thunks should have unique indices!"); return LHS.first < RHS.first; @@ -2223,6 +2223,7 @@ ItaniumVTableContext::ItaniumVTableContext(ASTContext &Context) ItaniumVTableContext::~ItaniumVTableContext() {} uint64_t ItaniumVTableContext::getMethodVTableIndex(GlobalDecl GD) { + GD = GD.getCanonicalDecl(); MethodVTableIndicesTy::iterator I = MethodVTableIndices.find(GD); if (I != MethodVTableIndices.end()) return I->second; @@ -2367,8 +2368,6 @@ namespace { class VFTableBuilder { public: - typedef MicrosoftVTableContext::MethodVFTableLocation MethodVFTableLocation; - typedef llvm::DenseMap<GlobalDecl, MethodVFTableLocation> MethodVFTableLocationsTy; @@ -2398,7 +2397,7 @@ private: MethodVFTableLocationsTy MethodVFTableLocations; - /// \brief Does this class have an RTTI component? + /// Does this class have an RTTI component? bool HasRTTIComponent = false; /// MethodInfo - Contains information about a method in a vtable. @@ -2505,6 +2504,8 @@ private: for (const auto &I : MethodInfoMap) { const CXXMethodDecl *MD = I.first; const MethodInfo &MI = I.second; + assert(MD == MD->getCanonicalDecl()); + // Skip the methods that the MostDerivedClass didn't override // and the entries shadowed by return adjusting thunks. if (MD->getParent() != MostDerivedClass || MI.Shadowed) @@ -2997,7 +2998,7 @@ void VFTableBuilder::AddMethods(BaseSubobject Base, unsigned BaseDepth, } // In case we need a return adjustment, we'll add a new slot for - // the overrider. Mark the overriden method as shadowed by the new slot. + // the overrider. Mark the overridden method as shadowed by the new slot. OverriddenMethodInfo.Shadowed = true; // Force a special name mangling for a return-adjusting thunk @@ -3344,8 +3345,8 @@ static bool rebucketPaths(VPtrInfoVector &Paths) { PathsSorted.reserve(Paths.size()); for (auto& P : Paths) PathsSorted.push_back(*P); - std::sort(PathsSorted.begin(), PathsSorted.end(), - [](const VPtrInfo &LHS, const VPtrInfo &RHS) { + llvm::sort(PathsSorted.begin(), PathsSorted.end(), + [](const VPtrInfo &LHS, const VPtrInfo &RHS) { return LHS.MangledPath < RHS.MangledPath; }); bool Changed = false; @@ -3544,6 +3545,18 @@ static void computeFullPathsForVFTables(ASTContext &Context, } } +static bool vfptrIsEarlierInMDC(const ASTRecordLayout &Layout, + const MethodVFTableLocation &LHS, + const MethodVFTableLocation &RHS) { + CharUnits L = LHS.VFPtrOffset; + CharUnits R = RHS.VFPtrOffset; + if (LHS.VBase) + L += Layout.getVBaseClassOffset(LHS.VBase); + if (RHS.VBase) + R += Layout.getVBaseClassOffset(RHS.VBase); + return L < R; +} + void MicrosoftVTableContext::computeVTableRelatedInformation( const CXXRecordDecl *RD) { assert(RD->isDynamicClass()); @@ -3555,14 +3568,14 @@ void MicrosoftVTableContext::computeVTableRelatedInformation( const VTableLayout::AddressPointsMapTy EmptyAddressPointsMap; { - VPtrInfoVector VFPtrs; - computeVTablePaths(/*ForVBTables=*/false, RD, VFPtrs); - computeFullPathsForVFTables(Context, RD, VFPtrs); + auto VFPtrs = llvm::make_unique<VPtrInfoVector>(); + computeVTablePaths(/*ForVBTables=*/false, RD, *VFPtrs); + computeFullPathsForVFTables(Context, RD, *VFPtrs); VFPtrLocations[RD] = std::move(VFPtrs); } MethodVFTableLocationsTy NewMethodLocations; - for (const std::unique_ptr<VPtrInfo> &VFPtr : VFPtrLocations[RD]) { + for (const std::unique_ptr<VPtrInfo> &VFPtr : *VFPtrLocations[RD]) { VFTableBuilder Builder(*this, RD, *VFPtr); VFTableIdTy id(RD, VFPtr->FullOffsetInMDC); @@ -3574,12 +3587,15 @@ void MicrosoftVTableContext::computeVTableRelatedInformation( EmptyAddressPointsMap); Thunks.insert(Builder.thunks_begin(), Builder.thunks_end()); + const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); for (const auto &Loc : Builder.vtable_locations()) { - GlobalDecl GD = Loc.first; - MethodVFTableLocation NewLoc = Loc.second; - auto M = NewMethodLocations.find(GD); - if (M == NewMethodLocations.end() || NewLoc < M->second) - NewMethodLocations[GD] = NewLoc; + auto Insert = NewMethodLocations.insert(Loc); + if (!Insert.second) { + const MethodVFTableLocation &NewLoc = Loc.second; + MethodVFTableLocation &OldLoc = Insert.first->second; + if (vfptrIsEarlierInMDC(Layout, NewLoc, OldLoc)) + OldLoc = NewLoc; + } } } @@ -3704,7 +3720,7 @@ MicrosoftVTableContext::getVFPtrOffsets(const CXXRecordDecl *RD) { computeVTableRelatedInformation(RD); assert(VFPtrLocations.count(RD) && "Couldn't find vfptr locations"); - return VFPtrLocations[RD]; + return *VFPtrLocations[RD]; } const VTableLayout & @@ -3717,13 +3733,15 @@ MicrosoftVTableContext::getVFTableLayout(const CXXRecordDecl *RD, return *VFTableLayouts[id]; } -const MicrosoftVTableContext::MethodVFTableLocation & +MethodVFTableLocation MicrosoftVTableContext::getMethodVFTableLocation(GlobalDecl GD) { assert(cast<CXXMethodDecl>(GD.getDecl())->isVirtual() && "Only use this method for virtual methods or dtors"); if (isa<CXXDestructorDecl>(GD.getDecl())) assert(GD.getDtorType() == Dtor_Deleting); + GD = GD.getCanonicalDecl(); + MethodVFTableLocationsTy::iterator I = MethodVFTableLocations.find(GD); if (I != MethodVFTableLocations.end()) return I->second; |