aboutsummaryrefslogtreecommitdiff
path: root/lib/AST/CXXInheritance.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2015-05-27 18:47:56 +0000
committerDimitry Andric <dim@FreeBSD.org>2015-05-27 18:47:56 +0000
commit5e20cdd81c44a443562a09007668ffdf76c455af (patch)
treedbbd4047878da71c1a706e26ce05b4e7791b14cc /lib/AST/CXXInheritance.cpp
parentd5f23b0b7528b5c3caed1ba14f897cc4aaa9e3c3 (diff)
downloadsrc-5e20cdd81c44a443562a09007668ffdf76c455af.tar.gz
src-5e20cdd81c44a443562a09007668ffdf76c455af.zip
Vendor import of clang trunk r238337:vendor/clang/clang-trunk-r238337
Notes
Notes: svn path=/vendor/clang/dist/; revision=283627 svn path=/vendor/clang/clang-trunk-r238337/; revision=283628; tag=vendor/clang/clang-trunk-r238337
Diffstat (limited to 'lib/AST/CXXInheritance.cpp')
-rw-r--r--lib/AST/CXXInheritance.cpp138
1 files changed, 50 insertions, 88 deletions
diff --git a/lib/AST/CXXInheritance.cpp b/lib/AST/CXXInheritance.cpp
index 6e80ee7c28a1..800c8f83b880 100644
--- a/lib/AST/CXXInheritance.cpp
+++ b/lib/AST/CXXInheritance.cpp
@@ -318,48 +318,36 @@ bool CXXRecordDecl::lookupInBases(BaseMatchesCallback *BaseMatches,
//
// FIXME: This is an O(N^2) algorithm, but DPG doesn't see an easy
// way to make it any faster.
- for (CXXBasePaths::paths_iterator P = Paths.begin(), PEnd = Paths.end();
- P != PEnd; /* increment in loop */) {
- bool Hidden = false;
-
- for (CXXBasePath::iterator PE = P->begin(), PEEnd = P->end();
- PE != PEEnd && !Hidden; ++PE) {
- if (PE->Base->isVirtual()) {
- CXXRecordDecl *VBase = nullptr;
- if (const RecordType *Record = PE->Base->getType()->getAs<RecordType>())
- VBase = cast<CXXRecordDecl>(Record->getDecl());
- if (!VBase)
+ Paths.Paths.remove_if([&Paths](const CXXBasePath &Path) {
+ for (const CXXBasePathElement &PE : Path) {
+ if (!PE.Base->isVirtual())
+ continue;
+
+ CXXRecordDecl *VBase = nullptr;
+ if (const RecordType *Record = PE.Base->getType()->getAs<RecordType>())
+ VBase = cast<CXXRecordDecl>(Record->getDecl());
+ if (!VBase)
+ break;
+
+ // The declaration(s) we found along this path were found in a
+ // subobject of a virtual base. Check whether this virtual
+ // base is a subobject of any other path; if so, then the
+ // declaration in this path are hidden by that patch.
+ for (const CXXBasePath &HidingP : Paths) {
+ CXXRecordDecl *HidingClass = nullptr;
+ if (const RecordType *Record =
+ HidingP.back().Base->getType()->getAs<RecordType>())
+ HidingClass = cast<CXXRecordDecl>(Record->getDecl());
+ if (!HidingClass)
break;
- // The declaration(s) we found along this path were found in a
- // subobject of a virtual base. Check whether this virtual
- // base is a subobject of any other path; if so, then the
- // declaration in this path are hidden by that patch.
- for (CXXBasePaths::paths_iterator HidingP = Paths.begin(),
- HidingPEnd = Paths.end();
- HidingP != HidingPEnd;
- ++HidingP) {
- CXXRecordDecl *HidingClass = nullptr;
- if (const RecordType *Record
- = HidingP->back().Base->getType()->getAs<RecordType>())
- HidingClass = cast<CXXRecordDecl>(Record->getDecl());
- if (!HidingClass)
- break;
-
- if (HidingClass->isVirtuallyDerivedFrom(VBase)) {
- Hidden = true;
- break;
- }
- }
+ if (HidingClass->isVirtuallyDerivedFrom(VBase))
+ return true;
}
}
+ return false;
+ });
- if (Hidden)
- P = Paths.Paths.erase(P);
- else
- ++P;
- }
-
return true;
}
@@ -569,18 +557,14 @@ void FinalOverriderCollector::Collect(const CXXRecordDecl *RD,
// overrider. To do so, we dig down to the original virtual
// functions using data recursion and update all of the methods it
// overrides.
- typedef std::pair<CXXMethodDecl::method_iterator,
- CXXMethodDecl::method_iterator> OverriddenMethods;
+ typedef llvm::iterator_range<CXXMethodDecl::method_iterator>
+ OverriddenMethods;
SmallVector<OverriddenMethods, 4> Stack;
- Stack.push_back(std::make_pair(CanonM->begin_overridden_methods(),
- CanonM->end_overridden_methods()));
+ Stack.push_back(llvm::make_range(CanonM->begin_overridden_methods(),
+ CanonM->end_overridden_methods()));
while (!Stack.empty()) {
- OverriddenMethods OverMethods = Stack.back();
- Stack.pop_back();
-
- for (; OverMethods.first != OverMethods.second; ++OverMethods.first) {
- const CXXMethodDecl *CanonOM
- = cast<CXXMethodDecl>((*OverMethods.first)->getCanonicalDecl());
+ for (const CXXMethodDecl *OM : Stack.pop_back_val()) {
+ const CXXMethodDecl *CanonOM = OM->getCanonicalDecl();
// C++ [class.virtual]p2:
// A virtual member function C::vf of a class object S is
@@ -601,8 +585,8 @@ void FinalOverriderCollector::Collect(const CXXRecordDecl *RD,
// Continue recursion to the methods that this virtual method
// overrides.
- Stack.push_back(std::make_pair(CanonOM->begin_overridden_methods(),
- CanonOM->end_overridden_methods()));
+ Stack.push_back(llvm::make_range(CanonOM->begin_overridden_methods(),
+ CanonOM->end_overridden_methods()));
}
}
@@ -630,54 +614,32 @@ CXXRecordDecl::getFinalOverriders(CXXFinalOverriderMap &FinalOverriders) const {
// 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) {
- SmallVectorImpl<UniqueVirtualMethod> &Overriding = SO->second;
+ for (auto &OM : FinalOverriders) {
+ for (auto &SO : OM.second) {
+ SmallVectorImpl<UniqueVirtualMethod> &Overriding = SO.second;
if (Overriding.size() < 2)
continue;
- for (SmallVectorImpl<UniqueVirtualMethod>::iterator
- Pos = Overriding.begin(), PosEnd = Overriding.end();
- Pos != PosEnd;
- /* increment in loop */) {
- if (!Pos->InVirtualSubobject) {
- ++Pos;
- 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.
- bool Hidden = false;
- for (SmallVectorImpl<UniqueVirtualMethod>::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;
- }
- }
+ 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());
}
}
}