[cfe-dev] ParamDecls missing from function DeclContext

Douglas Gregor dgregor at apple.com
Mon May 21 16:37:54 PDT 2012

On May 21, 2012, at 4:36 PM, John McCall <rjmccall at apple.com> wrote:

> On May 21, 2012, at 4:27 PM, Douglas Gregor wrote:
>> On May 21, 2012, at 11:46 AM, Richard Smith <richard at metafoo.co.uk> wrote:
>>> On Mon, May 21, 2012 at 11:03 AM, Douglas Gregor <dgregor at apple.com> wrote:
>>> On May 16, 2012, at 10:49 AM, Abramo Bagnara <abramo.bagnara at gmail.com> wrote:
>>> > Il 16/05/2012 17:57, Douglas Gregor ha scritto:
>>> >>
>>> >>>>
>>> >>>>> That said, the invariant that the decls list on a DeclContext is
>>> >>>>> exactly the list of Decls which have that DC as their lexical context
>>> >>>>> would be useful. In particular, it could be useful for some clients to
>>> >>>>> guarantee that traversing Decls by recursively iterating all lexical
>>> >>>>> decls in all DCs would, in fact, reach all Decls.
>>> >>>>
>>> >>>> Okay, I agree that this is a useful general invariant.
>>> >>>
>>> >>> Everything is very nice in this way and we'd love to do in this way, but
>>> >>> this contrasts with
>>> >>>
>>> >>>>> Abramo wrote:
>>> >>>>> Also if I don't have any problem with this I'd like to understand why
>>> >>>>> you think that FunctionTypeLoc should not have a pointer to a
>>> >>>>> DeclContext where the args are registered (that for FunctionDecl
>>> >>>>> function type is the very same FunctionDecl).
>>> >>>
>>> >>>> Doug answer:
>>> >>>> I'd rather not spend any storage on a DeclContext* in the FunctionTypeLoc.
>>> >>>
>>> >>> Suppose we have:
>>> >>> typedef int f(int x);
>>> >>>
>>> >>> We should assign to int x a lexical DeclContext, suppose we choose to
>>> >>> assign it to the TranslationUnit... then to satisfy the invariant above
>>> >>> we should insert the ParmVarDecl in the TranslationUnit.
>>> >>>
>>> >>> I really doubt this is sane choice... what happens to all visitors of
>>> >>> DeclContext when they encounter these ParmVarDecl (that I'd say are
>>> >>> definitely "misplaced"...)
>>> >>
>>> >>
>>> >> The C(++) languages don't actually place such declarations in any
>>> >> particular context, so it's not clear where they belong in the AST.
>>> >> Introducing some kind of abstract function declaration that is the
>>> >> DeclContext might conceivably work, but that's a rather heavyweight
>>> >> solution just to maintain an invariant. Using FunctionTypeLoc doesn't
>>> >> really work, because DeclContexts are supposed to be Decls.
>>> >
>>> > Just to be clear, I was not thinking to transform FunctionTypeLoc in a
>>> > DeclContext, but to put a DeclContext* in FunctionTypeLoc data.
>>> >
>>> > This pointer points to FunctionDecl itself when the FunctionTypeLoc is
>>> > the type of a FunctionDecl, otherwise it points to a specific class
>>> > derived from DeclContext (FunctionTypeDeclContext?) that contains only
>>> > the ParmVarDecl's.
>>> In the FunctionDecl case, we don't actually need this pointer because it is available in the ParmVarDecls. Can we optimize it away?
>>> >> Personally, I'm fine with having parameters in the lexical
>>> >> DeclContext of the translation unit for this case, but we can investigate other designs.
>>> >
>>> > How you would skip them?
>>> isa<ParmVarDecl>?
>>> > What about template instantiation of these? Everything would be added to
>>> > TranslationUnit?
>>> I guess so.
>>> > Perhaps I'm the only to feel this way, but to add Decls to contexts
>>> > where they don't belong sincerely appears like a little mess to me...
>>> I agree that it feels a little messy, but we're discussing increasing Clang's memory footprint to meet an invariant that we've never needed before. Make it cheap or make it important and it becomes obvious that it's worth doing.
>>> It's not completely clear to me what invariant a FunctionTypeDeclContext would help with.
>> I think the intent is that the FunctionTypeDeclContext be the context used for parameters in a function type that is *not* directly the type of a function or function template declaration. One could then iterate over the lexical declarations in the FunctionTypeDeclContext to get the ParmVarDecls in that function type.
> Does even this give us a reasonable AST?  Okay, great, the FunctionTypeDeclContext is the semantic context of these declarations.  And its parent context is... the translation unit?
> I think the truth is that parameters of abstract function types are a weird exception, because they're actually only declarations grammatically;  they don't really declare anything.  I would rather give them *no* decl context than give them some pretend one.  This is also a much easier invariant to maintain:  a ParmVarDecl has a DC if and only if it declares a parameter of an actual function declaration.

The translation unit is a safer form of "no decl context", given that we assume throughout the frontend that Decl::getDeclContext() returns non-NULL. I guess we could invent some other sentinel DeclContext for this purpose.

	- Doug

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20120521/7422151a/attachment.html>

More information about the cfe-dev mailing list