<div dir="ltr">Hello Richard,<div><br></div><div>I tried your suggestion but I get the following error when the method <i>AddInitializerToDecl </i>is invoked on the <i>FieldDecl </i>:</div><div><div><b>test3.cpp:32:9: error: illegal initializer (only variables can be initialized)</b></div>
<div><b></b></div></div><div><br></div><div>My code does the following :</div><div><br></div><div><b>class MyClass </b></div><div><b>{</b></div><div><b> MyOtherClass myVar {"StringToModify"};</b></div><div>
<b>}</b></div><div><br></div><div>In the mean time, I found a solution without a TreeTransform. My initial problem (wrong const char array length) is solved by setting a new type on the StringLiteral. </div><div><br></div>
<div>However, if you have any idea on how to get this working with a TreeTransform, I am willing to try. </div><div><br></div><div>Thanks</div><div><br></div></div><div class="gmail_extra"><br><br><div class="gmail_quote">
On Fri, May 30, 2014 at 6:32 PM, Richard Smith <span dir="ltr"><<a href="mailto:richard@metafoo.co.uk" target="_blank">richard@metafoo.co.uk</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div><div class="h5">On Fri, May 30, 2014 at 10:52 AM, Timothée Vandeput <span dir="ltr"><<a href="mailto:timothee.vandeput@gmail.com" target="_blank">timothee.vandeput@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Hello Richard,<div><br></div><div class="gmail_extra"><div class="gmail_quote"><div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<div dir="ltr"><div class="gmail_extra">
<div class="gmail_quote"><div><i>The AST is neither designed nor intended to support in-place modification -- it's supposed to be essentially immutable once created. TreeTransform is a better approach (since it creates new AST rather than updating existing AST nodes in-place).</i></div>
</div></div></div></blockquote><div><br></div></div><div>This is what I have been reading here on previous messages, hence our attempt to use TreeTransform.</div><div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div></div><div><i>In your overridden TransformStringLiteral, how are you creating the new StringLiteral? We don't seem to have any relevant functions on Sema for this, so I think you'd need to compute the relevant type yourself and call StringLiteral::Create.</i></div>
</div></div></div>
</blockquote></div></div><div class="gmail_extra"><br></div><div class="gmail_extra">This is what we tried, here is the code snippet of our TreeTransform class :</div><div class="gmail_extra"><br></div><div class="gmail_extra">
<div class="gmail_extra"><div class="gmail_extra"><b>class HmIdTransform : public TreeTransform<HmIdTransform></b></div><div class="gmail_extra"><b>{</b></div></div></div></div><div class="gmail_extra"><div class="gmail_extra">
<div class="gmail_extra"><div class="gmail_extra"><b><span style="white-space:pre-wrap"> </span>Sema& m_Sema;</b></div></div></div></div><div class="gmail_extra"><div class="gmail_extra"><div class="gmail_extra">
<div class="gmail_extra">
<b><span style="white-space:pre-wrap"> </span>ASTContext& m_Context;</b></div><div class="gmail_extra"><b><span style="white-space:pre-wrap"> </span>std::string m_NewString;</b><br></div><div class="gmail_extra">
<b><br></b></div><div class="gmail_extra"><b>public:</b></div><div class="gmail_extra"><b><span style="white-space:pre-wrap"> </span>HmIdTransform(Sema& semaRef, std::string newString)</b></div><div class="gmail_extra">
<b><span style="white-space:pre-wrap"> </span>: TreeTransform(semaRef)</b></div><div class="gmail_extra"><b><span style="white-space:pre-wrap"> </span>, m_Sema(semaRef)</b></div><div class="gmail_extra"><b><span style="white-space:pre-wrap"> </span>, m_Context(semaRef.getASTContext())</b></div>
<div class="gmail_extra"><b><span style="white-space:pre-wrap"> </span>, m_NewString(newString)</b></div><div class="gmail_extra"><b><span style="white-space:pre-wrap"> </span>{</b></div><div class="gmail_extra">
<b><br></b></div><div class="gmail_extra"><b><span style="white-space:pre-wrap"> </span>}</b></div><div class="gmail_extra"><b><br></b></div><div class="gmail_extra"><b><span style="white-space:pre-wrap"> </span>bool AlwaysRebuild() { return true; }</b></div>
<div class="gmail_extra"><b><br></b></div><div class="gmail_extra"><b><span style="white-space:pre-wrap"> </span>ExprResult TransformStringLiteral(StringLiteral* strLiteral)</b></div><div class="gmail_extra"><b><span style="white-space:pre-wrap"> </span>{</b></div>
<div class="gmail_extra"><b><span style="white-space:pre-wrap"> </span>QualType StrType = m_Context.getConstantArrayType(m_Context.CharTy, llvm::APInt(32, m_NewString.size() + 1), ArrayType::Normal, 0);</b></div><div class="gmail_extra">
<b><br></b></div><div class="gmail_extra"><b><span style="white-space:pre-wrap"> </span>return m_Sema.Owned(StringLiteral::Create(m_Context, m_NewString, StringLiteral::Ascii, false, StrType, strLiteral->getLocStart()));</b></div>
<div class="gmail_extra"><b><span style="white-space:pre-wrap"> </span>}</b></div><div class="gmail_extra"><b>};</b></div></div></div><div class="gmail_extra">
<br></div><div class="gmail_extra">Here is an extract of our RecursiveASTVisitor::TraverseFieldDecl method :</div><div class="gmail_extra"><br></div><div class="gmail_extra"><div class="gmail_extra"><div class="gmail_extra">
<span style="white-space:pre-wrap"><b>bool TraverseFieldDecl(FieldDecl* decl)</b></span></div><div class="gmail_extra"><span style="white-space:pre-wrap"><b>{</b></span></div><div class="gmail_extra"><b><span style="white-space:pre-wrap"> </span>if(decl->hasInClassInitializer())</b><br>
</div><div class="gmail_extra"><b><span style="white-space:pre-wrap"> </span>{</b><br></div><div class="gmail_extra"><b><span style="white-space:pre-wrap"> </span>Expr* initializer = decl->getInClassInitializer();</b></div>
<div class="gmail_extra"><b><span style="white-space:pre-wrap"><br></span></b></div><div class="gmail_extra"><b><span style="white-space:pre-wrap"> </span>if(initializer && initializer->children())</b><br>
</div><div class="gmail_extra"><b><span style="white-space:pre-wrap"> </span>{</b></div><div class="gmail_extra"><b><span style="white-space:pre-wrap"> </span>HmIdTransform initTransform(m_CI.getSema(), "ModifiedString");</b><br>
</div><div class="gmail_extra"><span style="white-space:pre-wrap"><b><br></b></span></div><div class="gmail_extra"><b><span style="white-space:pre-wrap"> </span>initTransform.TransformInitializer(initializer, true);</b></div>
</div></div></div></div></blockquote><div><br></div></div></div><div>This returns the transformed initializer; you need to do something with the result. (This, too, will require modifying the AST, so it's not a particularly safe operation.)</div>
<div><br></div><div>I'm not sure if this will be sufficient, but you could try:</div><div><br></div><div>decl->removeInClassInitializer();</div><div>SemaRef.AddInitializerToDecl(decl, /*result of transform*/, false, false);</div>
<div class="">
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_extra"><div class="gmail_extra">
<div class="gmail_extra"><b><span style="white-space:pre-wrap"> </span>}</b><br></div><div class="gmail_extra"><b><span style="white-space:pre-wrap"> </span>}</b></div><div class="gmail_extra"><br></div><div class="gmail_extra">
<b><span style="white-space:pre-wrap"> </span>return true;</b></div><div class="gmail_extra"><span style="white-space:pre-wrap"><b>}</b></span></div></div></div><div class="gmail_extra"><br></div><div class="gmail_extra">
Now, it seems the node doesn't get rebuild, do we have to invoke a method to rebuild the modified node?</div>
<div class="gmail_extra">I though the TreeTransform would do it (knowing that it has a reference to the Sema) but I guess I am mistaken. </div><div class="gmail_extra"><br></div><div class="gmail_extra">Thanks for your help !</div>
</div></div>
</blockquote></div></div><br></div></div>
</blockquote></div><br></div>