Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions clang/include/clang/AST/Decl.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,9 @@ class TranslationUnitDecl : public Decl,
TranslationUnitDecl *getNextRedeclarationImpl() override {
return getNextRedeclaration();
}
TranslationUnitDecl *getNextRedeclarationNoUpdateImpl() override {
return getNextRedeclarationNoUpdate();
}

TranslationUnitDecl *getPreviousDeclImpl() override {
return getPreviousDecl();
Expand Down Expand Up @@ -607,6 +610,7 @@ class NamespaceDecl : public NamespaceBaseDecl,
using redeclarable_base = Redeclarable<NamespaceDecl>;

NamespaceDecl *getNextRedeclarationImpl() override;
NamespaceDecl *getNextRedeclarationNoUpdateImpl() override;
NamespaceDecl *getPreviousDeclImpl() override;
NamespaceDecl *getMostRecentDeclImpl() override;

Expand Down Expand Up @@ -1135,6 +1139,10 @@ class VarDecl : public DeclaratorDecl, public Redeclarable<VarDecl> {
return getNextRedeclaration();
}

VarDecl *getNextRedeclarationNoUpdateImpl() override {
return getNextRedeclarationNoUpdate();
}

VarDecl *getPreviousDeclImpl() override {
return getPreviousDecl();
}
Expand Down Expand Up @@ -2163,6 +2171,10 @@ class FunctionDecl : public DeclaratorDecl,
return getNextRedeclaration();
}

FunctionDecl *getNextRedeclarationNoUpdateImpl() override {
return getNextRedeclarationNoUpdate();
}

FunctionDecl *getPreviousDeclImpl() override {
return getPreviousDecl();
}
Expand Down Expand Up @@ -3586,6 +3598,10 @@ class TypedefNameDecl : public TypeDecl, public Redeclarable<TypedefNameDecl> {
return getNextRedeclaration();
}

TypedefNameDecl *getNextRedeclarationNoUpdateImpl() override {
return getNextRedeclarationNoUpdate();
}

TypedefNameDecl *getPreviousDeclImpl() override {
return getPreviousDecl();
}
Expand Down Expand Up @@ -3755,6 +3771,10 @@ class TagDecl : public TypeDecl,
return getNextRedeclaration();
}

TagDecl *getNextRedeclarationNoUpdateImpl() override {
return getNextRedeclarationNoUpdate();
}

TagDecl *getPreviousDeclImpl() override {
return getPreviousDecl();
}
Expand Down
35 changes: 27 additions & 8 deletions clang/include/clang/AST/DeclBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -989,6 +989,10 @@ class alignas(8) Decl {
/// Decl subclasses that can be redeclared should override this method so that
/// Decl::redecl_iterator can iterate over them.
virtual Decl *getNextRedeclarationImpl() { return this; }
/// Returns the next redeclaration without loading.
/// FIXME: We may be able to erase such unneccesary virtual function call by
/// introduce CRTP.
virtual Decl *getNextRedeclarationNoUpdateImpl() { return this; }

/// Implementation of getPreviousDecl(), to be overridden by any
/// subclass that has a redeclaration chain.
Expand All @@ -1000,7 +1004,8 @@ class alignas(8) Decl {

public:
/// Iterates through all the redeclarations of the same decl.
class redecl_iterator {
template <bool Update = true>
class redecl_iterator_impl {
/// Current - The current declaration.
Decl *Current = nullptr;
Decl *Starter;
Expand All @@ -1012,36 +1017,37 @@ class alignas(8) Decl {
using iterator_category = std::forward_iterator_tag;
using difference_type = std::ptrdiff_t;

redecl_iterator() = default;
explicit redecl_iterator(Decl *C) : Current(C), Starter(C) {}
redecl_iterator_impl() = default;
explicit redecl_iterator_impl(Decl *C) : Current(C), Starter(C) {}

reference operator*() const { return Current; }
value_type operator->() const { return Current; }

redecl_iterator& operator++() {
redecl_iterator_impl& operator++() {
assert(Current && "Advancing while iterator has reached end");
// Get either previous decl or latest decl.
Decl *Next = Current->getNextRedeclarationImpl();
Decl *Next = Update ? Current->getNextRedeclarationImpl() : Current->getNextRedeclarationNoUpdateImpl();
assert(Next && "Should return next redeclaration or itself, never null!");
Current = (Next != Starter) ? Next : nullptr;
return *this;
}

redecl_iterator operator++(int) {
redecl_iterator_impl operator++(int) {
redecl_iterator tmp(*this);
++(*this);
return tmp;
}

friend bool operator==(redecl_iterator x, redecl_iterator y) {
friend bool operator==(redecl_iterator_impl x, redecl_iterator_impl y) {
return x.Current == y.Current;
}

friend bool operator!=(redecl_iterator x, redecl_iterator y) {
friend bool operator!=(redecl_iterator_impl x, redecl_iterator_impl y) {
return x.Current != y.Current;
}
};

using redecl_iterator = redecl_iterator_impl</*update=*/true>;
using redecl_range = llvm::iterator_range<redecl_iterator>;

/// Returns an iterator range for all the redeclarations of the same
Expand All @@ -1056,6 +1062,19 @@ class alignas(8) Decl {

redecl_iterator redecls_end() const { return redecl_iterator(); }

using noload_redecl_iterator = redecl_iterator_impl</*update=*/false>;
using noload_redecl_range = llvm::iterator_range<noload_redecl_iterator>;

noload_redecl_range noload_redecls() const {
return noload_redecl_range(noload_redecls_begin(), noload_redecls_end());
}

noload_redecl_iterator noload_redecls_begin() const {
return noload_redecl_iterator(const_cast<Decl *>(this));
}

noload_redecl_iterator noload_redecls_end() const { return noload_redecl_iterator(); }

/// Retrieve the previous declaration that declares the same entity
/// as this declaration, or NULL if there is no previous declaration.
Decl *getPreviousDecl() { return getPreviousDeclImpl(); }
Expand Down
5 changes: 5 additions & 0 deletions clang/include/clang/AST/DeclCXX.h
Original file line number Diff line number Diff line change
Expand Up @@ -3229,6 +3229,7 @@ class NamespaceAliasDecl : public NamespaceBaseDecl,
using redeclarable_base = Redeclarable<NamespaceAliasDecl>;

NamespaceAliasDecl *getNextRedeclarationImpl() override;
NamespaceAliasDecl *getNextRedeclarationNoUpdateImpl() override;
NamespaceAliasDecl *getPreviousDeclImpl() override;
NamespaceAliasDecl *getMostRecentDeclImpl() override;

Expand Down Expand Up @@ -3414,6 +3415,10 @@ class UsingShadowDecl : public NamedDecl, public Redeclarable<UsingShadowDecl> {
return getNextRedeclaration();
}

UsingShadowDecl *getNextRedeclarationNoUpdateImpl() override {
return getNextRedeclarationNoUpdate();
}

UsingShadowDecl *getPreviousDeclImpl() override {
return getPreviousDecl();
}
Expand Down
7 changes: 7 additions & 0 deletions clang/include/clang/AST/DeclObjC.h
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ class ObjCMethodDecl : public NamedDecl, public DeclContext {
/// An interface declaration will return its definition.
/// Otherwise it will return itself.
ObjCMethodDecl *getNextRedeclarationImpl() override;
ObjCMethodDecl *getNextRedeclarationNoUpdateImpl() override;

public:
friend class ASTDeclReader;
Expand Down Expand Up @@ -1265,6 +1266,9 @@ class ObjCInterfaceDecl : public ObjCContainerDecl
ObjCInterfaceDecl *getNextRedeclarationImpl() override {
return getNextRedeclaration();
}
ObjCInterfaceDecl *getNextRedeclarationNoUpdateImpl() override {
return getNextRedeclarationNoUpdate();
}

ObjCInterfaceDecl *getPreviousDeclImpl() override {
return getPreviousDecl();
Expand Down Expand Up @@ -2122,6 +2126,9 @@ class ObjCProtocolDecl : public ObjCContainerDecl,
ObjCProtocolDecl *getNextRedeclarationImpl() override {
return getNextRedeclaration();
}
ObjCProtocolDecl *getNextRedeclarationNoUpdateImpl() override {
return getNextRedeclarationNoUpdate();
}

ObjCProtocolDecl *getPreviousDeclImpl() override {
return getPreviousDecl();
Expand Down
3 changes: 3 additions & 0 deletions clang/include/clang/AST/DeclTemplate.h
Original file line number Diff line number Diff line change
Expand Up @@ -718,6 +718,9 @@ class RedeclarableTemplateDecl : public TemplateDecl,
RedeclarableTemplateDecl *getNextRedeclarationImpl() override {
return getNextRedeclaration();
}
RedeclarableTemplateDecl *getNextRedeclarationNoUpdateImpl() override {
return getNextRedeclarationNoUpdate();
}

RedeclarableTemplateDecl *getPreviousDeclImpl() override {
return getPreviousDecl();
Expand Down
10 changes: 8 additions & 2 deletions clang/include/clang/AST/Redeclarable.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ class Redeclarable {
isa<UninitializedLatest>(cast<NotKnownLatest>(Link));
}

template <bool Update = true>
decl_type *getPrevious(const decl_type *D) const {
if (NotKnownLatest NKL = dyn_cast<NotKnownLatest>(Link)) {
if (auto *Prev = dyn_cast<Previous>(NKL))
Expand All @@ -128,7 +129,8 @@ class Redeclarable {
const_cast<decl_type *>(D));
}

return static_cast<decl_type *>(cast<KnownLatest>(Link).get(D));
return Update ? static_cast<decl_type *>(cast<KnownLatest>(Link).get(D))
: static_cast<decl_type *>(cast<KnownLatest>(Link).getNotUpdated());
}

void setPrevious(decl_type *D) {
Expand Down Expand Up @@ -183,7 +185,11 @@ class Redeclarable {
decl_type *First;

decl_type *getNextRedeclaration() const {
return RedeclLink.getPrevious(static_cast<const decl_type *>(this));
return RedeclLink.template getPrevious</*update=*/true>(static_cast<const decl_type *>(this));
}

decl_type *getNextRedeclarationNoUpdate() const {
return RedeclLink.template getPrevious</*update=*/false>(static_cast<const decl_type *>(this));
}

public:
Expand Down
2 changes: 2 additions & 0 deletions clang/include/clang/Serialization/ASTReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -2078,6 +2078,8 @@ class ASTReader
return static_cast<unsigned>(DeclsLoaded.size());
}

unsigned getNumDeclsLoaded() const;

/// Returns the number of submodules known.
unsigned getTotalNumSubmodules() const {
return static_cast<unsigned>(SubmodulesLoaded.size());
Expand Down
8 changes: 8 additions & 0 deletions clang/lib/AST/DeclCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3276,6 +3276,10 @@ NamespaceDecl *NamespaceDecl::getNextRedeclarationImpl() {
return getNextRedeclaration();
}

NamespaceDecl *NamespaceDecl::getNextRedeclarationNoUpdateImpl() {
return getNextRedeclarationNoUpdate();
}

NamespaceDecl *NamespaceDecl::getPreviousDeclImpl() {
return getPreviousDecl();
}
Expand All @@ -3290,6 +3294,10 @@ NamespaceAliasDecl *NamespaceAliasDecl::getNextRedeclarationImpl() {
return getNextRedeclaration();
}

NamespaceAliasDecl *NamespaceAliasDecl::getNextRedeclarationNoUpdateImpl() {
return getNextRedeclarationNoUpdate();
}

NamespaceAliasDecl *NamespaceAliasDecl::getPreviousDeclImpl() {
return getPreviousDecl();
}
Expand Down
5 changes: 5 additions & 0 deletions clang/lib/AST/DeclObjC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1006,6 +1006,11 @@ ObjCMethodDecl *ObjCMethodDecl::getNextRedeclarationImpl() {
return Redecl ? Redecl : this;
}

// FIXME: make sure ObjCMethodDecl::getNextRedeclarationImpl wont't load.
ObjCMethodDecl *ObjCMethodDecl::getNextRedeclarationNoUpdateImpl() {
return getNextRedeclarationImpl();
}

ObjCMethodDecl *ObjCMethodDecl::getCanonicalDecl() {
auto *CtxD = cast<Decl>(getDeclContext());
const auto &Sel = getSelector();
Expand Down
9 changes: 6 additions & 3 deletions clang/lib/Serialization/ASTReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8847,14 +8847,17 @@ void ASTReader::StartTranslationUnit(ASTConsumer *Consumer) {
DeserializationListener->ReaderInitialized(this);
}

unsigned ASTReader::getNumDeclsLoaded() const {
return DeclsLoaded.size() -
llvm::count(DeclsLoaded.materialized(), (Decl *)nullptr);
}

void ASTReader::PrintStats() {
std::fprintf(stderr, "*** AST File Statistics:\n");

unsigned NumTypesLoaded =
TypesLoaded.size() - llvm::count(TypesLoaded.materialized(), QualType());
unsigned NumDeclsLoaded =
DeclsLoaded.size() -
llvm::count(DeclsLoaded.materialized(), (Decl *)nullptr);
unsigned NumDeclsLoaded = getNumDeclsLoaded();
unsigned NumIdentifiersLoaded =
IdentifiersLoaded.size() -
llvm::count(IdentifiersLoaded, (IdentifierInfo *)nullptr);
Expand Down
14 changes: 12 additions & 2 deletions clang/lib/Serialization/ASTReaderDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2107,8 +2107,18 @@ void ASTDeclMerger::MergeDefinitionData(
auto *Def = DD.Definition;
DD = std::move(MergeDD);
DD.Definition = Def;
for (auto *D : Def->redecls())
cast<CXXRecordDecl>(D)->DefinitionData = &DD;

#ifndef NDEBUG
unsigned OldLoadedSize = Reader.getNumDeclsLoaded();
#endif

for (auto *RD : Def->noload_redecls())
cast<CXXRecordDecl>(RD)->DefinitionData = &DD;

#ifndef NDEBUG
assert(Reader.getNumDeclsLoaded() == OldLoadedSize && "We shouldn't load new decls during merge definition data for class");
#endif

return;
}

Expand Down
Loading