diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/AST/VTableBuilder.cpp | 26 |
1 files changed, 21 insertions, 5 deletions
diff --git a/clang/lib/AST/VTableBuilder.cpp b/clang/lib/AST/VTableBuilder.cpp index 3e7871e7bd7..a95791ce884 100644 --- a/clang/lib/AST/VTableBuilder.cpp +++ b/clang/lib/AST/VTableBuilder.cpp @@ -3544,6 +3544,19 @@ static void computeFullPathsForVFTables(ASTContext &Context, } } +static bool +vfptrIsEarlierInMDC(const ASTRecordLayout &Layout, + const MicrosoftVTableContext::MethodVFTableLocation &LHS, + const MicrosoftVTableContext::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()); @@ -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; + } } } |