[cfe-dev] injecting a member function

John McCall rjmccall at apple.com
Fri Feb 18 00:41:50 PST 2011

On Feb 18, 2011, at 12:25 AM, Eric Niebler wrote:
> On 2/18/2011 2:58 PM, John McCall wrote:
>> I think you want to make some sort of PropertyAccessOperator
>> expression.  It would work basically like BinaryConditionalOperator
> Thanks, John. Do you mean "ConditionalOperator" (which is ternary)?

No, I mean BinaryConditionalOperator, which represents the GNU
omitted-middle-operand ?: extension, and which has similar issues with
a sub-expression that's used in multiple places.  This is new in ToT.

>> does, which is to say, it would bind the result of an expression
>> (the base of the property) to an OpaqueValueExpr, then perform
>> an arbitrary expression using that.  For source fidelity, it would also
>> preserve the original member expression (and RHS, where applicable).
> <aside>
> Regarding that, we abandoned our earlier plan to save original
> expressions directly in the AST via a RewrittenExpr node. It broke to
> much code that was explicitly testing nodes for their StmtClass.
> Instead, the AST contains the rewritten expression, and the original
> expression is stored in a map in the ASTContext, where it's available to
> anybody who's interested. (The mapping is preserved by the AST
> serialization code.)

I don't see how this can work;  the property base needs to be used in
multiple places in the rewritten expression.

>> As a more concrete example, "obj.prop++" would look something like this:
>>  (PropertyAccessOperator int
>>    # The original operand, for source fidelity
>>    (MemberExpr int lvalue property
>>      (DeclRefExpr "obj" Obj lvalue))
>>    # The opaque value expression
>>    (OpaqueValueExpr 0xabcdef Obj lvalue)
> I'm not 100% clear what the purpose of this OpaqueValueExpr is, but
> maybe it will become clear when I study the code. Is it a temporary that
> is storing the result of obj.getProp()? Shouldn't that be represented in
> the AST somehow?

It is represented in the AST:  it's an expression node.  Certain other
expression nodes can bind it to the result of an expression, which can
then be legitimately used in multiple places.  The overall effect is like
a "let" expression in a functional language, where the OVE acts as a
reference to the bound variable.  In functional syntax, my proposal was:
  let tmp = obj in
  tmp.setProp(tmp.getProp() + 1)

The best solution for dealing with the result might actually be to
introduce a *second* OpaqueValueExpr.  In functional terms, this
would be:
  let tmp1 = obj in
  let tmp2 = tmp1.getProp() + 1 in
  (tmp1.setProp(tmp2); tmp2)


More information about the cfe-dev mailing list