[cfe-dev] Function Instantiation: Where? Or is it?

Douglas Gregor dgregor at apple.com
Tue Feb 1 13:37:34 PST 2011

On Feb 1, 2011, at 12:42 PM, Larisse Voufo wrote:

> On Tue, Feb 1, 2011 at 3:01 PM, Douglas Gregor <dgregor at apple.com> wrote:
> On Feb 1, 2011, at 11:45 AM, Larisse Voufo wrote:
>> Let me see if I can rephrase this problem... 
>> At this point, instantiation is no longer an issue. The issue is managing new DeclContext's.
>> Take the following definition of a concept:
>> concept A<typename T> {
>>     void f(int) { }
>> }
>> This definition is parsed into a ConceptDecl  object ContextA where ConceptDecl is a DeclContext as well as a TemplateDecl.
>> When the concept is used on a generic function such as:
>> template<typename T>
>> requires A<T>
>> void func(T a) {
>>     f(a);
>> }
>> at the call f(a),  the lookup process finds the definition of f() in the DeclContext ContextA.  
>> Hence, the definition of func() is accepted. 
>> Let's refer to the found definition as Fn.
>> Now, when func() is used in the main, the lookup and instantiation-related processes are still finding and using that same definition of f(): Fn.
> That's wrong. You need to map from the concept's function f() to the corresponding function f() in the concept map.
> 	- Doug
> Perhaps I should've phrased that this is the sample case I'm examining at the moment, not the defacto way that concepts should work. The idea above should generalize to any DeclContext, whether they are  ConceptDecls or not. 
> For instance, forget concepts, call  "concept A<typename T>" My_DeclContext and replace everything as follows:
> My_DeclContext A {
>     void f(int) { }
> }
> //This definition is parsed into a SomeDecl  object ContextA where SomeDecl is a DeclContext.
> template<...>
> lookup_in (A)
> void func(T a) {
>     f(a);
> }
> Again, the observations from the previous example should naturally translate to this case, and they are the result of an intensive debugging session (overnight)...
> If Fn is found and used throughout the compilation, how come it gets lost at link time? 
> My interest is that: if we can get this to work, then I'll know for sure that I understand the way that lookup and instantiation work in clang, with respect to added declaration contexts. 

Fn is in a concept, so it can't be instantiated without instantiating the concept itself first to produce an instantiated Fn declaration. Then you can go ahead and instantiate the body of the instantiated Fn declaration. Step through how a member function of a class template gets instantiated:

	template<typename T>
	struct A {
		void f(int);

It doesn't make any sense to instantiate A<T>::f(int) without knowing what T is, but that's what you're trying to do with concepts.

> I'm concerned that we are perhaps getting confused from thinking about this problem from completely different perspective. Marcin was also quite ahead of me on this. :) 
> Please, just note that I am not particularly thinking of concepts at the moment... I want to very basically understand why the case above would cause the error I am getting, when the only major change I made was in deviating the lookup process for f() so that it is looked up in ContextA -- using LookupQualifiedName(...), rather than in the global scope...

The change you made means that the function declaration "f" that's being referenced from the instantiation of "func" is still dependent on a template, even though this is non-template code (after instantiation). 

	- Doug
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20110201/fbf46605/attachment.html>

More information about the cfe-dev mailing list