[cfe-dev] PATCH: C++ Function Overloading (v2)
Argiris Kirtzidis
akyrtzi at gmail.com
Tue Oct 21 06:35:06 PDT 2008
Doug Gregor wrote:
> We certainly need some way to represent the notion of an expression
> that refers to an overloaded function; that's a basic notion in C++,
> because name lookup can return a set of overloaded functions. Maybe it
> could be something other than a DeclRefExpr that references an
> OverloadedFunctionDecl.
>
Yes, I question only the use of OverloadedFunctionDecl. Currently,
IdentifierResolver can already provide the set of overloaded functions
so the overhead of OverloadedFunctionDecl is not strictly needed.
>
> Templates will need to store sets of overloaded functions.
>
Even now, with no trace of a template implementation in clang, the use
of OverloadedFunctionDecl is questionable:
-First, consider this example:
void f(char); #1
template<class T> void g(T t)
{
f(t); #2 //dependent
}
void f(int); #3
void h()
{
g(2); #4 //should cause a call of f(int)
}
At #2 'f' does not have any overloads and no OverloadedFunctionDecl
exists, how should this be represented ?
If #2 is regarded as a call to #1, then we miss #3 at instantiation time
(#4) (as specified in C++ 14.6p9).
In order to pickup #3, should we turn 'f' into a OverloadedFunctionDecl,
even if 'f' nevers gets an overload, just because it gets called in a
templated expression ?
-Second, I see no reason why IdentifierResolver can't be made to
eventually work with templates and be used to get the overload set for
'f' at #4 (if it turns out that there are overloads)
> I can think of two kinds of clients that might want or need to deal
> with OverloadedFunctionDecls.
>
> First of all, any clients that are focused on parsing and don't need
> to do much semantic analysis could certainly skip overload resolution,
> and would therefore leave the OverloadedFunctionDecls in place since
> they don't need to be resolved.
>
> Second, clients that want to do some kind of speculative overload
> resolution would need to query the overloads that show up in the
> overload set. For example, an IDE that tries to help with overload
> resolution by showing options while you type. Type "f(17, " and it
> shows you all of the f's that could still be called. This client needs
> to be able to ask the AST or Sema (it's not clear which) which "f"'s
> are available, and then ask Sema which ones are still callable.
>
> None of these require the exact OverloadedFunctionDecl formulation in
> my patch, but they are AST clients to consider.
>
There was a discussion here:
http://lists.cs.uiuc.edu/pipermail/cfe-dev/2008-September/002841.html
about how clients should reason about symbols/identifiers. The consensus
was that Sema builds up a lot of useful semantic information that later
discards. It would be useful to somehow expose semantic information from
Sema and avoid bloating the AST with semantic information (as would be
the case with OverloadedFunctionDecl).
For example, I think that eventually IdentifierResolver will either be
exposed by Sema to clients or a similar construct will be used. By your
example, an IDE usually wants to inquire "I'm in this scope, what can
this identifier mean in this context ? Give me a set of decls." which is
exactly the functionality and purpose of IdentifierResolver.
>
>> How about if a reference of overloaded function "f", results in a
>> OverloadExpr (with OverloadType), that contains the "f" IdentifierInfo and a
>> 'void*' opaque value meant to be used by Sema (or in general, the Action
>> implementation that created the OverloadExpr) ?
>> The advantage of this is that Sema has full control and flexibility over the
>> overload resolution mechanism, e.g. it can change it completely and it will
>> have no impact on the AST or the AST clients.
>>
>
> The representation of the set of overloaded functions doesn't really
> have anything to do with the overload resolution mechanism. Overload
> resolution has to pass over the set of overloaded functions found by
> name lookup and build its own data structures, collect other functions
> found via argument-dependent lookup, etc., so I think it is very
> unlikely even that two different Semas would need different
> representations of the set of overloaded functions.
>
> The disadvantage of having the 'void*' opaque value is that it makes
> ownership harder: how does this void* get deallocated, serialized, or
> de-serialized?
>
I agree, the opaque value definitely complicates things. How about a
OverloadExpr that contains a DeclContext* and an IdentifierInfo* (for
the moment, not sure what exact structure would be needed for templates).
To summarize, my point is that currently OverloadedFunctionDecl is an
unnecessary overhead since IdentifierResolver already can be used to get
the set of overloads. If later on (e.g. for templates), we find out that
IdentifierResolver is not sufficient, we can always add
OverloadedFunctionDecl too. At the moment it makes little sense to have
them since the only expressions that are supposed to reference them (and
not get immediately resolved) are expressions in templates, and there's
a long way ahead before reaching the "template hill" :-)
A bit off-topic:
Currently the iterator abstraction of IdentifierResolver is stretched
thin and will probably snap when more name lookup rules are added. I
lean towards removing the iterator and using a single function that
returns the set of decls based on an identifier.
-Argiris
More information about the cfe-dev
mailing list