Skip to content
This repository was archived by the owner on Nov 1, 2021. It is now read-only.

Commit 25836be

Browse files
committed
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
1 parent 054fd17 commit 25836be

14 files changed

+52
-88
lines changed

include/clang/AST/DeclCXX.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -2015,7 +2015,7 @@ class CXXMethodDecl : public FunctionDecl {
20152015
if (CD->isVirtualAsWritten() || CD->isPure())
20162016
return true;
20172017

2018-
return (CD->begin_overridden_methods() != CD->end_overridden_methods());
2018+
return CD->size_overridden_methods() != 0;
20192019
}
20202020

20212021
/// If it's possible to devirtualize a call to this method, return the called

lib/AST/ASTContext.cpp

+9-17
Original file line numberDiff line numberDiff line change
@@ -1378,35 +1378,27 @@ void ASTContext::setInstantiatedFromUnnamedFieldDecl(FieldDecl *Inst,
13781378

13791379
ASTContext::overridden_cxx_method_iterator
13801380
ASTContext::overridden_methods_begin(const CXXMethodDecl *Method) const {
1381-
llvm::DenseMap<const CXXMethodDecl *, CXXMethodVector>::const_iterator Pos =
1382-
OverriddenMethods.find(Method->getCanonicalDecl());
1383-
if (Pos == OverriddenMethods.end())
1384-
return nullptr;
1385-
return Pos->second.begin();
1381+
return overridden_methods(Method).begin();
13861382
}
13871383

13881384
ASTContext::overridden_cxx_method_iterator
13891385
ASTContext::overridden_methods_end(const CXXMethodDecl *Method) const {
1390-
llvm::DenseMap<const CXXMethodDecl *, CXXMethodVector>::const_iterator Pos =
1391-
OverriddenMethods.find(Method->getCanonicalDecl());
1392-
if (Pos == OverriddenMethods.end())
1393-
return nullptr;
1394-
return Pos->second.end();
1386+
return overridden_methods(Method).end();
13951387
}
13961388

13971389
unsigned
13981390
ASTContext::overridden_methods_size(const CXXMethodDecl *Method) const {
1399-
llvm::DenseMap<const CXXMethodDecl *, CXXMethodVector>::const_iterator Pos =
1400-
OverriddenMethods.find(Method->getCanonicalDecl());
1401-
if (Pos == OverriddenMethods.end())
1402-
return 0;
1403-
return Pos->second.size();
1391+
auto Range = overridden_methods(Method);
1392+
return Range.end() - Range.begin();
14041393
}
14051394

14061395
ASTContext::overridden_method_range
14071396
ASTContext::overridden_methods(const CXXMethodDecl *Method) const {
1408-
return overridden_method_range(overridden_methods_begin(Method),
1409-
overridden_methods_end(Method));
1397+
llvm::DenseMap<const CXXMethodDecl *, CXXMethodVector>::const_iterator Pos =
1398+
OverriddenMethods.find(Method->getCanonicalDecl());
1399+
if (Pos == OverriddenMethods.end())
1400+
return overridden_method_range(nullptr, nullptr);
1401+
return overridden_method_range(Pos->second.begin(), Pos->second.end());
14101402
}
14111403

14121404
void ASTContext::addOverriddenMethod(const CXXMethodDecl *Method,

lib/AST/ASTDumper.cpp

+3-4
Original file line numberDiff line numberDiff line change
@@ -1195,12 +1195,11 @@ void ASTDumper::VisitFunctionDecl(const FunctionDecl *D) {
11951195
};
11961196

11971197
dumpChild([=] {
1198-
auto FirstOverrideItr = MD->begin_overridden_methods();
1198+
auto Overrides = MD->overridden_methods();
11991199
OS << "Overrides: [ ";
1200-
dumpOverride(*FirstOverrideItr);
1200+
dumpOverride(*Overrides.begin());
12011201
for (const auto *Override :
1202-
llvm::make_range(FirstOverrideItr + 1,
1203-
MD->end_overridden_methods())) {
1202+
llvm::make_range(Overrides.begin() + 1, Overrides.end())) {
12041203
OS << ", ";
12051204
dumpOverride(Override);
12061205
}

lib/AST/CXXInheritance.cpp

+8-11
Original file line numberDiff line numberDiff line change
@@ -650,9 +650,11 @@ void FinalOverriderCollector::Collect(const CXXRecordDecl *RD,
650650
continue;
651651

652652
CXXMethodDecl *CanonM = cast<CXXMethodDecl>(M->getCanonicalDecl());
653+
using OverriddenMethodsRange =
654+
llvm::iterator_range<CXXMethodDecl::method_iterator>;
655+
OverriddenMethodsRange OverriddenMethods = CanonM->overridden_methods();
653656

654-
if (CanonM->begin_overridden_methods()
655-
== CanonM->end_overridden_methods()) {
657+
if (OverriddenMethods.begin() == OverriddenMethods.end()) {
656658
// This is a new virtual function that does not override any
657659
// other virtual function. Add it to the map of virtual
658660
// functions for which we are tracking overridders.
@@ -671,11 +673,7 @@ void FinalOverriderCollector::Collect(const CXXRecordDecl *RD,
671673
// overrider. To do so, we dig down to the original virtual
672674
// functions using data recursion and update all of the methods it
673675
// overrides.
674-
using OverriddenMethods =
675-
llvm::iterator_range<CXXMethodDecl::method_iterator>;
676-
SmallVector<OverriddenMethods, 4> Stack;
677-
Stack.push_back(llvm::make_range(CanonM->begin_overridden_methods(),
678-
CanonM->end_overridden_methods()));
676+
SmallVector<OverriddenMethodsRange, 4> Stack(1, OverriddenMethods);
679677
while (!Stack.empty()) {
680678
for (const CXXMethodDecl *OM : Stack.pop_back_val()) {
681679
const CXXMethodDecl *CanonOM = OM->getCanonicalDecl();
@@ -693,14 +691,13 @@ void FinalOverriderCollector::Collect(const CXXRecordDecl *RD,
693691
UniqueVirtualMethod(CanonM, SubobjectNumber,
694692
InVirtualSubobject));
695693

696-
if (CanonOM->begin_overridden_methods()
697-
== CanonOM->end_overridden_methods())
694+
auto OverriddenMethods = CanonOM->overridden_methods();
695+
if (OverriddenMethods.begin() == OverriddenMethods.end())
698696
continue;
699697

700698
// Continue recursion to the methods that this virtual method
701699
// overrides.
702-
Stack.push_back(llvm::make_range(CanonOM->begin_overridden_methods(),
703-
CanonOM->end_overridden_methods()));
700+
Stack.push_back(OverriddenMethods);
704701
}
705702
}
706703

lib/AST/DeclCXX.cpp

+1-3
Original file line numberDiff line numberDiff line change
@@ -1642,9 +1642,7 @@ bool CXXMethodDecl::isStatic() const {
16421642

16431643
static bool recursivelyOverrides(const CXXMethodDecl *DerivedMD,
16441644
const CXXMethodDecl *BaseMD) {
1645-
for (CXXMethodDecl::method_iterator I = DerivedMD->begin_overridden_methods(),
1646-
E = DerivedMD->end_overridden_methods(); I != E; ++I) {
1647-
const CXXMethodDecl *MD = *I;
1645+
for (const CXXMethodDecl *MD : DerivedMD->overridden_methods()) {
16481646
if (MD->getCanonicalDecl() == BaseMD->getCanonicalDecl())
16491647
return true;
16501648
if (recursivelyOverrides(MD, BaseMD))

lib/AST/RecordLayoutBuilder.cpp

+3-4
Original file line numberDiff line numberDiff line change
@@ -2895,13 +2895,12 @@ void MicrosoftRecordLayoutBuilder::computeVtorDispSet(
28952895
Work.insert(MD);
28962896
while (!Work.empty()) {
28972897
const CXXMethodDecl *MD = *Work.begin();
2898-
CXXMethodDecl::method_iterator i = MD->begin_overridden_methods(),
2899-
e = MD->end_overridden_methods();
2898+
auto MethodRange = MD->overridden_methods();
29002899
// If a virtual method has no-overrides it lives in its parent's vtable.
2901-
if (i == e)
2900+
if (MethodRange.begin() == MethodRange.end())
29022901
BasesWithOverriddenMethods.insert(MD->getParent());
29032902
else
2904-
Work.insert(i, e);
2903+
Work.insert(MethodRange.begin(), MethodRange.end());
29052904
// We've finished processing this element, remove it from the working set.
29062905
Work.erase(MD);
29072906
}

lib/AST/VTableBuilder.cpp

+3-8
Original file line numberDiff line numberDiff line change
@@ -1079,9 +1079,7 @@ static void
10791079
visitAllOverriddenMethods(const CXXMethodDecl *MD, VisitorTy &Visitor) {
10801080
assert(MD->isVirtual() && "Method is not virtual!");
10811081

1082-
for (CXXMethodDecl::method_iterator I = MD->begin_overridden_methods(),
1083-
E = MD->end_overridden_methods(); I != E; ++I) {
1084-
const CXXMethodDecl *OverriddenMD = *I;
1082+
for (const CXXMethodDecl *OverriddenMD : MD->overridden_methods()) {
10851083
if (!Visitor(OverriddenMD))
10861084
continue;
10871085
visitAllOverriddenMethods(OverriddenMD, Visitor);
@@ -1329,11 +1327,8 @@ static bool OverridesIndirectMethodInBases(
13291327
ItaniumVTableBuilder::PrimaryBasesSetVectorTy &Bases) {
13301328
if (Bases.count(MD->getParent()))
13311329
return true;
1332-
1333-
for (CXXMethodDecl::method_iterator I = MD->begin_overridden_methods(),
1334-
E = MD->end_overridden_methods(); I != E; ++I) {
1335-
const CXXMethodDecl *OverriddenMD = *I;
1336-
1330+
1331+
for (const CXXMethodDecl *OverriddenMD : MD->overridden_methods()) {
13371332
// Check "indirect overriders".
13381333
if (OverridesIndirectMethodInBases(OverriddenMD, Bases))
13391334
return true;

lib/Analysis/ThreadSafetyCommon.cpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -319,11 +319,11 @@ static bool hasCppPointerType(const til::SExpr *E) {
319319
static const CXXMethodDecl *getFirstVirtualDecl(const CXXMethodDecl *D) {
320320
while (true) {
321321
D = D->getCanonicalDecl();
322-
CXXMethodDecl::method_iterator I = D->begin_overridden_methods(),
323-
E = D->end_overridden_methods();
324-
if (I == E)
322+
auto OverriddenMethods = D->overridden_methods();
323+
if (OverriddenMethods.begin() == OverriddenMethods.end())
325324
return D; // Method does not override anything
326-
D = *I; // FIXME: this does not work with multiple inheritance.
325+
// FIXME: this does not work with multiple inheritance.
326+
D = *OverriddenMethods.begin();
327327
}
328328
return nullptr;
329329
}

lib/CodeGen/CGDebugInfo.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -1395,7 +1395,7 @@ llvm::DISubprogram *CGDebugInfo::CreateCXXMemberFunction(
13951395
// C++ ABI does not include all virtual methods from non-primary bases in
13961396
// the vtable for the most derived class. For example, if C inherits from
13971397
// A and B, C's primary vftable will not include B's virtual methods.
1398-
if (Method->begin_overridden_methods() == Method->end_overridden_methods())
1398+
if (Method->size_overridden_methods() == 0)
13991399
Flags |= llvm::DINode::FlagIntroducedVirtual;
14001400

14011401
// The 'this' adjustment accounts for both the virtual and non-virtual

lib/Index/IndexDecl.cpp

+2-3
Original file line numberDiff line numberDiff line change
@@ -233,9 +233,8 @@ class IndexingDeclVisitor : public ConstDeclVisitor<IndexingDeclVisitor, bool> {
233233
if (auto *CXXMD = dyn_cast<CXXMethodDecl>(D)) {
234234
if (CXXMD->isVirtual())
235235
Roles |= (unsigned)SymbolRole::Dynamic;
236-
for (auto I = CXXMD->begin_overridden_methods(),
237-
E = CXXMD->end_overridden_methods(); I != E; ++I) {
238-
Relations.emplace_back((unsigned)SymbolRole::RelationOverrideOf, *I);
236+
for (const CXXMethodDecl *O : CXXMD->overridden_methods()) {
237+
Relations.emplace_back((unsigned)SymbolRole::RelationOverrideOf, O);
239238
}
240239
}
241240
gatherTemplatePseudoOverrides(D, Relations);

lib/Sema/SemaCodeComplete.cpp

+1-4
Original file line numberDiff line numberDiff line change
@@ -3378,12 +3378,9 @@ static void MaybeAddOverrideCalls(Sema &S, DeclContext *InContext,
33783378
return;
33793379

33803380
PrintingPolicy Policy = getCompletionPrintingPolicy(S);
3381-
for (CXXMethodDecl::method_iterator M = Method->begin_overridden_methods(),
3382-
MEnd = Method->end_overridden_methods();
3383-
M != MEnd; ++M) {
3381+
for (const CXXMethodDecl *Overridden : Method->overridden_methods()) {
33843382
CodeCompletionBuilder Builder(Results.getAllocator(),
33853383
Results.getCodeCompletionTUInfo());
3386-
const CXXMethodDecl *Overridden = *M;
33873384
if (Overridden->getCanonicalDecl() == Method->getCanonicalDecl())
33883385
continue;
33893386

lib/Sema/SemaDecl.cpp

+4-6
Original file line numberDiff line numberDiff line change
@@ -7517,16 +7517,14 @@ enum OverrideErrorKind { OEK_All, OEK_NonDeleted, OEK_Deleted };
75177517
static void ReportOverrides(Sema& S, unsigned DiagID, const CXXMethodDecl *MD,
75187518
OverrideErrorKind OEK = OEK_All) {
75197519
S.Diag(MD->getLocation(), DiagID) << MD->getDeclName();
7520-
for (CXXMethodDecl::method_iterator I = MD->begin_overridden_methods(),
7521-
E = MD->end_overridden_methods();
7522-
I != E; ++I) {
7520+
for (const CXXMethodDecl *O : MD->overridden_methods()) {
75237521
// This check (& the OEK parameter) could be replaced by a predicate, but
75247522
// without lambdas that would be overkill. This is still nicer than writing
75257523
// out the diag loop 3 times.
75267524
if ((OEK == OEK_All) ||
7527-
(OEK == OEK_NonDeleted && !(*I)->isDeleted()) ||
7528-
(OEK == OEK_Deleted && (*I)->isDeleted()))
7529-
S.Diag((*I)->getLocation(), diag::note_overridden_virtual_function);
7525+
(OEK == OEK_NonDeleted && !O->isDeleted()) ||
7526+
(OEK == OEK_Deleted && O->isDeleted()))
7527+
S.Diag(O->getLocation(), diag::note_overridden_virtual_function);
75307528
}
75317529
}
75327530

lib/Sema/SemaDeclCXX.cpp

+10-18
Original file line numberDiff line numberDiff line change
@@ -2748,8 +2748,7 @@ void Sema::CheckOverrideControl(NamedDecl *D) {
27482748
// If a function is marked with the virt-specifier override and
27492749
// does not override a member function of a base class, the program is
27502750
// ill-formed.
2751-
bool HasOverriddenMethods =
2752-
MD->begin_overridden_methods() != MD->end_overridden_methods();
2751+
bool HasOverriddenMethods = MD->size_overridden_methods() != 0;
27532752
if (MD->hasAttr<OverrideAttr>() && !HasOverriddenMethods)
27542753
Diag(MD->getLocation(), diag::err_function_marked_override_not_overriding)
27552754
<< MD->getDeclName();
@@ -7424,10 +7423,8 @@ struct FindHiddenVirtualMethod {
74247423
const llvm::SmallPtrSetImpl<const CXXMethodDecl *> &Methods) {
74257424
if (MD->size_overridden_methods() == 0)
74267425
return Methods.count(MD->getCanonicalDecl());
7427-
for (CXXMethodDecl::method_iterator I = MD->begin_overridden_methods(),
7428-
E = MD->end_overridden_methods();
7429-
I != E; ++I)
7430-
if (CheckMostOverridenMethods(*I, Methods))
7426+
for (const CXXMethodDecl *O : MD->overridden_methods())
7427+
if (CheckMostOverridenMethods(O, Methods))
74317428
return true;
74327429
return false;
74337430
}
@@ -7485,10 +7482,9 @@ static void AddMostOverridenMethods(const CXXMethodDecl *MD,
74857482
llvm::SmallPtrSetImpl<const CXXMethodDecl *>& Methods) {
74867483
if (MD->size_overridden_methods() == 0)
74877484
Methods.insert(MD->getCanonicalDecl());
7488-
for (CXXMethodDecl::method_iterator I = MD->begin_overridden_methods(),
7489-
E = MD->end_overridden_methods();
7490-
I != E; ++I)
7491-
AddMostOverridenMethods(*I, Methods);
7485+
else
7486+
for (const CXXMethodDecl *O : MD->overridden_methods())
7487+
AddMostOverridenMethods(O, Methods);
74927488
}
74937489

74947490
/// \brief Check if a method overloads virtual methods in a base class without
@@ -14062,15 +14058,13 @@ void Sema::SetDeclDeleted(Decl *Dcl, SourceLocation DelLoc) {
1406214058
// non-deleted virtual function.
1406314059
if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(Fn)) {
1406414060
bool IssuedDiagnostic = false;
14065-
for (CXXMethodDecl::method_iterator I = MD->begin_overridden_methods(),
14066-
E = MD->end_overridden_methods();
14067-
I != E; ++I) {
14061+
for (const CXXMethodDecl *O : MD->overridden_methods()) {
1406814062
if (!(*MD->begin_overridden_methods())->isDeleted()) {
1406914063
if (!IssuedDiagnostic) {
1407014064
Diag(DelLoc, diag::err_deleted_override) << MD->getDeclName();
1407114065
IssuedDiagnostic = true;
1407214066
}
14073-
Diag((*I)->getLocation(), diag::note_overridden_virtual_function);
14067+
Diag(O->getLocation(), diag::note_overridden_virtual_function);
1407414068
}
1407514069
}
1407614070
// If this function was implicitly deleted because it was defaulted,
@@ -14981,10 +14975,8 @@ void Sema::actOnDelayedExceptionSpecification(Decl *MethodD,
1498114975

1498214976
if (Method->isVirtual()) {
1498314977
// Check overrides, which we previously had to delay.
14984-
for (CXXMethodDecl::method_iterator O = Method->begin_overridden_methods(),
14985-
OEnd = Method->end_overridden_methods();
14986-
O != OEnd; ++O)
14987-
CheckOverridingFunctionExceptionSpec(Method, *O);
14978+
for (const CXXMethodDecl *O : Method->overridden_methods())
14979+
CheckOverridingFunctionExceptionSpec(Method, O);
1498814980
}
1498914981
}
1499014982

lib/Serialization/ASTWriterDecl.cpp

+2-4
Original file line numberDiff line numberDiff line change
@@ -1267,10 +1267,8 @@ void ASTDeclWriter::VisitCXXMethodDecl(CXXMethodDecl *D) {
12671267
VisitFunctionDecl(D);
12681268
if (D->isCanonicalDecl()) {
12691269
Record.push_back(D->size_overridden_methods());
1270-
for (CXXMethodDecl::method_iterator
1271-
I = D->begin_overridden_methods(), E = D->end_overridden_methods();
1272-
I != E; ++I)
1273-
Record.AddDeclRef(*I);
1270+
for (const CXXMethodDecl *MD : D->overridden_methods())
1271+
Record.AddDeclRef(MD);
12741272
} else {
12751273
// We only need to record overridden methods once for the canonical decl.
12761274
Record.push_back(0);

0 commit comments

Comments
 (0)