[cfe-dev] Getting the FieldDecl of a template class from a MemberExpr

Douglas Gregor dgregor at apple.com
Mon Jun 6 10:01:33 PDT 2011


Sent from my iPhone

On May 29, 2011, at 9:31 AM, Adrien Chauve <adrien.chauve at gmail.com> wrote:

> Thanks a lot!
> Here is what I came up with (I didn't make getInstantiatedFrom a member yet):
> 
> /// getInstantiatedFrom - if the parent of this (FieldDecl* d) is an                                                                    
> /// instanciation of a template class, return the corresponding FieldDecl* of this                                                      
> /// template class.                                                                                                                     
> FieldDecl* getInstantiatedFrom(FieldDecl const * const d)                                                                               
> {                                                                                                                                       
>     ClassTemplateSpecializationDecl const * const parent =                                                                              
>         dyn_cast<ClassTemplateSpecializationDecl>(d->getParent());                                                                      

CXXRecordDecls themselves can also be instantiations of member classes. There's a getInstantiatedFromMember() function (or something like it) to determine when this is the case. 

>                                                                                                                                         
>     // check the parent of this field is an instanciation of a class template                                                           
>     if (!parent || parent->getTemplateSpecializationKind() != TSK_ImplicitInstantiation)                                                
>         return 0;                                                                                                                      

Explicit instantiations should also be considered here.

>                                                                                                                                         
>     CXXRecordDecl const * const generic_parent =                                                                                        
>         parent->getSpecializedTemplate()->getTemplatedDecl();                                                                           
>     assert(generic_parent);                                                                                                             
>                                                                                                                                         
>     for(CXXRecordDecl::field_iterator f=generic_parent->field_begin(), e=generic_parent->field_end(); f != e; ++f)                      
>     {                                                                                                                                   
>         if ((*f)->getNameAsString() == d->getNameAsString())                                                                            
>             return *f;                                                                                                                  
>     }                                                                                                                                  

DeclContex::lookup() can perform this search faster. 

>                                                                                                                                         
>     // should never get here                                                                                                            
>     return 0;                                                                                                                           
> }
> 
> 
> Is it what you had in mind? I would be glad to make it a patch and add some tests it it seems ok.
> 
> Adrien      
> 
> On Fri, May 27, 2011 at 23:34, Douglas Gregor <dgregor at apple.com> wrote:
> 
> On May 27, 2011, at 2:32 PM, Johannes Schaub (litb) wrote:
> 
> > Douglas Gregor wrote:
> >
> >>
> >> On May 27, 2011, at 10:02 AM, Adrien Chauve wrote:
> >>
> >>> Hi,
> >>>
> >>> Using a RecursiveASTVisitor, I've been trying to rename field names
> >>> against some conventions.
> >>>
> >>> Let's say I would like to rename Foo::bar into Foo::m_bar in the
> >>> following code:
> >>>
> >>> template<typename T>
> >>> struct Foo
> >>> {
> >>>    int bar;
> >>> };
> >>>
> >>> int main()
> >>> {
> >>>    Foo<double> foo;
> >>>    foo.bar = 2;
> >>>
> >>>    return 1;
> >>> }
> >>>
> >>>
> >>> In my custom visitor, I implement the following method:
> >>>
> >>> bool VisitMemberExpr(MemberExpr* member)
> >>> {
> >>>    ValueDecl* v = member->getMemberDecl(); // FieldDecl or CXXMethodDecl
> >>>    ...
> >>> }
> >>>
> >>> But the FieldDecl I get when visiting the statement corresponding to
> >>> "foo.bar=2;" is Foo<double>::bar, but not Foo::bar.
> >>>
> >>> So my question is: is it possible to get the FieldDecl of Foo<T>::bar
> >>> from the FieldDecl of Foo<double>::bar ? at least when the struct is not
> >>> specialized? What happens when the struct is specialized?
> >>
> >> For fields, this is a pain. You'll actually have to look at the type that
> >> owns the field (a ClassTemplateSpecializationDecl), check whether it was
> >> instantiated vs. specialized (using getSpecializationKind()) and, if it
> >> was instantiated, retrieve the class template from which is was
> >> instantiated (getSpecializedTemplate()).
> >>
> >
> > I was looking into the doxygen documentations, and I couldn't find how to
> > proceed from that.
> >
> > How to get the correct field decl of the class template that correspond to
> > the field decl of the instantiated specialization? Can one just take the
> > std::distance of the field decl iterator for the specialization, and with
> > that, index into the field decl iterator of the class template?
> 
> That works, or you can use name lookup.
> 
>        - Doug
> 
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
> 
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20110606/36c4ee98/attachment.html>


More information about the cfe-dev mailing list