[cfe-dev] injecting a member function
eric at boostpro.com
Fri Feb 18 01:49:06 PST 2011
On 2/18/2011 3:41 PM, John McCall wrote:
> 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.
Ah. That's explains why I didn't see it. I'm on a fork that is a bit
behind your trunk, and we don't have it yet. Forgive me for being a bit
slow on the uptake.
>>> 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).
>> 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.
OK, I'm slowly starting to understand. We were doing a naive rewrite of
"++a.b" to "a.set(a.get()+1)". You're saying that the expression "a"
should not be evaluated more than once, and you're right. OK, back to
the drawing board. :-)
>>> 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)
In practical terms, that means that, when evaluating tmp, evaluate obj
(once), and thereafter all other times tmp is evaluated, just use the
result already computed. And this Just Works wrt lvalues and rvalues.
> 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)
<nod> I think I'm there, finally. Thanks.
More information about the cfe-dev