예제 #1
0
void 
CXXRecordDecl::getFinalOverriders(CXXFinalOverriderMap &FinalOverriders) const {
  FinalOverriderCollector Collector;
  Collector.Collect(this, false, 0, FinalOverriders);

  // Weed out any final overriders that come from virtual base class
  // subobjects that were hidden by other subobjects along any path.
  // This is the final-overrider variant of C++ [class.member.lookup]p10.
  for (CXXFinalOverriderMap::iterator OM = FinalOverriders.begin(), 
                           OMEnd = FinalOverriders.end();
       OM != OMEnd;
       ++OM) {
    for (OverridingMethods::iterator SO = OM->second.begin(), 
                                  SOEnd = OM->second.end();
         SO != SOEnd; 
         ++SO) {
      SmallVector<UniqueVirtualMethod, 4> &Overriding = SO->second;
      if (Overriding.size() < 2)
        continue;

      for (SmallVector<UniqueVirtualMethod, 4>::iterator 
             Pos = Overriding.begin(), PosEnd = Overriding.end();
           Pos != PosEnd;
           /* increment in loop */) {
        if (!Pos->InVirtualSubobject) {
          ++Pos;
          continue;
        }

        // We have an overriding method in a virtual base class
        // subobject (or non-virtual base class subobject thereof);
        // determine whether there exists an other overriding method
        // in a base class subobject that hides the virtual base class
        // subobject.
        bool Hidden = false;
        for (SmallVector<UniqueVirtualMethod, 4>::iterator
               OP = Overriding.begin(), OPEnd = Overriding.end();
             OP != OPEnd && !Hidden; 
             ++OP) {
          if (Pos == OP)
            continue;

          if (OP->Method->getParent()->isVirtuallyDerivedFrom(
                         const_cast<CXXRecordDecl *>(Pos->InVirtualSubobject)))
            Hidden = true;
        }

        if (Hidden) {
          // The current overriding function is hidden by another
          // overriding function; remove this one.
          Pos = Overriding.erase(Pos);
          PosEnd = Overriding.end();
        } else {
          ++Pos;
        }
      }
    }
  }
}
예제 #2
0
void 
CXXRecordDecl::getFinalOverriders(CXXFinalOverriderMap &FinalOverriders) const {
  FinalOverriderCollector Collector;
  Collector.Collect(this, false, nullptr, FinalOverriders);

  // Weed out any final overriders that come from virtual base class
  // subobjects that were hidden by other subobjects along any path.
  // This is the final-overrider variant of C++ [class.member.lookup]p10.
  for (auto &OM : FinalOverriders) {
    for (auto &SO : OM.second) {
      SmallVectorImpl<UniqueVirtualMethod> &Overriding = SO.second;
      if (Overriding.size() < 2)
        continue;

      auto IsHidden = [&Overriding](const UniqueVirtualMethod &M) {
        if (!M.InVirtualSubobject)
          return false;

        // We have an overriding method in a virtual base class
        // subobject (or non-virtual base class subobject thereof);
        // determine whether there exists an other overriding method
        // in a base class subobject that hides the virtual base class
        // subobject.
        for (const UniqueVirtualMethod &OP : Overriding)
          if (&M != &OP &&
              OP.Method->getParent()->isVirtuallyDerivedFrom(
                  M.InVirtualSubobject))
            return true;
        return false;
      };

      Overriding.erase(
          std::remove_if(Overriding.begin(), Overriding.end(), IsHidden),
          Overriding.end());
    }
  }
}