================ @@ -1613,8 +1613,8 @@ namespace { bool TemplateInstantiator::AlreadyTransformed(QualType T) { if (T.isNull()) return true; - - if (T->isInstantiationDependentType() || T->isVariablyModifiedType()) + if (T->isInstantiationDependentType() || T->isVariablyModifiedType() || + (SemaRef.getLangOpts().CPlusPlus20 && T->isDecltypeType())) ---------------- jcsxky wrote:
@cor3ntin I use this test case locally: ```cpp A<double>::Func<long long> f{}; ``` AST looks like: ```cpp Breakpoint 42, clang::DecltypeType::DecltypeType (this=0x39d190, E=0x39cfd0, underlyingType=..., can=...) at /home/huqizhi/Downloads/llvm-project/clang/lib/AST/Type.cpp:3797 3797 E(E), UnderlyingType(underlyingType) {} (gdb-ChatDBG) p E->dumpColor() CXXBindTemporaryExpr 0x39cfd0 'class A<double>::(lambda at /home/huqizhi/K.cpp:18:27)' (CXXTemporary 0x39cfd0) `-LambdaExpr 0x39cfa0 'class A<double>::(lambda at /home/huqizhi/K.cpp:18:27)' |-CXXRecordDecl 0x39ca60 implicit class definition | |-DefinitionData lambda pass_in_registers empty standard_layout trivially_copyable trivial literal has_constexpr_non_copy_move_ctor can_const_default_init | | |-DefaultConstructor exists trivial constexpr needs_implicit defaulted_is_constexpr | | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param | | |-MoveConstructor exists simple trivial needs_implicit | | |-CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param | | |-MoveAssignment exists simple trivial needs_implicit | | `-Destructor simple irrelevant trivial constexpr | |-CXXMethodDecl 0x39cbc8 constexpr operator() 'auto (void) const -> auto' implicit_instantiation inline instantiated_from 0x37cc18 | | `-CompoundStmt 0x39cd58 | | `-ReturnStmt 0x39cd48 | | `-CXXUnresolvedConstructExpr 0x39cd08 'U' 'U' list | | `-InitListExpr 0x39ccc8 'void' | |-CXXConversionDecl 0x39cdf0 implicit constexpr operator auto (*)() 'auto (*(void) const noexcept)(void) -> auto' inline | |-CXXMethodDecl 0x39ceb0 implicit __invoke 'auto (void) -> auto' static inline | `-CXXDestructorDecl 0x39cff8 implicit referenced constexpr ~(lambda at /home/huqizhi/K.cpp:18:27) 'void (void) noexcept' inline default trivial `-CompoundStmt 0x39cd58 `-ReturnStmt 0x39cd48 `-CXXUnresolvedConstructExpr 0x39cd08 'U' 'U' list `-InitListExpr 0x39ccc8 'void' ``` `CXXBindTemporaryExpr` and `LambdaExpr` both are not `InstantiationDependentType` ```cpp (gdb-ChatDBG) p E->isInstantiationDependent() $306 = false (gdb-ChatDBG) p ((CXXBindTemporaryExpr*)E)->getSubExpr()->isInstantiationDependent() $308 = false ``` This is because type of the lambda is not `InstantiationDependentType`: ```cpp (gdb-ChatDBG) p ((LambdaExpr*)(((CXXBindTemporaryExpr*)E)->getSubExpr()))->getType().dump() RecordType 0x39cba0 'class A<double>::(lambda at /home/huqizhi/K.cpp:18:27)' `-CXXRecord 0x39ca60 '' $312 = void ``` I think retransforming all the` decltype` should be right because retransforming should not change the result. But, this may involve some efficiency problem. Since `CXXUnresolvedConstructExpr` in the lambda expression is `InstantiationDependentType`, Maybe visiting the lambda expression and checking whether it has `InstantiationDependentType` child is a better approach (I think, but more complex). https://github.com/llvm/llvm-project/pull/80802 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits