Hi John,

I think that I’ll need a bit more explanation here. The infinite recursion 
occurs while traversing the instantiations of the class template definition and 
I do want to traverse these instantiations. That’s the whole point of my 
proposed change.

By the way, here’s one more bit of information.  The problem does not occur 
when the template is explicitly instantiated:

-----------------------------------------------------------------------------
template<typename Container>
class vector_iterator
{
    template <typename C> friend class vector_iterator;
};

vector_iterator<int> it_int;

template class vector_iterator<int>;
-----------------------------------------------------------------------------
....
  Visiting Decl ClassTemplateSpecialization @0x105046ec0 (vector_iterator) {
    getSpecializationKind() = 4
    Visiting Decl CXXRecord @0x105047190 
(vector_iterator<int>::vector_iterator) {
      "***Implicit declaration ignored***"
    }
    Visiting Decl Friend @0x105047350 () {
      Visiting Decl ClassTemplate @0x105047310 (vector_iterator) {
        Visiting Decl CXXRecord @0x105047280 (vector_iterator) {
        }
        Visiting Decl TemplateTypeParm @0x105047220 
(vector_iterator<int>::<anonymous>) {
        }
      }
    }
  }
}
-----------------------------------------------------------------------------

You see how the friendd...@0x105047350 refers to a ClassTemplate instead of the 
classtemplatespecializat...@0x105046ec0.

Which leads me to wonder even more whether the AST produced when scanning the 
code snippet of my previous example is valid or not ?

- Shouldn’t the AST form a DAG ?
- Are cycles really allowed in the AST ?
- Why would a cycle be necessary when using implicit instantiation and not for 
explicit instantiation ?
- Etc...

I’ll try digging further because I’ll really need this to work.

Benoit

Le 2010-08-30 à 17:30, John McCall a écrit :

On Aug 30, 2010, at 2:27 PM, Benoit Belley wrote:
Thanks for taking the time to review my changes. The following patch should 
address all of your concerns. I have clarified that I want to traverse all of 
the template instantiations (not just the explicit ones).

/// This visitor always recurses in the declarator of explicit
/// template instantiations, such as for example "template class
/// set<int>'. But by default, it will not recurse in the
/// instantiations (implicit or explicit) of the template (function or
/// class) themselves since the instatiated AST isn't written in the
/// source code anywhere. This behavior can be changed by overriding
/// shouldVisitTemplateInstantiations() in the derived class to return
/// true.

Unfortunately, while testing my changes, I have come across an issue and I 
don’t know what the correct solution is. The following code snippet (inspired 
from the Intel TBB header files) demonstrates the issue:


—————————————————
// This is fine.
class A
{
  friend class A;
}

// This class template definiton is also fine...
template<typename Container>
class vector_iterator
{
  template <typename C> friend class vector_iterator;
};

// ... until it gets instantiated.
vector_iterator<int> it_int;
--------------------------------

It will throw the RecursiveASTVisitor in an infinite loop when 
shouldVisitTemplateInstantiations() == true. The attached file tracing.txt 
contains a trace of the visitor in action and points out to cause of the 
problem:

Probably you should only visit the instantiations for the template definition.

John.



Benoit Belley
Sr Principal Developer
M&E-Product Development Group

Autodesk Canada Inc.
10 Rue Duke
Montreal, Quebec  H3C 2L7
Canada

Direct 514 954-7154



[cid:[email protected]]


<<inline: image002.gif>>

_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to