Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

templated lambda recognized as compare type #4242

Open
lceWolf opened this issue Feb 12, 2024 · 5 comments
Open

templated lambda recognized as compare type #4242

lceWolf opened this issue Feb 12, 2024 · 5 comments
Labels

Comments

@lceWolf
Copy link

lceWolf commented Feb 12, 2024

Uncrustify version: 0.78.1

Issue

C++20's templated lambdas are not parsed correctly. Given the following code

int main()
{
    auto t = []<typename T>(T t)
    {
        return t;
    };
}

The template part <typename T> is parsed as a part of a comparison (see debug output below).
This has the effect that if sp_compare is set to force, the template part is formatted as follows:
[] < typename T > (T t)

Expected

The template part is recognized correctly and is independent of sp_compare.

Maybe a new option has to be added for controlling newlines for these templates to distinguish function templates and templated lambdas?

Debug output

# language                      = CPP
# -=====-
# Line                Tag         Parent_type  Type of the parent         Columns Br/Lvl/pp             Flags   Nl  Text
#   1>            NEWLINE|               NONE|     PARENT_NOT_SET[  1/  1/  1/  0][0/0/0][                  0][1-0]
#   2>               TYPE|           FUNC_DEF|     PARENT_NOT_SET[  1/  1/  4/  0][0/0/0][             e 0000][0-0] int
#   2>           FUNC_DEF|               NONE|     PARENT_NOT_SET[  5/  5/  9/  1][0/0/0][                  0][0-0]     main
#   2>        FPAREN_OPEN|           FUNC_DEF|     PARENT_NOT_SET[  9/  9/ 10/  0][0/0/0][        2 0000 0000][0-0]         (
#   2>       FPAREN_CLOSE|           FUNC_DEF|     PARENT_NOT_SET[ 10/ 10/ 11/  0][0/0/0][        2 0000 0008][0-0]          )
#   2>            NEWLINE|               NONE|     PARENT_NOT_SET[ 11/ 11/  1/  0][0/0/0][                  0][1-0]
#   3>         BRACE_OPEN|           FUNC_DEF|     PARENT_NOT_SET[  1/  1/  2/  0][0/0/0][        2 0000 0000][0-0] {
#   3>            NEWLINE|               NONE|     PARENT_NOT_SET[  2/  2/  5/  0][1/1/0][                  0][1-0]
#   4>               TYPE|               NONE|     PARENT_NOT_SET[  5/  5/  9/  0][1/1/0][          208e 0000][0-0]     auto
#   4>               WORD|               NONE|     PARENT_NOT_SET[ 10/ 10/ 11/  1][1/1/0][          2300 0000][0-0]          t
#   4>             ASSIGN|               NONE|     PARENT_NOT_SET[ 12/ 12/ 13/  1][1/1/0][        2 0000 0000][0-0]            =
#   4>            TSQUARE|               NONE|     PARENT_NOT_SET[ 14/ 14/ 16/  1][1/1/0][        2 0008 0000][0-0]              []
#   4>            COMPARE|               NONE|     PARENT_NOT_SET[ 17/ 17/ 18/  1][1/1/0][        2 0000 0000][0-0]                 <
#   4>               TYPE|               NONE|     PARENT_NOT_SET[ 19/ 19/ 25/  1][1/1/0][             a 0000][0-0]                   size_t
#   4>               WORD|               NONE|     PARENT_NOT_SET[ 26/ 26/ 27/  1][1/1/0][                  0][0-0]                          T
#   4>            COMPARE|               NONE|     PARENT_NOT_SET[ 28/ 28/ 29/  1][1/1/0][        2 0000 0000][0-0]                            >
#   4>         PAREN_OPEN|             C_CAST|     PARENT_NOT_SET[ 30/ 30/ 31/  1][1/1/0][        2 0008 0000][0-0]                              (
#   4>               TYPE|             C_CAST|     PARENT_NOT_SET[ 31/ 31/ 32/  0][1/2/0][             a 0000][0-0]                               T
#   4>               TYPE|             C_CAST|     PARENT_NOT_SET[ 33/ 33/ 34/  1][1/2/0][                  0][0-0]                                 t
#   4>        PAREN_CLOSE|             C_CAST|     PARENT_NOT_SET[ 34/ 34/ 35/  0][1/1/0][        2 0000 0000][0-0]                                  )
#   4>            NEWLINE|               NONE|     PARENT_NOT_SET[ 35/ 35/  5/  0][1/1/0][                  0][1-0]
#   5>         BRACE_OPEN|             C_CAST|     PARENT_NOT_SET[  5/  5/  6/  0][1/1/0][        2 0008 0000][0-0]     {
#   5>            NEWLINE|               NONE|     PARENT_NOT_SET[  6/  6/  9/  0][2/2/0][                  0][1-0]
#   6>             RETURN|               NONE|     PARENT_NOT_SET[  9/  9/ 15/  0][2/2/0][             e 0000][0-0]         return
#   6>               WORD|               NONE|     PARENT_NOT_SET[ 16/ 16/ 17/  1][2/2/0][             8 0000][0-0]                t
#   6>          SEMICOLON|               NONE|     PARENT_NOT_SET[ 17/ 17/ 18/  0][2/2/0][        2 0000 0000][0-0]                 ;
#   6>            NEWLINE|               NONE|     PARENT_NOT_SET[ 18/ 18/  5/  0][2/2/0][                  0][1-0]
#   7>        BRACE_CLOSE|             C_CAST|     PARENT_NOT_SET[  5/  5/  6/  0][1/1/0][        2 0000 0000][0-0]     }
#   7>          SEMICOLON|               NONE|     PARENT_NOT_SET[  6/  6/  7/  0][1/1/0][        2 0000 0000][0-0]      ;
#   7>            NEWLINE|               NONE|     PARENT_NOT_SET[  7/  7/  1/  0][1/1/0][                  0][1-0]
#   8>        BRACE_CLOSE|           FUNC_DEF|     PARENT_NOT_SET[  1/  1/  2/  0][0/0/0][        2 0000 0000][0-0] }
#   8>            NEWLINE|               NONE|     PARENT_NOT_SET[  2/  2/  1/  0][0/0/0][                  0][1-0]
# -=====-
@guy-maurel
Copy link
Contributor

Is the template part recognized correctly?
What is about the change from typename to size_t?
I get with clang -Xclang -ast-dump -fsyntax-only lceWolf.cpp

lceWolf.cpp:4:16: warning: explicit template parameter list for lambdas is a C++20 extension [-Wc++20-extensions]
    auto t = []<typename T>(T t)
               ^

Can you provide a compileable source?

@gmaurel gmaurel added the C++20 label Feb 20, 2024
@lceWolf
Copy link
Author

lceWolf commented Feb 23, 2024

Thanks for your reply!

Yes the template seems to be recognized correctly. (see the new debug output below).
I don't know what happened to the output, honestly. Looks like I messed something up. Very sorry for that!

New Debug ouput

# Uncrustify_d-0.78.1
# option(s) with 'not default' value: 0
#
# -=====-
# number of loops               = 0
# -=====-
# language                      = CPP
# -=====-
# Line                Tag         Parent_type  Type of the parent         Columns Br/Lvl/pp             Flags   Nl  Text
#   1>               TYPE|           FUNC_DEF|     PARENT_NOT_SET[  1/  1/  4/  0][0/0/0][             e 0000][0-0] int
#   1>           FUNC_DEF|               NONE|     PARENT_NOT_SET[  5/  5/  9/  1][0/0/0][                  0][0-0]     main
#   1>        FPAREN_OPEN|           FUNC_DEF|     PARENT_NOT_SET[  9/  9/ 10/  0][0/0/0][        2 0000 0000][0-0]         (
#   1>       FPAREN_CLOSE|           FUNC_DEF|     PARENT_NOT_SET[ 10/ 10/ 11/  0][0/0/0][        2 0000 0008][0-0]          )
#   1>            NEWLINE|               NONE|     PARENT_NOT_SET[ 11/ 11/  1/  0][0/0/0][                  0][1-0]
#   2>         BRACE_OPEN|           FUNC_DEF|     PARENT_NOT_SET[  1/  1/  2/  0][0/0/0][        2 0000 0000][0-0] {
#   2>            NEWLINE|               NONE|     PARENT_NOT_SET[  2/  2/  5/  0][1/1/0][                  0][1-0]
#   3>               TYPE|               NONE|     PARENT_NOT_SET[  9/  5/  9/  0][1/1/0][          208e 0000][0-0]         auto
#   3>               WORD|               NONE|     PARENT_NOT_SET[ 14/ 10/ 11/  1][1/1/0][          2300 0000][0-0]              t
#   3>             ASSIGN|               NONE|     PARENT_NOT_SET[ 16/ 12/ 13/  1][1/1/0][        2 0000 0000][0-0]                =
#   3>            TSQUARE|               NONE|     PARENT_NOT_SET[ 18/ 14/ 16/  1][1/1/0][        2 0008 0000][0-0]                  []
#   3>            COMPARE|               NONE|     PARENT_NOT_SET[ 20/ 16/ 17/  0][1/1/0][        2 0000 0000][0-0]                    <
#   3>           TYPENAME|               NONE|     PARENT_NOT_SET[ 21/ 17/ 25/  0][1/1/0][             a 0000][0-0]                     typename
#   3>               WORD|               NONE|     PARENT_NOT_SET[ 30/ 26/ 27/  1][1/1/0][                  0][0-0]                              T
#   3>            COMPARE|               NONE|     PARENT_NOT_SET[ 31/ 27/ 28/  0][1/1/0][        2 0000 0000][0-0]                               >
#   3>         PAREN_OPEN|             C_CAST|     PARENT_NOT_SET[ 32/ 28/ 29/  0][1/1/0][        2 0008 0000][0-0]                                (
#   3>               TYPE|             C_CAST|     PARENT_NOT_SET[ 33/ 29/ 30/  0][1/2/0][             a 0000][0-0]                                 T
#   3>               TYPE|             C_CAST|     PARENT_NOT_SET[ 35/ 31/ 32/  1][1/2/0][                  0][0-0]                                   t
#   3>        PAREN_CLOSE|             C_CAST|     PARENT_NOT_SET[ 36/ 32/ 33/  0][1/1/0][        2 0000 0000][0-0]                                    )
#   3>            NEWLINE|               NONE|     PARENT_NOT_SET[ 37/ 33/  5/  0][1/1/0][                  0][1-0]
#   4>         BRACE_OPEN|             C_CAST|     PARENT_NOT_SET[  9/  5/  6/  0][1/1/0][        2 0008 0000][0-0]         {
#   4>            NEWLINE|               NONE|     PARENT_NOT_SET[ 10/  6/  9/  0][2/2/0][                  0][1-0]
#   5>             RETURN|               NONE|     PARENT_NOT_SET[ 17/  9/ 15/  0][2/2/0][             e 0000][0-0]                 return
#   5>               WORD|               NONE|     PARENT_NOT_SET[ 24/ 16/ 17/  1][2/2/0][             8 0000][0-0]                        t
#   5>          SEMICOLON|               NONE|     PARENT_NOT_SET[ 25/ 17/ 18/  0][2/2/0][        2 0000 0000][0-0]                         ;
#   5>            NEWLINE|               NONE|     PARENT_NOT_SET[ 26/ 18/  5/  0][2/2/0][                  0][1-0]
#   6>        BRACE_CLOSE|             C_CAST|     PARENT_NOT_SET[  9/  5/  6/  0][1/1/0][        2 0000 0000][0-0]         }
#   6>          SEMICOLON|               NONE|     PARENT_NOT_SET[ 10/  6/  7/  0][1/1/0][        2 0000 0000][0-0]          ;
#   6>            NEWLINE|               NONE|     PARENT_NOT_SET[ 11/  7/  1/  0][1/1/0][                  0][1-0]
#   7>        BRACE_CLOSE|           FUNC_DEF|     PARENT_NOT_SET[  1/  1/  2/  0][0/0/0][        2 0000 0000][0-0] }
#   7>            NEWLINE|               NONE|     PARENT_NOT_SET[  2/  2/  1/  0][0/0/0][                  0][2-0]
# -=====-

Compile

using clang++ -Xclang -ast-dump -fsyntax-only lceWolf.cpp -std=c++20 it compiles fine and results in

TranslationUnitDecl 0x15fc198 <<invalid sloc>> <invalid sloc>
|-TypedefDecl 0x15fca20 <<invalid sloc>> <invalid sloc> implicit __int128_t '__int128'
| `-BuiltinType 0x15fc760 '__int128'
|-TypedefDecl 0x15fca98 <<invalid sloc>> <invalid sloc> implicit __uint128_t 'unsigned __int128'
| `-BuiltinType 0x15fc780 'unsigned __int128'
|-TypedefDecl 0x15fce50 <<invalid sloc>> <invalid sloc> implicit __NSConstantString '__NSConstantString_tag'
| `-RecordType 0x15fcba0 '__NSConstantString_tag'
|   `-CXXRecord 0x15fcaf8 '__NSConstantString_tag'
|-TypedefDecl 0x15fcef8 <<invalid sloc>> <invalid sloc> implicit __builtin_ms_va_list 'char *'
| `-PointerType 0x15fceb0 'char *'
|   `-BuiltinType 0x15fc240 'char'
|-TypedefDecl 0x1646ea0 <<invalid sloc>> <invalid sloc> implicit __builtin_va_list '__va_list_tag[1]'
| `-ConstantArrayType 0x1646e40 '__va_list_tag[1]' 1 
|   `-RecordType 0x15fd000 '__va_list_tag'
|     `-CXXRecord 0x15fcf58 '__va_list_tag'
`-FunctionDecl 0x1646f58 <lceWolf.cpp:1:1, line:7:1> line:1:5 main 'int ()'
  `-CompoundStmt 0x1679420 <line:2:1, line:7:1>
    `-DeclStmt 0x1679408 <line:3:5, line:6:6>
      `-VarDecl 0x1647108 <line:3:5, line:6:5> line:3:10 t '(lambda at lceWolf.cpp:3:14)':'(lambda at lceWolf.cpp:3:14)' cinit
        `-LambdaExpr 0x1647ca8 <col:14, line:6:5> '(lambda at lceWolf.cpp:3:14)'
          |-CXXRecordDecl 0x1647398 <line:3:14> col:14 implicit class definition
          | |-DefinitionData generic 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
          | |-FunctionTemplateDecl 0x16476c0 <<invalid sloc>, line:6:5> line:3:14 operator()
          | | |-TemplateTypeParmDecl 0x1647178 <col:17, col:26> col:26 referenced typename depth 0 index 0 T
          | | `-CXXMethodDecl 0x1647608 <col:32, line:6:5> line:3:14 constexpr operator() 'auto (T) const' inline
          | |   |-ParmVarDecl 0x1647240 <col:29, col:31> col:31 referenced t 'T'
          | |   `-CompoundStmt 0x16477d8 <line:4:5, line:6:5>
          | |     `-ReturnStmt 0x16477c8 <line:5:9, col:16>
          | |       `-DeclRefExpr 0x16477a8 <col:16> 'T' lvalue ParmVar 0x1647240 't' 'T'
          | |-FunctionTemplateDecl 0x1647b20 <<invalid sloc>, line:6:5> line:3:14 implicit operator auto (*)(type-parameter-0-0)
          | | |-TemplateTypeParmDecl 0x1647178 <col:17, col:26> col:26 referenced typename depth 0 index 0 T
          | | `-CXXConversionDecl 0x1647a70 <col:14, line:6:5> line:3:14 implicit constexpr operator auto (*)(type-parameter-0-0) 'auto (*() const noexcept)(T)' inline
          | |-FunctionTemplateDecl 0x1647c38 <<invalid sloc>, line:6:5> line:3:14 implicit __invoke
          | | |-TemplateTypeParmDecl 0x1647178 <col:17, col:26> col:26 referenced typename depth 0 index 0 T
          | | `-CXXMethodDecl 0x1647b88 <col:14, line:6:5> line:3:14 implicit __invoke 'auto (T)' static inline
          | |   `-ParmVarDecl 0x1647a00 <col:29, col:31> col:31 t 'T'
          | `-CXXDestructorDecl 0x1647cd8 <col:14> col:14 implicit referenced constexpr ~ 'void () noexcept' inline default trivial
          `-CompoundStmt 0x16477d8 <line:4:5, line:6:5>
            `-ReturnStmt 0x16477c8 <line:5:9, col:16>
              `-DeclRefExpr 0x16477a8 <col:16> 'T' lvalue ParmVar 0x1647240 't' 'T'

@guy-maurel
Copy link
Contributor

can you close?

@lceWolf
Copy link
Author

lceWolf commented Mar 4, 2024

I just tested with the latest master (Uncrustify-0.78.1-143-d2b66ae86) and the issue seems to still be present.
If sp_compare is set to force the file is still wrongly formatted

@lceWolf
Copy link
Author

lceWolf commented Apr 18, 2024

@guy-maurel I don't want to push, I just want to make sure that all the necessary information is available. So, is anything still missing?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants