================
@@ -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

Reply via email to