llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang-modules Author: Chuanqi Xu (ChuanqiXu9) <details> <summary>Changes</summary> I meant to add test but I found it is hard as now we will always load every redecls after ASTReader. So I just add an assert for it. --- Full diff: https://github.com/llvm/llvm-project/pull/170823.diff 11 Files Affected: - (modified) clang/include/clang/AST/Decl.h (+20) - (modified) clang/include/clang/AST/DeclBase.h (+27-8) - (modified) clang/include/clang/AST/DeclCXX.h (+5) - (modified) clang/include/clang/AST/DeclObjC.h (+7) - (modified) clang/include/clang/AST/DeclTemplate.h (+3) - (modified) clang/include/clang/AST/Redeclarable.h (+8-2) - (modified) clang/include/clang/Serialization/ASTReader.h (+2) - (modified) clang/lib/AST/DeclCXX.cpp (+8) - (modified) clang/lib/AST/DeclObjC.cpp (+5) - (modified) clang/lib/Serialization/ASTReader.cpp (+6-3) - (modified) clang/lib/Serialization/ASTReaderDecl.cpp (+12-2) ``````````diff diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h index 2e8ceff453547..632a7326316a0 100644 --- a/clang/include/clang/AST/Decl.h +++ b/clang/include/clang/AST/Decl.h @@ -108,6 +108,9 @@ class TranslationUnitDecl : public Decl, TranslationUnitDecl *getNextRedeclarationImpl() override { return getNextRedeclaration(); } + TranslationUnitDecl *getNextRedeclarationNoUpdateImpl() override { + return getNextRedeclarationNoUpdate(); + } TranslationUnitDecl *getPreviousDeclImpl() override { return getPreviousDecl(); @@ -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; @@ -1135,6 +1139,10 @@ class VarDecl : public DeclaratorDecl, public Redeclarable<VarDecl> { return getNextRedeclaration(); } + VarDecl *getNextRedeclarationNoUpdateImpl() override { + return getNextRedeclarationNoUpdate(); + } + VarDecl *getPreviousDeclImpl() override { return getPreviousDecl(); } @@ -2163,6 +2171,10 @@ class FunctionDecl : public DeclaratorDecl, return getNextRedeclaration(); } + FunctionDecl *getNextRedeclarationNoUpdateImpl() override { + return getNextRedeclarationNoUpdate(); + } + FunctionDecl *getPreviousDeclImpl() override { return getPreviousDecl(); } @@ -3586,6 +3598,10 @@ class TypedefNameDecl : public TypeDecl, public Redeclarable<TypedefNameDecl> { return getNextRedeclaration(); } + TypedefNameDecl *getNextRedeclarationNoUpdateImpl() override { + return getNextRedeclarationNoUpdate(); + } + TypedefNameDecl *getPreviousDeclImpl() override { return getPreviousDecl(); } @@ -3755,6 +3771,10 @@ class TagDecl : public TypeDecl, return getNextRedeclaration(); } + TagDecl *getNextRedeclarationNoUpdateImpl() override { + return getNextRedeclarationNoUpdate(); + } + TagDecl *getPreviousDeclImpl() override { return getPreviousDecl(); } diff --git a/clang/include/clang/AST/DeclBase.h b/clang/include/clang/AST/DeclBase.h index 5519787d71f88..ea30d1dfc8f37 100644 --- a/clang/include/clang/AST/DeclBase.h +++ b/clang/include/clang/AST/DeclBase.h @@ -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. @@ -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; @@ -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 @@ -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(); } diff --git a/clang/include/clang/AST/DeclCXX.h b/clang/include/clang/AST/DeclCXX.h index dfa3befb27dd0..4238885cc4678 100644 --- a/clang/include/clang/AST/DeclCXX.h +++ b/clang/include/clang/AST/DeclCXX.h @@ -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; @@ -3414,6 +3415,10 @@ class UsingShadowDecl : public NamedDecl, public Redeclarable<UsingShadowDecl> { return getNextRedeclaration(); } + UsingShadowDecl *getNextRedeclarationNoUpdateImpl() override { + return getNextRedeclarationNoUpdate(); + } + UsingShadowDecl *getPreviousDeclImpl() override { return getPreviousDecl(); } diff --git a/clang/include/clang/AST/DeclObjC.h b/clang/include/clang/AST/DeclObjC.h index 2541edba83855..dfdefc6f90316 100644 --- a/clang/include/clang/AST/DeclObjC.h +++ b/clang/include/clang/AST/DeclObjC.h @@ -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; @@ -1265,6 +1266,9 @@ class ObjCInterfaceDecl : public ObjCContainerDecl ObjCInterfaceDecl *getNextRedeclarationImpl() override { return getNextRedeclaration(); } + ObjCInterfaceDecl *getNextRedeclarationNoUpdateImpl() override { + return getNextRedeclarationNoUpdate(); + } ObjCInterfaceDecl *getPreviousDeclImpl() override { return getPreviousDecl(); @@ -2122,6 +2126,9 @@ class ObjCProtocolDecl : public ObjCContainerDecl, ObjCProtocolDecl *getNextRedeclarationImpl() override { return getNextRedeclaration(); } + ObjCProtocolDecl *getNextRedeclarationNoUpdateImpl() override { + return getNextRedeclarationNoUpdate(); + } ObjCProtocolDecl *getPreviousDeclImpl() override { return getPreviousDecl(); diff --git a/clang/include/clang/AST/DeclTemplate.h b/clang/include/clang/AST/DeclTemplate.h index a4a1bb9c13c79..f836b32314eff 100644 --- a/clang/include/clang/AST/DeclTemplate.h +++ b/clang/include/clang/AST/DeclTemplate.h @@ -718,6 +718,9 @@ class RedeclarableTemplateDecl : public TemplateDecl, RedeclarableTemplateDecl *getNextRedeclarationImpl() override { return getNextRedeclaration(); } + RedeclarableTemplateDecl *getNextRedeclarationNoUpdateImpl() override { + return getNextRedeclarationNoUpdate(); + } RedeclarableTemplateDecl *getPreviousDeclImpl() override { return getPreviousDecl(); diff --git a/clang/include/clang/AST/Redeclarable.h b/clang/include/clang/AST/Redeclarable.h index 68516c66aaf65..2003d624e07db 100644 --- a/clang/include/clang/AST/Redeclarable.h +++ b/clang/include/clang/AST/Redeclarable.h @@ -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)) @@ -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) { @@ -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: diff --git a/clang/include/clang/Serialization/ASTReader.h b/clang/include/clang/Serialization/ASTReader.h index d276f0d21b958..1ac4b2566b54c 100644 --- a/clang/include/clang/Serialization/ASTReader.h +++ b/clang/include/clang/Serialization/ASTReader.h @@ -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()); diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp index 24e4f189cbe4a..60b15244535a4 100644 --- a/clang/lib/AST/DeclCXX.cpp +++ b/clang/lib/AST/DeclCXX.cpp @@ -3276,6 +3276,10 @@ NamespaceDecl *NamespaceDecl::getNextRedeclarationImpl() { return getNextRedeclaration(); } +NamespaceDecl *NamespaceDecl::getNextRedeclarationNoUpdateImpl() { + return getNextRedeclarationNoUpdate(); +} + NamespaceDecl *NamespaceDecl::getPreviousDeclImpl() { return getPreviousDecl(); } @@ -3290,6 +3294,10 @@ NamespaceAliasDecl *NamespaceAliasDecl::getNextRedeclarationImpl() { return getNextRedeclaration(); } +NamespaceAliasDecl *NamespaceAliasDecl::getNextRedeclarationNoUpdateImpl() { + return getNextRedeclarationNoUpdate(); +} + NamespaceAliasDecl *NamespaceAliasDecl::getPreviousDeclImpl() { return getPreviousDecl(); } diff --git a/clang/lib/AST/DeclObjC.cpp b/clang/lib/AST/DeclObjC.cpp index a66eb72981084..e07607b075bdd 100644 --- a/clang/lib/AST/DeclObjC.cpp +++ b/clang/lib/AST/DeclObjC.cpp @@ -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(); diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index aec61322fb8be..0d9edff273b6a 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -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); diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index 882d54f31280a..6e180b48e9e95 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -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 = ⅅ + +#ifndef NDEBUG + unsigned OldLoadedSize = Reader.getNumDeclsLoaded(); +#endif + + for (auto *RD : Def->noload_redecls()) + cast<CXXRecordDecl>(RD)->DefinitionData = ⅅ + +#ifndef NDEBUG + assert(Reader.getNumDeclsLoaded() == OldLoadedSize && "We shouldn't load new decls during merge definition data for class"); +#endif + return; } `````````` </details> https://github.com/llvm/llvm-project/pull/170823 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
