[PATCH] D157296: [AST][Coroutine] Fix CoyieldExpr missing end loc

Ding Fei via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Mon Aug 7 19:20:32 PDT 2023


danix800 added a comment.

1. Use invalid loc: `SourceLocation()`

  ExprWithCleanups 0x55d1067162c8 <line:68:3, col:12> 'void'
  `-CoyieldExpr 0x55d106716280 <col:3, col:12> 'void'
    |-CXXMemberCallExpr 0x55d106715ed8 <col:3, col:12> 'std::suspend_always':'std::suspend_always'
    | |-MemberExpr 0x55d106715ea8 <col:3> '<bound member function type>' .yield_value 0x55d10670b220
    | | `-DeclRefExpr 0x55d106715e88 <col:3> 'std::coroutine_traits<Chat, int>::promise_type':'Chat::promise_type' lvalue Var 0x55d106714218 '__promise' 'std::coroutine_traits<Chat, int>::promise_type':'Chat::promise_type'
    | `-ImplicitCastExpr 0x55d106715f00 <col:12> 'int' <LValueToRValue>
    |   `-DeclRefExpr 0x55d1067118e8 <col:12> 'int' lvalue ParmVar 0x55d1067116c0 'sss' 'int'
    |-MaterializeTemporaryExpr 0x55d106715f58 <col:3, col:12> 'std::suspend_always':'std::suspend_always' lvalue
    | `-CXXMemberCallExpr 0x55d106715ed8 <col:3, col:12> 'std::suspend_always':'std::suspend_always'
    |   |-MemberExpr 0x55d106715ea8 <col:3> '<bound member function type>' .yield_value 0x55d10670b220
    |   | `-DeclRefExpr 0x55d106715e88 <col:3> 'std::coroutine_traits<Chat, int>::promise_type':'Chat::promise_type' lvalue Var 0x55d106714218 '__promise' 'std::coroutine_traits<Chat, int>::promise_type':'Chat::promise_type'
    |   `-ImplicitCastExpr 0x55d106715f00 <col:12> 'int' <LValueToRValue>
    |     `-DeclRefExpr 0x55d1067118e8 <col:12> 'int' lvalue ParmVar 0x55d1067116c0 'sss' 'int'
    |-ExprWithCleanups 0x55d106715fd8 <col:3, <invalid sloc>> 'bool'
    | `-CXXMemberCallExpr 0x55d106715fb8 <col:3, <invalid sloc>> 'bool'
    |   `-MemberExpr 0x55d106715f88 <col:3> '<bound member function type>' .await_ready 0x55d106708858
    |     `-OpaqueValueExpr 0x55d106715f70 <col:3, col:12> 'std::suspend_always':'std::suspend_always' lvalue
    |       `-MaterializeTemporaryExpr 0x55d106715f58 <col:3, col:12> 'std::suspend_always':'std::suspend_always' lvalue
    |         `-CXXMemberCallExpr 0x55d106715ed8 <col:3, col:12> 'std::suspend_always':'std::suspend_always'
    |           |-MemberExpr 0x55d106715ea8 <col:3> '<bound member function type>' .yield_value 0x55d10670b220
    |           | `-DeclRefExpr 0x55d106715e88 <col:3> 'std::coroutine_traits<Chat, int>::promise_type':'Chat::promise_type' lvalue Var 0x55d106714218 '__promise' 'std::coroutine_traits<Chat, int>::promise_type':'Chat::promise_type'
    |           `-ImplicitCastExpr 0x55d106715f00 <col:12> 'int' <LValueToRValue>
    |             `-DeclRefExpr 0x55d1067118e8 <col:12> 'int' lvalue ParmVar 0x55d1067116c0 'sss' 'int'
    |-CXXMemberCallExpr 0x55d106716160 <col:3> 'void'
    | |-MemberExpr 0x55d106716130 <col:3> '<bound member function type>' .await_suspend 0x55d106708ad8
    | | `-OpaqueValueExpr 0x55d106715f70 <col:3, col:12> 'std::suspend_always':'std::suspend_always' lvalue
    | |   `-MaterializeTemporaryExpr 0x55d106715f58 <col:3, col:12> 'std::suspend_always':'std::suspend_always' lvalue
    | |     `-CXXMemberCallExpr 0x55d106715ed8 <col:3, col:12> 'std::suspend_always':'std::suspend_always'
    | |       |-MemberExpr 0x55d106715ea8 <col:3> '<bound member function type>' .yield_value 0x55d10670b220
    | |       | `-DeclRefExpr 0x55d106715e88 <col:3> 'std::coroutine_traits<Chat, int>::promise_type':'Chat::promise_type' lvalue Var 0x55d106714218 '__promise' 'std::coroutine_traits<Chat, int>::promise_type':'Chat::promise_type'
    | |       `-ImplicitCastExpr 0x55d106715f00 <col:12> 'int' <LValueToRValue>
    | |         `-DeclRefExpr 0x55d1067118e8 <col:12> 'int' lvalue ParmVar 0x55d1067116c0 'sss' 'int'
    | `-ImplicitCastExpr 0x55d106716218 <col:3> 'coroutine_handle<>':'std::coroutine_handle<void>' <ConstructorConversion>
    |   `-CXXConstructExpr 0x55d1067161e8 <col:3> 'coroutine_handle<>':'std::coroutine_handle<void>' 'void (coroutine_handle<promise_type>) noexcept'
    |     `-CallExpr 0x55d1067160d0 <col:3> 'coroutine_handle<promise_type>':'std::coroutine_handle<Chat::promise_type>'
    |       |-ImplicitCastExpr 0x55d1067160b8 <col:3> 'coroutine_handle<promise_type> (*)(void *) noexcept' <FunctionToPointerDecay>
    |       | `-DeclRefExpr 0x55d106716098 <col:3> 'coroutine_handle<promise_type> (void *) noexcept' lvalue CXXMethod 0x55d10670dd98 'from_address' 'coroutine_handle<promise_type> (void *) noexcept'
    |       `-CallExpr 0x55d106716078 <col:3> 'void *'
    |         `-ImplicitCastExpr 0x55d106716060 <col:3> 'void *(*)() noexcept' <FunctionToPointerDecay>
    |           `-DeclRefExpr 0x55d106716040 <col:3> 'void *() noexcept' lvalue Function 0x55d106714c88 '__builtin_coro_frame' 'void *() noexcept'
    `-CXXMemberCallExpr 0x55d106716260 <col:3, <invalid sloc>> 'void'
      `-MemberExpr 0x55d106716230 <col:3> '<bound member function type>' .await_resume 0x55d106708bf8
        `-OpaqueValueExpr 0x55d106715f70 <col:3, col:12> 'std::suspend_always':'std::suspend_always' lvalue
          `-MaterializeTemporaryExpr 0x55d106715f58 <col:3, col:12> 'std::suspend_always':'std::suspend_always' lvalue
            `-CXXMemberCallExpr 0x55d106715ed8 <col:3, col:12> 'std::suspend_always':'std::suspend_always'
              |-MemberExpr 0x55d106715ea8 <col:3> '<bound member function type>' .yield_value 0x55d10670b220
              | `-DeclRefExpr 0x55d106715e88 <col:3> 'std::coroutine_traits<Chat, int>::promise_type':'Chat::promise_type' lvalue Var 0x55d106714218 '__promise' 'std::coroutine_traits<Chat, int>::promise_type':'Chat::promise_type'
              `-ImplicitCastExpr 0x55d106715f00 <col:12> 'int' <LValueToRValue>
                `-DeclRefExpr 0x55d1067118e8 <col:12> 'int' lvalue ParmVar 0x55d1067116c0 'sss' 'int'

Note that `CXXMemberCallExpr 0x55d106716260 <col:3, <invalid sloc>>` relies on `RParenLoc` directly. Coroutine is implemented as member call so I think `RParen` is intended and should exist and be correct.

2. Use last arg's end loc if exists:  `auto EndLoc = Args.empty() ? Loc : Args.back()->getEndLoc();`

  ExprWithCleanups 0x55dcfa09f2c8 <line:68:3, col:12> 'void'
  `-CoyieldExpr 0x55dcfa09f280 <col:3, col:12> 'void'
    |-CXXMemberCallExpr 0x55dcfa09eed8 <col:3, col:12> 'std::suspend_always':'std::suspend_always'
    | |-MemberExpr 0x55dcfa09eea8 <col:3> '<bound member function type>' .yield_value 0x55dcfa094220
    | | `-DeclRefExpr 0x55dcfa09ee88 <col:3> 'std::coroutine_traits<Chat, int>::promise_type':'Chat::promise_type' lvalue Var 0x55dcfa09d218 '__promise' 'std::coroutine_traits<Chat, int>::promise_type':'Chat::promise_type'
    | `-ImplicitCastExpr 0x55dcfa09ef00 <col:12> 'int' <LValueToRValue>
    |   `-DeclRefExpr 0x55dcfa09a8e8 <col:12> 'int' lvalue ParmVar 0x55dcfa09a6c0 'sss' 'int'
    |-MaterializeTemporaryExpr 0x55dcfa09ef58 <col:3, col:12> 'std::suspend_always':'std::suspend_always' lvalue
    | `-CXXMemberCallExpr 0x55dcfa09eed8 <col:3, col:12> 'std::suspend_always':'std::suspend_always'
    |   |-MemberExpr 0x55dcfa09eea8 <col:3> '<bound member function type>' .yield_value 0x55dcfa094220
    |   | `-DeclRefExpr 0x55dcfa09ee88 <col:3> 'std::coroutine_traits<Chat, int>::promise_type':'Chat::promise_type' lvalue Var 0x55dcfa09d218 '__promise' 'std::coroutine_traits<Chat, int>::promise_type':'Chat::promise_type'
    |   `-ImplicitCastExpr 0x55dcfa09ef00 <col:12> 'int' <LValueToRValue>
    |     `-DeclRefExpr 0x55dcfa09a8e8 <col:12> 'int' lvalue ParmVar 0x55dcfa09a6c0 'sss' 'int'
    |-ExprWithCleanups 0x55dcfa09efd8 <col:3> 'bool'
    | `-CXXMemberCallExpr 0x55dcfa09efb8 <col:3> 'bool'
    |   `-MemberExpr 0x55dcfa09ef88 <col:3> '<bound member function type>' .await_ready 0x55dcfa091858
    |     `-OpaqueValueExpr 0x55dcfa09ef70 <col:3, col:12> 'std::suspend_always':'std::suspend_always' lvalue
    |       `-MaterializeTemporaryExpr 0x55dcfa09ef58 <col:3, col:12> 'std::suspend_always':'std::suspend_always' lvalue
    |         `-CXXMemberCallExpr 0x55dcfa09eed8 <col:3, col:12> 'std::suspend_always':'std::suspend_always'
    |           |-MemberExpr 0x55dcfa09eea8 <col:3> '<bound member function type>' .yield_value 0x55dcfa094220
    |           | `-DeclRefExpr 0x55dcfa09ee88 <col:3> 'std::coroutine_traits<Chat, int>::promise_type':'Chat::promise_type' lvalue Var 0x55dcfa09d218 '__promise' 'std::coroutine_traits<Chat, int>::promise_type':'Chat::promise_type'
    |           `-ImplicitCastExpr 0x55dcfa09ef00 <col:12> 'int' <LValueToRValue>
    |             `-DeclRefExpr 0x55dcfa09a8e8 <col:12> 'int' lvalue ParmVar 0x55dcfa09a6c0 'sss' 'int'
    |-CXXMemberCallExpr 0x55dcfa09f160 <col:3> 'void'
    | |-MemberExpr 0x55dcfa09f130 <col:3> '<bound member function type>' .await_suspend 0x55dcfa091ad8
    | | `-OpaqueValueExpr 0x55dcfa09ef70 <col:3, col:12> 'std::suspend_always':'std::suspend_always' lvalue
    | |   `-MaterializeTemporaryExpr 0x55dcfa09ef58 <col:3, col:12> 'std::suspend_always':'std::suspend_always' lvalue
    | |     `-CXXMemberCallExpr 0x55dcfa09eed8 <col:3, col:12> 'std::suspend_always':'std::suspend_always'
    | |       |-MemberExpr 0x55dcfa09eea8 <col:3> '<bound member function type>' .yield_value 0x55dcfa094220
    | |       | `-DeclRefExpr 0x55dcfa09ee88 <col:3> 'std::coroutine_traits<Chat, int>::promise_type':'Chat::promise_type' lvalue Var 0x55dcfa09d218 '__promise' 'std::coroutine_traits<Chat, int>::promise_type':'Chat::promise_type'
    | |       `-ImplicitCastExpr 0x55dcfa09ef00 <col:12> 'int' <LValueToRValue>
    | |         `-DeclRefExpr 0x55dcfa09a8e8 <col:12> 'int' lvalue ParmVar 0x55dcfa09a6c0 'sss' 'int'
    | `-ImplicitCastExpr 0x55dcfa09f218 <col:3> 'coroutine_handle<>':'std::coroutine_handle<void>' <ConstructorConversion>
    |   `-CXXConstructExpr 0x55dcfa09f1e8 <col:3> 'coroutine_handle<>':'std::coroutine_handle<void>' 'void (coroutine_handle<promise_type>) noexcept'
    |     `-CallExpr 0x55dcfa09f0d0 <col:3> 'coroutine_handle<promise_type>':'std::coroutine_handle<Chat::promise_type>'
    |       |-ImplicitCastExpr 0x55dcfa09f0b8 <col:3> 'coroutine_handle<promise_type> (*)(void *) noexcept' <FunctionToPointerDecay>
    |       | `-DeclRefExpr 0x55dcfa09f098 <col:3> 'coroutine_handle<promise_type> (void *) noexcept' lvalue CXXMethod 0x55dcfa096d98 'from_address' 'coroutine_handle<promise_type> (void *) noexcept'
    |       `-CallExpr 0x55dcfa09f078 <col:3> 'void *'
    |         `-ImplicitCastExpr 0x55dcfa09f060 <col:3> 'void *(*)() noexcept' <FunctionToPointerDecay>
    |           `-DeclRefExpr 0x55dcfa09f040 <col:3> 'void *() noexcept' lvalue Function 0x55dcfa09dc88 '__builtin_coro_frame' 'void *() noexcept'
    `-CXXMemberCallExpr 0x55dcfa09f260 <col:3> 'void'
      `-MemberExpr 0x55dcfa09f230 <col:3> '<bound member function type>' .await_resume 0x55dcfa091bf8
        `-OpaqueValueExpr 0x55dcfa09ef70 <col:3, col:12> 'std::suspend_always':'std::suspend_always' lvalue
          `-MaterializeTemporaryExpr 0x55dcfa09ef58 <col:3, col:12> 'std::suspend_always':'std::suspend_always' lvalue
            `-CXXMemberCallExpr 0x55dcfa09eed8 <col:3, col:12> 'std::suspend_always':'std::suspend_always'
              |-MemberExpr 0x55dcfa09eea8 <col:3> '<bound member function type>' .yield_value 0x55dcfa094220
              | `-DeclRefExpr 0x55dcfa09ee88 <col:3> 'std::coroutine_traits<Chat, int>::promise_type':'Chat::promise_type' lvalue Var 0x55dcfa09d218 '__promise' 'std::coroutine_traits<Chat, int>::promise_type':'Chat::promise_type'
              `-ImplicitCastExpr 0x55dcfa09ef00 <col:12> 'int' <LValueToRValue>
                `-DeclRefExpr 0x55dcfa09a8e8 <col:12> 'int' lvalue ParmVar 0x55dcfa09a6c0 'sss' 'int'

Note that `CXXMemberCallExpr 0x55dcfa09f260 <col:3>` cannot get end loc because no arg exists (but covered by its base).

3. Use `Base` end loc instead of `Loc` if no args: `auto EndLoc = Args.empty() ? Base->getEndLoc() : Args.back()->getEndLoc();`

  ExprWithCleanups 0x5650003822c8 <line:68:3, col:12> 'void'
  `-CoyieldExpr 0x565000382280 <col:3, col:12> 'void'
    |-CXXMemberCallExpr 0x565000381ed8 <col:3, col:12> 'std::suspend_always':'std::suspend_always'
    | |-MemberExpr 0x565000381ea8 <col:3> '<bound member function type>' .yield_value 0x565000377220
    | | `-DeclRefExpr 0x565000381e88 <col:3> 'std::coroutine_traits<Chat, int>::promise_type':'Chat::promise_type' ...
    | `-ImplicitCastExpr 0x565000381f00 <col:12> 'int' <LValueToRValue>
    |   `-DeclRefExpr 0x56500037d8e8 <col:12> 'int' lvalue ParmVar 0x56500037d6c0 'sss' 'int'
    |-MaterializeTemporaryExpr 0x565000381f58 <col:3, col:12> 'std::suspend_always':'std::suspend_always' lvalue
    | `-CXXMemberCallExpr 0x565000381ed8 <col:3, col:12> 'std::suspend_always':'std::suspend_always'
    |   |-MemberExpr 0x565000381ea8 <col:3> '<bound member function type>' .yield_value 0x565000377220
    |   | `-DeclRefExpr 0x565000381e88 <col:3> 'std::coroutine_traits<Chat, int>::promise_type':'Chat::promise_type' ...
    |   `-ImplicitCastExpr 0x565000381f00 <col:12> 'int' <LValueToRValue>
    |     `-DeclRefExpr 0x56500037d8e8 <col:12> 'int' lvalue ParmVar 0x56500037d6c0 'sss' 'int'
    |-ExprWithCleanups 0x565000381fd8 <col:3, col:12> 'bool'
    | `-CXXMemberCallExpr 0x565000381fb8 <col:3, col:12> 'bool'
    |   `-MemberExpr 0x565000381f88 <col:3> '<bound member function type>' .await_ready 0x565000374858
    |     `-OpaqueValueExpr 0x565000381f70 <col:3, col:12> 'std::suspend_always':'std::suspend_always' lvalue
    |       `-MaterializeTemporaryExpr 0x565000381f58 <col:3, col:12> 'std::suspend_always':'std::suspend_always' lvalue
    |         `-CXXMemberCallExpr 0x565000381ed8 <col:3, col:12> 'std::suspend_always':'std::suspend_always'
    |           |-MemberExpr 0x565000381ea8 <col:3> '<bound member function type>' .yield_value 0x565000377220
    |           | `-DeclRefExpr 0x565000381e88 <col:3> 'std::coroutine_traits<Chat, int>::promise_type':'Chat::promise_type' ...
    |           `-ImplicitCastExpr 0x565000381f00 <col:12> 'int' <LValueToRValue>
    |             `-DeclRefExpr 0x56500037d8e8 <col:12> 'int' lvalue ParmVar 0x56500037d6c0 'sss' 'int'
    |-CXXMemberCallExpr 0x565000382160 <col:3> 'void'
    | |-MemberExpr 0x565000382130 <col:3> '<bound member function type>' .await_suspend 0x565000374ad8
    | | `-OpaqueValueExpr 0x565000381f70 <col:3, col:12> 'std::suspend_always':'std::suspend_always' lvalue
    | |   `-MaterializeTemporaryExpr 0x565000381f58 <col:3, col:12> 'std::suspend_always':'std::suspend_always' lvalue
    | |     `-CXXMemberCallExpr 0x565000381ed8 <col:3, col:12> 'std::suspend_always':'std::suspend_always'
    | |       |-MemberExpr 0x565000381ea8 <col:3> '<bound member function type>' .yield_value 0x565000377220
    | |       | `-DeclRefExpr 0x565000381e88 <col:3> 'std::coroutine_traits<Chat, int>::promise_type':'Chat::promise_type' ...
    | |       `-ImplicitCastExpr 0x565000381f00 <col:12> 'int' <LValueToRValue>
    | |         `-DeclRefExpr 0x56500037d8e8 <col:12> 'int' lvalue ParmVar 0x56500037d6c0 'sss' 'int'
    | `-ImplicitCastExpr 0x565000382218 <col:3> 'coroutine_handle<>':'std::coroutine_handle<void>' <ConstructorConversion>
    |   `-CXXConstructExpr 0x5650003821e8 <col:3> 'coroutine_handle<>':'std::coroutine_handle<void>' 'void (coroutine_handle<promise_type>) noexcept'
    |     `-CallExpr 0x5650003820d0 <col:3> 'coroutine_handle<promise_type>':'std::coroutine_handle<Chat::promise_type>'
    |       |-ImplicitCastExpr 0x5650003820b8 <col:3> 'coroutine_handle<promise_type> (*)(void *) noexcept' <FunctionToPointerDecay>
    |       | `-DeclRefExpr 0x565000382098 <col:3> 'coroutine_handle<promise_type> (void *) noexcept' lvalue CXXMethod 0x565000379d98 'from_address' ...
    |       `-CallExpr 0x565000382078 <col:3> 'void *'
    |         `-ImplicitCastExpr 0x565000382060 <col:3> 'void *(*)() noexcept' <FunctionToPointerDecay>
    |           `-DeclRefExpr 0x565000382040 <col:3> 'void *() noexcept' lvalue Function 0x565000380c88 '__builtin_coro_frame' 'void *() noexcept'
    `-CXXMemberCallExpr 0x565000382260 <col:3, col:12> 'void'
      `-MemberExpr 0x565000382230 <col:3> '<bound member function type>' .await_resume 0x565000374bf8
        `-OpaqueValueExpr 0x565000381f70 <col:3, col:12> 'std::suspend_always':'std::suspend_always' lvalue
          `-MaterializeTemporaryExpr 0x565000381f58 <col:3, col:12> 'std::suspend_always':'std::suspend_always' lvalue
            `-CXXMemberCallExpr 0x565000381ed8 <col:3, col:12> 'std::suspend_always':'std::suspend_always'
              |-MemberExpr 0x565000381ea8 <col:3> '<bound member function type>' .yield_value 0x565000377220
              | `-DeclRefExpr 0x565000381e88 <col:3> 'std::coroutine_traits<Chat, int>::promise_type':'Chat::promise_type' lvalue Var 0x565000380218 '__promise' ...
              `-ImplicitCastExpr 0x565000381f00 <col:12> 'int' <LValueToRValue>
                `-DeclRefExpr 0x56500037d8e8 <col:12> 'int' lvalue ParmVar 0x56500037d6c0 'sss' 'int'

This is better, but `CXXMemberCallExpr 0x565000382160 <col:3> 'void'` still cannot get proper end loc, its base spans `<col:3, col:12>`, arg also exists but this arg is irrevelant.

It's really hard to tell which is correct or not.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D157296/new/

https://reviews.llvm.org/D157296



More information about the cfe-commits mailing list