ChuanqiXu updated this revision to Diff 443147. ChuanqiXu retitled this revision from "[AST] [Modules] Handle full cases of DefaultArgStorage::setInherited" to "[RFC] [AST] [Modules] Handle full cases of DefaultArgStorage::setInherited". ChuanqiXu edited the summary of this revision. ChuanqiXu added a comment.
Rebase with main. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D128974/new/ https://reviews.llvm.org/D128974 Files: clang/include/clang/AST/DeclTemplate.h clang/test/Modules/InheritDefaultArguments.cppm clang/test/Modules/Inputs/PR31469/textual.h Index: clang/test/Modules/Inputs/PR31469/textual.h =================================================================== --- clang/test/Modules/Inputs/PR31469/textual.h +++ clang/test/Modules/Inputs/PR31469/textual.h @@ -4,7 +4,7 @@ template <class _Tp> class allocator; template <class _Tp, class _Alloc = allocator<_Tp>> class list; template <class _VoidPtr> class __list_iterator { - //template <class> friend class list; // causes another crash in ASTDeclReader::attachPreviousDecl + template <class> friend class list; template <class, class> friend class list; }; template <class _Tp, class _Alloc> class __list_imp {}; Index: clang/test/Modules/InheritDefaultArguments.cppm =================================================================== --- clang/test/Modules/InheritDefaultArguments.cppm +++ clang/test/Modules/InheritDefaultArguments.cppm @@ -10,7 +10,10 @@ class Templ; template <typename T, typename U> -class Templ {}; +class Templ { +public: + Templ(T t) {} +}; template <typename T> Templ(T t) -> Templ<T, int>; @@ -26,3 +29,6 @@ #include "foo.h" export module X; import A; +void foo() { + Templ t(0); +} Index: clang/include/clang/AST/DeclTemplate.h =================================================================== --- clang/include/clang/AST/DeclTemplate.h +++ clang/include/clang/AST/DeclTemplate.h @@ -15,6 +15,7 @@ #define LLVM_CLANG_AST_DECLTEMPLATE_H #include "clang/AST/ASTConcept.h" +#include "clang/AST/ASTContext.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclBase.h" #include "clang/AST/DeclCXX.h" @@ -373,11 +374,19 @@ /// Set that the default argument was inherited from another parameter. void setInherited(const ASTContext &C, ParmDecl *InheritedFrom) { - assert(!isInherited() && "default argument already inherited"); InheritedFrom = getParmOwningDefaultArg(InheritedFrom); if (!isSet()) ValueOrInherited = InheritedFrom; - else + else if (auto *D = ValueOrInherited.template dyn_cast<ParmDecl *>()) { + assert(C.isSameDefaultTemplateArgument(D, InheritedFrom)); + ValueOrInherited = + new (allocateDefaultArgStorageChain(C)) Chain{InheritedFrom, get()}; + } else if (auto *Inherited = + ValueOrInherited.template dyn_cast<Chain *>()) { + assert(C.isSameDefaultTemplateArgument(Inherited->PrevDeclWithDefaultArg, + InheritedFrom)); + Inherited->PrevDeclWithDefaultArg = InheritedFrom; + } else ValueOrInherited = new (allocateDefaultArgStorageChain(C)) Chain{InheritedFrom, ValueOrInherited.template get<ArgType>()}; }
Index: clang/test/Modules/Inputs/PR31469/textual.h =================================================================== --- clang/test/Modules/Inputs/PR31469/textual.h +++ clang/test/Modules/Inputs/PR31469/textual.h @@ -4,7 +4,7 @@ template <class _Tp> class allocator; template <class _Tp, class _Alloc = allocator<_Tp>> class list; template <class _VoidPtr> class __list_iterator { - //template <class> friend class list; // causes another crash in ASTDeclReader::attachPreviousDecl + template <class> friend class list; template <class, class> friend class list; }; template <class _Tp, class _Alloc> class __list_imp {}; Index: clang/test/Modules/InheritDefaultArguments.cppm =================================================================== --- clang/test/Modules/InheritDefaultArguments.cppm +++ clang/test/Modules/InheritDefaultArguments.cppm @@ -10,7 +10,10 @@ class Templ; template <typename T, typename U> -class Templ {}; +class Templ { +public: + Templ(T t) {} +}; template <typename T> Templ(T t) -> Templ<T, int>; @@ -26,3 +29,6 @@ #include "foo.h" export module X; import A; +void foo() { + Templ t(0); +} Index: clang/include/clang/AST/DeclTemplate.h =================================================================== --- clang/include/clang/AST/DeclTemplate.h +++ clang/include/clang/AST/DeclTemplate.h @@ -15,6 +15,7 @@ #define LLVM_CLANG_AST_DECLTEMPLATE_H #include "clang/AST/ASTConcept.h" +#include "clang/AST/ASTContext.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclBase.h" #include "clang/AST/DeclCXX.h" @@ -373,11 +374,19 @@ /// Set that the default argument was inherited from another parameter. void setInherited(const ASTContext &C, ParmDecl *InheritedFrom) { - assert(!isInherited() && "default argument already inherited"); InheritedFrom = getParmOwningDefaultArg(InheritedFrom); if (!isSet()) ValueOrInherited = InheritedFrom; - else + else if (auto *D = ValueOrInherited.template dyn_cast<ParmDecl *>()) { + assert(C.isSameDefaultTemplateArgument(D, InheritedFrom)); + ValueOrInherited = + new (allocateDefaultArgStorageChain(C)) Chain{InheritedFrom, get()}; + } else if (auto *Inherited = + ValueOrInherited.template dyn_cast<Chain *>()) { + assert(C.isSameDefaultTemplateArgument(Inherited->PrevDeclWithDefaultArg, + InheritedFrom)); + Inherited->PrevDeclWithDefaultArg = InheritedFrom; + } else ValueOrInherited = new (allocateDefaultArgStorageChain(C)) Chain{InheritedFrom, ValueOrInherited.template get<ArgType>()}; }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits