[cfe-dev] Lambda expr AST representation

Eli Friedman eli.friedman at gmail.com
Thu Oct 4 11:23:19 PDT 2012


On Thu, Oct 4, 2012 at 4:05 AM, Abramo Bagnara
<abramo.bagnara at bugseng.com> wrote:
>
> Despite what is written in C++11 5.1.2p7:
>
> The lambda-expression’s compound-statement yields the function-body
> (8.4) of the function call operator, but for purposes of name lookup
> (3.4), determining the type and value of this (9.3.2) and transforming
> id-expressions referring to non-static class members into class member
> access expressions using (*this) (9.3.1), the compound-statement is
> considered in the context of the lambda-expression.
>
> currently clang in its AST insert DeclRefExpr instead of correct
> MemberExpr, as the following typescript shows:
>
> $ cat p.cc
> int f(int a) {
>   return [a]()->int { return a; }();
> }
> $ _clang++ -cc1 -ast-dump -std=c++0x p.cc
> typedef __int128 __int128_t;
> typedef unsigned __int128 __uint128_t;
> typedef __va_list_tag __builtin_va_list[1];
> int f(int a) (CompoundStmt 0x4629a50 <p.cc:1:14, line:3:1>
>   (ReturnStmt 0x4629a30 <line:2:3, col:35>
>     (CXXOperatorCallExpr 0x46299b0 <col:10, col:35> 'int'
>       (ImplicitCastExpr 0x4629998 <col:34, col:35> 'auto (*)(void) const
> -> int' <FunctionToPointerDecay>
>         (DeclRefExpr 0x4629910 <col:34, col:35> 'auto (void) const ->
> int' lvalue CXXMethod 0x4629580 'operator()' 'auto (void) const -> int'))
>       (ImplicitCastExpr 0x4629a18 <col:10, col:33> 'const class <lambda
> at p.cc:2:10>' <NoOp>
>         (LambdaExpr 0x4629748 <col:10, col:33> 'class <lambda at p.cc:2:10>'
>           (ImplicitCastExpr 0x46296b0 <col:11> 'int' <LValueToRValue>
>             (DeclRefExpr 0x4629688 <col:11> 'int' lvalue ParmVar
> 0x45fbf00 'a' 'int'))
>           (CompoundStmt 0x4629728 <col:21, col:33>
>             (ReturnStmt 0x4629708 <col:23, col:30>
>               (ImplicitCastExpr 0x46296f0 <col:30> 'int' <LValueToRValue>
>                 (DeclRefExpr 0x46296c8 <col:30> 'const int' lvalue
> ParmVar 0x45fbf00 'a' 'int')))))))))
>
> Although I'm aware that these DeclRefExpr are handled especially in
> CodeGen I think that this behavior should be considered a defect of AST.

Despite the reference to "transforming id-expressions" in the
standard, the ASTs were intentionally designed the way they are
because an expression in a lambda acts more like a reference to the
original variable in terms of semantic analysis than some sort of
member reference expression.  The alternative involves some entirely
new AST nodes to keep around the relevant semantic information, and
from my perspective that would just bloat the AST without any
substantial benefit.

> Also, I've noted that lambda class fields generated for captured
> variables are anonymous instead to have the name of the captured variable.

That's what the standard says, sorry.

-Eli




More information about the cfe-dev mailing list