summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenjamin Kramer <benny.kra@googlemail.com>2017-12-17 23:52:45 +0000
committerBenjamin Kramer <benny.kra@googlemail.com>2017-12-17 23:52:45 +0000
commit25836be2c482830889d3af5a7615e8f9236e7006 (patch)
tree1e3d46ca8e4b57b4e34e6d4246216f032aafe745
parent054fd17ac82c689988ceb47fde1109a0d9f327d5 (diff)
Refactor overridden methods iteration to avoid double lookups.
Convert most uses to range-for loops. No functionality change intended. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@320954 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/AST/DeclCXX.h2
-rw-r--r--lib/AST/ASTContext.cpp26
-rw-r--r--lib/AST/ASTDumper.cpp7
-rw-r--r--lib/AST/CXXInheritance.cpp19
-rw-r--r--lib/AST/DeclCXX.cpp4
-rw-r--r--lib/AST/RecordLayoutBuilder.cpp7
-rw-r--r--lib/AST/VTableBuilder.cpp11
-rw-r--r--lib/Analysis/ThreadSafetyCommon.cpp8
-rw-r--r--lib/CodeGen/CGDebugInfo.cpp2
-rw-r--r--lib/Index/IndexDecl.cpp5
-rw-r--r--lib/Sema/SemaCodeComplete.cpp5
-rw-r--r--lib/Sema/SemaDecl.cpp10
-rw-r--r--lib/Sema/SemaDeclCXX.cpp28
-rw-r--r--lib/Serialization/ASTWriterDecl.cpp6
14 files changed, 52 insertions, 88 deletions
diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h
index a8bc68a004..88dc9a6559 100644
--- a/include/clang/AST/DeclCXX.h
+++ b/include/clang/AST/DeclCXX.h
@@ -2015,7 +2015,7 @@ public:
if (CD->isVirtualAsWritten() || CD->isPure())
return true;
- return (CD->begin_overridden_methods() != CD->end_overridden_methods());
+ return CD->size_overridden_methods() != 0;
}
/// If it's possible to devirtualize a call to this method, return the called
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 34a925020e..dd96148edb 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -1378,35 +1378,27 @@ void ASTContext::setInstantiatedFromUnnamedFieldDecl(FieldDecl *Inst,
ASTContext::overridden_cxx_method_iterator
ASTContext::overridden_methods_begin(const CXXMethodDecl *Method) const {
- llvm::DenseMap<const CXXMethodDecl *, CXXMethodVector>::const_iterator Pos =
- OverriddenMethods.find(Method->getCanonicalDecl());
- if (Pos == OverriddenMethods.end())
- return nullptr;
- return Pos->second.begin();
+ return overridden_methods(Method).begin();
}
ASTContext::overridden_cxx_method_iterator
ASTContext::overridden_methods_end(const CXXMethodDecl *Method) const {
- llvm::DenseMap<const CXXMethodDecl *, CXXMethodVector>::const_iterator Pos =
- OverriddenMethods.find(Method->getCanonicalDecl());
- if (Pos == OverriddenMethods.end())
- return nullptr;
- return Pos->second.end();
+ return overridden_methods(Method).end();
}
unsigned
ASTContext::overridden_methods_size(const CXXMethodDecl *Method) const {
- llvm::DenseMap<const CXXMethodDecl *, CXXMethodVector>::const_iterator Pos =
- OverriddenMethods.find(Method->getCanonicalDecl());
- if (Pos == OverriddenMethods.end())
- return 0;
- return Pos->second.size();
+ auto Range = overridden_methods(Method);
+ return Range.end() - Range.begin();
}
ASTContext::overridden_method_range
ASTContext::overridden_methods(const CXXMethodDecl *Method) const {
- return overridden_method_range(overridden_methods_begin(Method),
- overridden_methods_end(Method));
+ llvm::DenseMap<const CXXMethodDecl *, CXXMethodVector>::const_iterator Pos =
+ OverriddenMethods.find(Method->getCanonicalDecl());
+ if (Pos == OverriddenMethods.end())
+ return overridden_method_range(nullptr, nullptr);
+ return overridden_method_range(Pos->second.begin(), Pos->second.end());
}
void ASTContext::addOverriddenMethod(const CXXMethodDecl *Method,
diff --git a/lib/AST/ASTDumper.cpp b/lib/AST/ASTDumper.cpp
index e74aee0aaa..157b29fd84 100644
--- a/lib/AST/ASTDumper.cpp
+++ b/lib/AST/ASTDumper.cpp
@@ -1195,12 +1195,11 @@ void ASTDumper::VisitFunctionDecl(const FunctionDecl *D) {
};
dumpChild([=] {
- auto FirstOverrideItr = MD->begin_overridden_methods();
+ auto Overrides = MD->overridden_methods();
OS << "Overrides: [ ";
- dumpOverride(*FirstOverrideItr);
+ dumpOverride(*Overrides.begin());
for (const auto *Override :
- llvm::make_range(FirstOverrideItr + 1,
- MD->end_overridden_methods())) {
+ llvm::make_range(Overrides.begin() + 1, Overrides.end())) {
OS << ", ";
dumpOverride(Override);
}
diff --git a/lib/AST/CXXInheritance.cpp b/lib/AST/CXXInheritance.cpp
index 4f9f1da95f..24e96ba380 100644
--- a/lib/AST/CXXInheritance.cpp
+++ b/lib/AST/CXXInheritance.cpp
@@ -650,9 +650,11 @@ void FinalOverriderCollector::Collect(const CXXRecordDecl *RD,
continue;
CXXMethodDecl *CanonM = cast<CXXMethodDecl>(M->getCanonicalDecl());
+ using OverriddenMethodsRange =
+ llvm::iterator_range<CXXMethodDecl::method_iterator>;
+ OverriddenMethodsRange OverriddenMethods = CanonM->overridden_methods();
- if (CanonM->begin_overridden_methods()
- == CanonM->end_overridden_methods()) {
+ if (OverriddenMethods.begin() == OverriddenMethods.end()) {
// This is a new virtual function that does not override any
// other virtual function. Add it to the map of virtual
// functions for which we are tracking overridders.
@@ -671,11 +673,7 @@ 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.
- using OverriddenMethods =
- llvm::iterator_range<CXXMethodDecl::method_iterator>;
- SmallVector<OverriddenMethods, 4> Stack;
- Stack.push_back(llvm::make_range(CanonM->begin_overridden_methods(),
- CanonM->end_overridden_methods()));
+ SmallVector<OverriddenMethodsRange, 4> Stack(1, OverriddenMethods);
while (!Stack.empty()) {
for (const CXXMethodDecl *OM : Stack.pop_back_val()) {
const CXXMethodDecl *CanonOM = OM->getCanonicalDecl();
@@ -693,14 +691,13 @@ void FinalOverriderCollector::Collect(const CXXRecordDecl *RD,
UniqueVirtualMethod(CanonM, SubobjectNumber,
InVirtualSubobject));
- if (CanonOM->begin_overridden_methods()
- == CanonOM->end_overridden_methods())
+ auto OverriddenMethods = CanonOM->overridden_methods();
+ if (OverriddenMethods.begin() == OverriddenMethods.end())
continue;
// Continue recursion to the methods that this virtual method
// overrides.
- Stack.push_back(llvm::make_range(CanonOM->begin_overridden_methods(),
- CanonOM->end_overridden_methods()));
+ Stack.push_back(OverriddenMethods);
}
}
diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp
index 6126cc5267..41f2449a9d 100644
--- a/lib/AST/DeclCXX.cpp
+++ b/lib/AST/DeclCXX.cpp
@@ -1642,9 +1642,7 @@ bool CXXMethodDecl::isStatic() const {
static bool recursivelyOverrides(const CXXMethodDecl *DerivedMD,
const CXXMethodDecl *BaseMD) {
- for (CXXMethodDecl::method_iterator I = DerivedMD->begin_overridden_methods(),
- E = DerivedMD->end_overridden_methods(); I != E; ++I) {
- const CXXMethodDecl *MD = *I;
+ for (const CXXMethodDecl *MD : DerivedMD->overridden_methods()) {
if (MD->getCanonicalDecl() == BaseMD->getCanonicalDecl())
return true;
if (recursivelyOverrides(MD, BaseMD))
diff --git a/lib/AST/RecordLayoutBuilder.cpp b/lib/AST/RecordLayoutBuilder.cpp
index 0083e390cb..a9d43dfa80 100644
--- a/lib/AST/RecordLayoutBuilder.cpp
+++ b/lib/AST/RecordLayoutBuilder.cpp
@@ -2895,13 +2895,12 @@ void MicrosoftRecordLayoutBuilder::computeVtorDispSet(
Work.insert(MD);
while (!Work.empty()) {
const CXXMethodDecl *MD = *Work.begin();
- CXXMethodDecl::method_iterator i = MD->begin_overridden_methods(),
- e = MD->end_overridden_methods();
+ auto MethodRange = MD->overridden_methods();
// If a virtual method has no-overrides it lives in its parent's vtable.
- if (i == e)
+ if (MethodRange.begin() == MethodRange.end())
BasesWithOverriddenMethods.insert(MD->getParent());
else
- Work.insert(i, e);
+ Work.insert(MethodRange.begin(), MethodRange.end());
// We've finished processing this element, remove it from the working set.
Work.erase(MD);
}
diff --git a/lib/AST/VTableBuilder.cpp b/lib/AST/VTableBuilder.cpp
index ae8f6309fc..347c516ef6 100644
--- a/lib/AST/VTableBuilder.cpp
+++ b/lib/AST/VTableBuilder.cpp
@@ -1079,9 +1079,7 @@ static void
visitAllOverriddenMethods(const CXXMethodDecl *MD, VisitorTy &Visitor) {
assert(MD->isVirtual() && "Method is not virtual!");
- for (CXXMethodDecl::method_iterator I = MD->begin_overridden_methods(),
- E = MD->end_overridden_methods(); I != E; ++I) {
- const CXXMethodDecl *OverriddenMD = *I;
+ for (const CXXMethodDecl *OverriddenMD : MD->overridden_methods()) {
if (!Visitor(OverriddenMD))
continue;
visitAllOverriddenMethods(OverriddenMD, Visitor);
@@ -1329,11 +1327,8 @@ static bool OverridesIndirectMethodInBases(
ItaniumVTableBuilder::PrimaryBasesSetVectorTy &Bases) {
if (Bases.count(MD->getParent()))
return true;
-
- for (CXXMethodDecl::method_iterator I = MD->begin_overridden_methods(),
- E = MD->end_overridden_methods(); I != E; ++I) {
- const CXXMethodDecl *OverriddenMD = *I;
-
+
+ for (const CXXMethodDecl *OverriddenMD : MD->overridden_methods()) {
// Check "indirect overriders".
if (OverridesIndirectMethodInBases(OverriddenMD, Bases))
return true;
diff --git a/lib/Analysis/ThreadSafetyCommon.cpp b/lib/Analysis/ThreadSafetyCommon.cpp
index c1421b09c9..99284f07b4 100644
--- a/lib/Analysis/ThreadSafetyCommon.cpp
+++ b/lib/Analysis/ThreadSafetyCommon.cpp
@@ -319,11 +319,11 @@ static bool hasCppPointerType(const til::SExpr *E) {
static const CXXMethodDecl *getFirstVirtualDecl(const CXXMethodDecl *D) {
while (true) {
D = D->getCanonicalDecl();
- CXXMethodDecl::method_iterator I = D->begin_overridden_methods(),
- E = D->end_overridden_methods();
- if (I == E)
+ auto OverriddenMethods = D->overridden_methods();
+ if (OverriddenMethods.begin() == OverriddenMethods.end())
return D; // Method does not override anything
- D = *I; // FIXME: this does not work with multiple inheritance.
+ // FIXME: this does not work with multiple inheritance.
+ D = *OverriddenMethods.begin();
}
return nullptr;
}
diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp
index 5a288abe36..caea41ec0e 100644
--- a/lib/CodeGen/CGDebugInfo.cpp
+++ b/lib/CodeGen/CGDebugInfo.cpp
@@ -1395,7 +1395,7 @@ llvm::DISubprogram *CGDebugInfo::CreateCXXMemberFunction(
// C++ ABI does not include all virtual methods from non-primary bases in
// the vtable for the most derived class. For example, if C inherits from
// A and B, C's primary vftable will not include B's virtual methods.
- if (Method->begin_overridden_methods() == Method->end_overridden_methods())
+ if (Method->size_overridden_methods() == 0)
Flags |= llvm::DINode::FlagIntroducedVirtual;
// The 'this' adjustment accounts for both the virtual and non-virtual
diff --git a/lib/Index/IndexDecl.cpp b/lib/Index/IndexDecl.cpp
index 0615aeacea..e14750e046 100644
--- a/lib/Index/IndexDecl.cpp
+++ b/lib/Index/IndexDecl.cpp
@@ -233,9 +233,8 @@ public:
if (auto *CXXMD = dyn_cast<CXXMethodDecl>(D)) {
if (CXXMD->isVirtual())
Roles |= (unsigned)SymbolRole::Dynamic;
- for (auto I = CXXMD->begin_overridden_methods(),
- E = CXXMD->end_overridden_methods(); I != E; ++I) {
- Relations.emplace_back((unsigned)SymbolRole::RelationOverrideOf, *I);
+ for (const CXXMethodDecl *O : CXXMD->overridden_methods()) {
+ Relations.emplace_back((unsigned)SymbolRole::RelationOverrideOf, O);
}
}
gatherTemplatePseudoOverrides(D, Relations);
diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp
index ee11c5c94e..834e149d1a 100644
--- a/lib/Sema/SemaCodeComplete.cpp
+++ b/lib/Sema/SemaCodeComplete.cpp
@@ -3378,12 +3378,9 @@ static void MaybeAddOverrideCalls(Sema &S, DeclContext *InContext,
return;
PrintingPolicy Policy = getCompletionPrintingPolicy(S);
- for (CXXMethodDecl::method_iterator M = Method->begin_overridden_methods(),
- MEnd = Method->end_overridden_methods();
- M != MEnd; ++M) {
+ for (const CXXMethodDecl *Overridden : Method->overridden_methods()) {
CodeCompletionBuilder Builder(Results.getAllocator(),
Results.getCodeCompletionTUInfo());
- const CXXMethodDecl *Overridden = *M;
if (Overridden->getCanonicalDecl() == Method->getCanonicalDecl())
continue;
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 0b48a87c11..ec5ca69735 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -7517,16 +7517,14 @@ enum OverrideErrorKind { OEK_All, OEK_NonDeleted, OEK_Deleted };
static void ReportOverrides(Sema& S, unsigned DiagID, const CXXMethodDecl *MD,
OverrideErrorKind OEK = OEK_All) {
S.Diag(MD->getLocation(), DiagID) << MD->getDeclName();
- for (CXXMethodDecl::method_iterator I = MD->begin_overridden_methods(),
- E = MD->end_overridden_methods();
- I != E; ++I) {
+ for (const CXXMethodDecl *O : MD->overridden_methods()) {
// This check (& the OEK parameter) could be replaced by a predicate, but
// without lambdas that would be overkill. This is still nicer than writing
// out the diag loop 3 times.
if ((OEK == OEK_All) ||
- (OEK == OEK_NonDeleted && !(*I)->isDeleted()) ||
- (OEK == OEK_Deleted && (*I)->isDeleted()))
- S.Diag((*I)->getLocation(), diag::note_overridden_virtual_function);
+ (OEK == OEK_NonDeleted && !O->isDeleted()) ||
+ (OEK == OEK_Deleted && O->isDeleted()))
+ S.Diag(O->getLocation(), diag::note_overridden_virtual_function);
}
}
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 497713f660..96472a0a70 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -2748,8 +2748,7 @@ void Sema::CheckOverrideControl(NamedDecl *D) {
// If a function is marked with the virt-specifier override and
// does not override a member function of a base class, the program is
// ill-formed.
- bool HasOverriddenMethods =
- MD->begin_overridden_methods() != MD->end_overridden_methods();
+ bool HasOverriddenMethods = MD->size_overridden_methods() != 0;
if (MD->hasAttr<OverrideAttr>() && !HasOverriddenMethods)
Diag(MD->getLocation(), diag::err_function_marked_override_not_overriding)
<< MD->getDeclName();
@@ -7424,10 +7423,8 @@ private:
const llvm::SmallPtrSetImpl<const CXXMethodDecl *> &Methods) {
if (MD->size_overridden_methods() == 0)
return Methods.count(MD->getCanonicalDecl());
- for (CXXMethodDecl::method_iterator I = MD->begin_overridden_methods(),
- E = MD->end_overridden_methods();
- I != E; ++I)
- if (CheckMostOverridenMethods(*I, Methods))
+ for (const CXXMethodDecl *O : MD->overridden_methods())
+ if (CheckMostOverridenMethods(O, Methods))
return true;
return false;
}
@@ -7485,10 +7482,9 @@ static void AddMostOverridenMethods(const CXXMethodDecl *MD,
llvm::SmallPtrSetImpl<const CXXMethodDecl *>& Methods) {
if (MD->size_overridden_methods() == 0)
Methods.insert(MD->getCanonicalDecl());
- for (CXXMethodDecl::method_iterator I = MD->begin_overridden_methods(),
- E = MD->end_overridden_methods();
- I != E; ++I)
- AddMostOverridenMethods(*I, Methods);
+ else
+ for (const CXXMethodDecl *O : MD->overridden_methods())
+ AddMostOverridenMethods(O, Methods);
}
/// \brief Check if a method overloads virtual methods in a base class without
@@ -14062,15 +14058,13 @@ void Sema::SetDeclDeleted(Decl *Dcl, SourceLocation DelLoc) {
// non-deleted virtual function.
if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(Fn)) {
bool IssuedDiagnostic = false;
- for (CXXMethodDecl::method_iterator I = MD->begin_overridden_methods(),
- E = MD->end_overridden_methods();
- I != E; ++I) {
+ for (const CXXMethodDecl *O : MD->overridden_methods()) {
if (!(*MD->begin_overridden_methods())->isDeleted()) {
if (!IssuedDiagnostic) {
Diag(DelLoc, diag::err_deleted_override) << MD->getDeclName();
IssuedDiagnostic = true;
}
- Diag((*I)->getLocation(), diag::note_overridden_virtual_function);
+ Diag(O->getLocation(), diag::note_overridden_virtual_function);
}
}
// If this function was implicitly deleted because it was defaulted,
@@ -14981,10 +14975,8 @@ void Sema::actOnDelayedExceptionSpecification(Decl *MethodD,
if (Method->isVirtual()) {
// Check overrides, which we previously had to delay.
- for (CXXMethodDecl::method_iterator O = Method->begin_overridden_methods(),
- OEnd = Method->end_overridden_methods();
- O != OEnd; ++O)
- CheckOverridingFunctionExceptionSpec(Method, *O);
+ for (const CXXMethodDecl *O : Method->overridden_methods())
+ CheckOverridingFunctionExceptionSpec(Method, O);
}
}
diff --git a/lib/Serialization/ASTWriterDecl.cpp b/lib/Serialization/ASTWriterDecl.cpp
index 041ccd47d0..3dac3a4829 100644
--- a/lib/Serialization/ASTWriterDecl.cpp
+++ b/lib/Serialization/ASTWriterDecl.cpp
@@ -1267,10 +1267,8 @@ void ASTDeclWriter::VisitCXXMethodDecl(CXXMethodDecl *D) {
VisitFunctionDecl(D);
if (D->isCanonicalDecl()) {
Record.push_back(D->size_overridden_methods());
- for (CXXMethodDecl::method_iterator
- I = D->begin_overridden_methods(), E = D->end_overridden_methods();
- I != E; ++I)
- Record.AddDeclRef(*I);
+ for (const CXXMethodDecl *MD : D->overridden_methods())
+ Record.AddDeclRef(MD);
} else {
// We only need to record overridden methods once for the canonical decl.
Record.push_back(0);