Thanks a lot!<br>Here is what I came up with (I didn't make getInstantiatedFrom a member yet):<br><br>/// getInstantiatedFrom - if the parent of this (FieldDecl* d) is an <br>
/// instanciation of a template class, return the corresponding FieldDecl* of this <br>/// template class. <br>
FieldDecl* getInstantiatedFrom(FieldDecl const * const d) <br>{ <br>
ClassTemplateSpecializationDecl const * const parent = <br> dyn_cast<ClassTemplateSpecializationDecl>(d->getParent()); <br>
<br> // check the parent of this field is an instanciation of a class template <br>
if (!parent || parent->getTemplateSpecializationKind() != TSK_ImplicitInstantiation) <br> return 0; <br>
<br> CXXRecordDecl const * const generic_parent = <br>
parent->getSpecializedTemplate()->getTemplatedDecl(); <br> assert(generic_parent); <br>
<br> for(CXXRecordDecl::field_iterator f=generic_parent->field_begin(), e=generic_parent->field_end(); f != e; ++f) <br>
{ <br> if ((*f)->getNameAsString() == d->getNameAsString()) <br>
return *f; <br> } <br>
<br> // should never get here <br>
return 0; <br>}<br><br><br>Is it what you had in mind? I would be glad to make it a patch and add some tests it it seems ok.<br>
<br>Adrien <br><br><div class="gmail_quote">On Fri, May 27, 2011 at 23:34, Douglas Gregor <span dir="ltr"><<a href="mailto:dgregor@apple.com">dgregor@apple.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<div><div></div><div class="h5"><br>
On May 27, 2011, at 2:32 PM, Johannes Schaub (litb) wrote:<br>
<br>
> Douglas Gregor wrote:<br>
><br>
>><br>
>> On May 27, 2011, at 10:02 AM, Adrien Chauve wrote:<br>
>><br>
>>> Hi,<br>
>>><br>
>>> Using a RecursiveASTVisitor, I've been trying to rename field names<br>
>>> against some conventions.<br>
>>><br>
>>> Let's say I would like to rename Foo::bar into Foo::m_bar in the<br>
>>> following code:<br>
>>><br>
>>> template<typename T><br>
>>> struct Foo<br>
>>> {<br>
>>> int bar;<br>
>>> };<br>
>>><br>
>>> int main()<br>
>>> {<br>
>>> Foo<double> foo;<br>
>>> foo.bar = 2;<br>
>>><br>
>>> return 1;<br>
>>> }<br>
>>><br>
>>><br>
>>> In my custom visitor, I implement the following method:<br>
>>><br>
>>> bool VisitMemberExpr(MemberExpr* member)<br>
>>> {<br>
>>> ValueDecl* v = member->getMemberDecl(); // FieldDecl or CXXMethodDecl<br>
>>> ...<br>
>>> }<br>
>>><br>
>>> But the FieldDecl I get when visiting the statement corresponding to<br>
>>> "foo.bar=2;" is Foo<double>::bar, but not Foo::bar.<br>
>>><br>
>>> So my question is: is it possible to get the FieldDecl of Foo<T>::bar<br>
>>> from the FieldDecl of Foo<double>::bar ? at least when the struct is not<br>
>>> specialized? What happens when the struct is specialized?<br>
>><br>
>> For fields, this is a pain. You'll actually have to look at the type that<br>
>> owns the field (a ClassTemplateSpecializationDecl), check whether it was<br>
>> instantiated vs. specialized (using getSpecializationKind()) and, if it<br>
>> was instantiated, retrieve the class template from which is was<br>
>> instantiated (getSpecializedTemplate()).<br>
>><br>
><br>
> I was looking into the doxygen documentations, and I couldn't find how to<br>
> proceed from that.<br>
><br>
> How to get the correct field decl of the class template that correspond to<br>
> the field decl of the instantiated specialization? Can one just take the<br>
> std::distance of the field decl iterator for the specialization, and with<br>
> that, index into the field decl iterator of the class template?<br>
<br>
</div></div>That works, or you can use name lookup.<br>
<br>
- Doug<br>
<div><div></div><div class="h5"><br>
_______________________________________________<br>
cfe-dev mailing list<br>
<a href="mailto:cfe-dev@cs.uiuc.edu">cfe-dev@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev</a><br>
</div></div></blockquote></div><br>