[cfe-dev] The DeclContext of block-scope function declarations.
Douglas Gregor
dgregor at apple.com
Mon Aug 6 08:21:03 PDT 2012
On Aug 3, 2012, at 11:18 PM, Enea Zaffanella <zaffanella at cs.unipr.it> wrote:
> On 08/01/2012 07:09 PM, Douglas Gregor wrote:
> >
> > On Jul 9, 2012, at 1:57 AM, Enea Zaffanella <zaffanella at cs.unipr.it> wrote:
> >
> >> Consider the following program:
> >>
> >> $ cat block.cc
> >> namespace N {
> >>
> >> void f() {
> >> extern int var; // #1
> >> extern void g(int); // #2
> >> g(var);
> >> }
> >>
> >> class S {
> >> friend void h(); // #3
> >> };
> >>
> >> } // namespace N
> >>
>
> [...]
>
> > This is a longstanding [*] problem in Clang's representation. The
> lexical DeclContext should be the function for #1 and #2, while the
> semantic DeclContext should be the nearest enclosing namespace. Ideally,
> name lookup for redeclarations (but not uses) would then be able to find
> these functions, so that in
> >
> > namespace N {
> > void f() {
> > extern int var; #1
> > }
> >
> > extern int var; // #2
> >
> > void g() {
> > extern int var; // #3
> > }
> > }
> >
> > #1, #2, and #3 would all end up in the same redeclaration chain. That doesn't happen now.
> >
> >
> >
> > - Doug
> >
> > [*] Block-scope function declarations and extern variables predate the introduction of DeclContexts!
>
>
> Summarizing, the declaration of the local extern entity should be:
>
> (a) visible when looked up for redeclaration purposes
> in its lexical context;
>
> (b) visible when looked up for redeclaration purposes
> in its enclosing namespace (i.e., semantic context);
>
> (c) visible when looked up for uses in its lexical context;
>
> (d) *not* visible when looked up for uses in its enclosing
> namespace (i.e., semantic context).
>
>
> Currently, we have (a) and (c), but not (b) nor (d).
>
> By changing the semantic DeclContext to be the nearest enclosing namespace, we will get properties (a) and (b), but we won't obtain properties (c) and (d).
>
> As for (c), maybe
> DeclContext::makeDeclVisibleinContext(NamedDecl*)
> is a viable solution?
Yes.
> And then what about (d)?
>
> Should we use another flag in the Decl::IdentifierNamespace enumeration (e.g., IDNS_LocalExtern) mimicking what was done for IDNS_OrdinaryFriend, but with its own specific visibility rules?
> Are there simpler approaches?
I *think* the best approach is to generalize the idea behind IDNS_OrdinaryFriend, because friends have the same visibility properties as local externs. The new IDNS_OrdinaryHidden (or whatever) would be found be redeclaration lookup for ordinary names, but not by normal name lookup for ordinary names.
- Doug
More information about the cfe-dev
mailing list