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. 