diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/AST/VTableBuilder.cpp')
| -rw-r--r-- | contrib/llvm/tools/clang/lib/AST/VTableBuilder.cpp | 62 | 
1 files changed, 40 insertions, 22 deletions
diff --git a/contrib/llvm/tools/clang/lib/AST/VTableBuilder.cpp b/contrib/llvm/tools/clang/lib/AST/VTableBuilder.cpp index 347c516ef6a5..0a3da024f147 100644 --- a/contrib/llvm/tools/clang/lib/AST/VTableBuilder.cpp +++ b/contrib/llvm/tools/clang/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;  | 
