[RFH] C++ FE question

Josh Conner jconner@apple.com
Sat Sep 3 02:40:00 GMT 2005


I've been looking at PR23708, where a non-inline explicitly  
specialized template function is inheriting the inline semantics of  
the inline member function it specializes, when using pre-compiled  
headers (whew).  This can be seen in the following example:

     template <class T> class simple_class {
       public:
         inline void testfn (T);
     };

     template <> void simple_class<int>::testfn (int) {}  //  
incorrectly inheriting 'inline' semantics when using PCH

Where the specialization function ends up in a COMDAT section.

I have some understanding on why this is happening, but could use a  
little help in fixing the problem.  If I compile the example above  
into a precompiled header, the sequence of events is as follows:

   simple_class<T>::testfn is generated
   simple_class<T>::testfn is assigned to the COMDAT section by  
note_decl_for_pch()
   simple_class<int>::testfn (implicit instantiation) is generated,  
which inherits the COMDAT-ness from simple_class<T>::testfn
   simple_class<int>::testfn (explicit specialization) is generated
   simple_class<int>::testfn (explicit specialization) is assigned to  
the COMDAT section by duplicate_decls(), when it merges the  
declarations with the implicit instantiation

When not using precompiled headers, the sequence is this:

   simple_class<T>::testfn is generated
   simple_class<int>::testfn (implicit) is generated
   simple_class<int>::testfn (explicit) is generated
   simple_class<T>::testfn is assigned to the COMDAT section
   simple_class<int>::testfn (implicit) is assigned to the COMDAT  
section

My first approach was to modify duplicate_decls() so it wouldn't copy  
the COMDAT-ness into the explicit specialization, the same way that  
we avoid copying the DECL_DECLARED_INLINE_P.  This worked for my  
particular instance, however because COMDAT implementation is host- 
dependent, it seems very dangerous.

My second approach is to disable the code in note_decl_for_pch() that  
assigns COMDAT-ness early.  This works, too, but it would be nice to  
not lose the advantage that this code was put in for.

So, my third approach was to modify note_decl_for_pch() to filter out  
simple_class<T>::testfn, similarly to how the implicit <int>  
declaration is filtered out.  However, in order to do so, I need to  
detect that simple_class<T>::testfn is a member function of a  
template class.  But how do I do this?  I can detect which class the  
function is a member of by looking at DECL_CONTEXT, but I don't see  
how to determine if this class is a template class.  Is there a way  
to find the class type tree from the FUNCTION_DECL?  I can get see  
the type information I want at DECL_CONTEXT(decl)->common.chain in  
the debugger, but I have no reason to believe that this is the  
correct way to get it, or that it will work all of the time.

Does anyone have any suggestions on:
a) whether I'm headed in the right direction, and
b) if so, how to determine that simple_class<T>::testfn is a member  
of a template class, and not an instantiated class?

Thanks -

Josh



More information about the Gcc mailing list