[cfe-dev] PATCH: C++ Function Overloading (v2)

Doug Gregor doug.gregor at gmail.com
Wed Oct 22 08:20:51 PDT 2008

Hi Argiris,

On Tue, Oct 21, 2008 at 3:51 PM, Argiris Kirtzidis <akyrtzi at gmail.com> wrote:
> With "defeats the purpose" I mean that OverloadedFunctionDecl would be most
> useful if it was shared ('f' gets overloaded so 'f' gets replaced and the
> AST refers to this OverloadedFunctionDecl from now on), but, instead, each
> expression gets its own OverloadedFunctionDecl object.

Ah, understood.

> So what is the advantage of using
> - CallExpr -> DeclRefExpr -> OverloadedFunctionDecl (unique for this
> expression)
> instead of
> - CallExpr -> OverloadedFunctionExpr
> ?
> The second avoids the ownership issues of the first (plus it's a bit more
> compact).

The advantage of the first is that name lookup has something it can
return when it finds a set of overloaded functions. Name lookup is
going to find a Decl of some sort, and when that Decl is really a set
of overloaded function declarations, we need a Decl to represent it.
Hence, we have OverloadedFunctionDecl to refer to those declarations.

OverloadedFunctionExpr can serve as an expression that refers to a set
of overloaded functions, but it can't help tell Sema that the lookup
of a name returned a set of overloaded functions.

That issue is separable from the representation of
OverloadedFunctionDecl. In that case, I completely agree that it would
be better to have a DeclContext* + IdentifierInfo* representation, but
IIUC we don't yet have the ability to do that. That's probably because
I have yet to review your qualified-id parsing patch (sorry).

> Another related question:
> I assume that all FunctionDecls that would be found via ADL in the template
> definition context will also be found via ADL in the template instantiation
> context, is this correct ?

Yes, for a non-exported template. With an exported template, the
template definition is in a different translation unit, so it could
see different FunctionDecls.

> And consider another way that having OverloadedFunctionDecl complicates
> things:
> namespace A {
>  void f(int); #1
> }
> void f(char); #2
> void g() {
>  using namespace A; #3
>  f(0);
> }
> #4
> At #3, 'f' becomes an overloaded function (#1 and #2)
> At #4, 'f' is not an overloaded function.
> If an OverloadedFunctionDecl is created at #3, then it should be reverted
> for #4.
> Much simpler is to just inquire the IdentifierResolver about the set of
> overloaded functions at each context, and avoid any OverloadedFunctionDecl
> manipulation.

As it stands, the OverloadedFunctionDecls are managed by the
Sema::PushOnScopeChains, which creates or updates the
OverloadedFunctionDecl as functions are added into the scope. That
would likely mean that the lookup of "f" after #3 would create a new
OverloadedFunctionDecl... but there's no sense in arguing this point,
because I think we agree on the representation issue already. It's the
OverloadedFunctionExpr vs. OverloadedFunctionDecl question that

  - Doug

More information about the cfe-dev mailing list