[cfe-dev] injecting a member function
Eric Niebler
eric at boostpro.com
Fri Feb 18 00:25:11 PST 2011
On 2/18/2011 2:58 PM, John McCall wrote:
>
> On Feb 17, 2011, at 11:16 PM, Eric Niebler wrote:
>
>> For my work on MS and Borland properties, I need to be able transform
>> post-inc and post-dec expressions like "obj.prop++" into some equivalent
>> expression that uses getter and setter methods. (Prefix ops are simple
>> because they don't require the creation of a temporary to store the
>> result of the expression.)
>>
>> I'm thinking of approaching the problem like this: "obj.prop++" is
>> replaced with "obj.__builtin_postinc_Obj_Prop()", where that member is
>> generated on-demand and injected in the Obj class. The member would
>> essentially be:
>>
>> PropTy Obj::__builtin_postinc_Obj_Prop() {
>> PropTy tmp = this->getProp();
>> this->setProp(tmp + 1);
>> return tmp;
>> }
>>
>> Two questions:
>>
>> 1) Is this the correct approach? Or is there a simpler/easier way?
>> 2) Is there any precedent in clang for this? I'm looking for code I can
>> crib from, or routines I could reuse.
>
> 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)?
> 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.)
For performance sake, we added a bit to Expr to note that a given node
was the result of a rewrite and that the original expression can be
found elsewhere.
<aside>
> 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?
> # The expression whose result the OpaqueValueExpr will be bound to
> (DeclRefExpr "obj" Obj lvalue)
> # The expression to evaluate, expressed in terms of the OVE
> (CXXMemberCallExpr void
> (MemberExpr void(int) .setBase
> (OpaqueValueExpr 0xabcdef Obj lvalue))
> (CXXMemberCallExpr int
> (MemberExpr PropTy() .getBase
> (OpaqueValueExpr 0xabcdef Obj lvalue)))))
I don't yet have a mental model of what this AST represents. I'll go off
and study ConditionalOperator and maybe it'll become clear.
> Hmm. Unfortunately, I'm not sure how to indicate what the result of the
> operation should be.
Heh, that's kinda the problem I'm trying to solve. :-P
--
Eric Niebler
BoostPro Computing
http://www.boostpro.com
More information about the cfe-dev
mailing list