Quantcast

Trouble understand DeclContext

classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Trouble understand DeclContext

Asiri Rathnayake via cfe-dev

Hi,


I'm having trouble understanding the semantics of DeclContext.  The documentation on this class (as of 3.9) refers to "declaration contexts" which it does not define and which does not seem to be a concept from the standard.


How was it determined which classes should inherit DeclContext?  When should a nested DeclContext be added and when is it okay to use an existing DeclContext?


For example, DeclContext cannot correspond directly to declarative regions as defined in [basic.scope.declarative] (3.3.1) because only Decl subtypes inherit it.  A block, for example, is something that opens a new region, and in the AST it is a CompoundStmt, which is not a Decl.


Also, how bad of an idea would it be to change the type hierarchy so more classes inherit DeclContext?


Thanks,

David Fontaine


This email message is for the sole use of the intended recipient(s) and may contain confidential information.  Any unauthorized review, use, disclosure or distribution is prohibited.  If you are not the intended recipient, please contact the sender by reply email and destroy all copies of the original message.


_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Trouble understand DeclContext

Asiri Rathnayake via cfe-dev
2017-02-07 6:08 GMT+07:00 David Fontaine via cfe-dev <[hidden email]>:

Hi,


I'm having trouble understanding the semantics of DeclContext.  The documentation on this class (as of 3.9) refers to "declaration contexts" which it does not define and which does not seem to be a concept from the standard.


How was it determined which classes should inherit DeclContext?  When should a nested DeclContext be added and when is it okay to use an existing DeclContext?


The DeclContext is a declaration that is a container for other declarations. All non-leaf nodes of AST inherit it. If a contained declaration itself can contain other declarations (nested class, method of a class etc), it will be a nested DeclContext.

For example, DeclContext cannot correspond directly to declarative regions as defined in [basic.scope.declarative] (3.3.1) because only Decl subtypes inherit it.  A block, for example, is something that opens a new region, and in the AST it is a CompoundStmt, which is not a Decl.


Declarative regions contained in expressions, like CompoundStmt, are organized using Scope objects. However Scope is a parser notion, and is not represented in AST. 

Also, how bad of an idea would it be to change the type hierarchy so more classes inherit DeclContext?


Thanks,

David Fontaine


This email message is for the sole use of the intended recipient(s) and may contain confidential information.  Any unauthorized review, use, disclosure or distribution is prohibited.  If you are not the intended recipient, please contact the sender by reply email and destroy all copies of the original message.


_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev



_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Trouble understand DeclContext

Asiri Rathnayake via cfe-dev

Thank you Serge.


I was the person asking earlier about named parameter scoping rules in function pointer declarations.  Currently, these declarations are not in the AST.  I would like to add them ​so that they can be referenced by attribute expressions.


"The DeclContext is a declaration that is a container for other declarations. All non-leaf nodes of AST inherit it. If a contained declaration itself can contain other declarations (nested class, method of a class etc), it will be a nested DeclContext."


Based on this, it seems that VarDecl and FieldDecl should also inherit DeclContext, because a function pointer declaration, which may contain named parameters, would be one of those two.  Any opinion on this?



-David



From: Serge Pavlov <[hidden email]>
Sent: Monday, February 6, 2017 6:11 PM
To: David Fontaine
Cc: [hidden email]
Subject: Re: [cfe-dev] Trouble understand DeclContext
 
2017-02-07 6:08 GMT+07:00 David Fontaine via cfe-dev <[hidden email]>:

Hi,


I'm having trouble understanding the semantics of DeclContext.  The documentation on this class (as of 3.9) refers to "declaration contexts" which it does not define and which does not seem to be a concept from the standard.


How was it determined which classes should inherit DeclContext?  When should a nested DeclContext be added and when is it okay to use an existing DeclContext?


The DeclContext is a declaration that is a container for other declarations. All non-leaf nodes of AST inherit it. If a contained declaration itself can contain other declarations (nested class, method of a class etc), it will be a nested DeclContext.

For example, DeclContext cannot correspond directly to declarative regions as defined in [basic.scope.declarative] (3.3.1) because only Decl subtypes inherit it.  A block, for example, is something that opens a new region, and in the AST it is a CompoundStmt, which is not a Decl.


Declarative regions contained in expressions, like CompoundStmt, are organized using Scope objects. However Scope is a parser notion, and is not represented in AST. 

Also, how bad of an idea would it be to change the type hierarchy so more classes inherit DeclContext?


Thanks,

David Fontaine


This email message is for the sole use of the intended recipient(s) and may contain confidential information.  Any unauthorized review, use, disclosure or distribution is prohibited.  If you are not the intended recipient, please contact the sender by reply email and destroy all copies of the original message.


_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev



_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Trouble understand DeclContext

Asiri Rathnayake via cfe-dev
2017-02-07 9:41 GMT+07:00 David Fontaine <[hidden email]>:

"The DeclContext is a declaration that is a container for other declarations. All non-leaf nodes of AST inherit it. If a contained declaration itself can contain other declarations (nested class, method of a class etc), it will be a nested DeclContext."


Based on this, it seems that VarDecl and FieldDecl should also inherit DeclContext, because a function pointer declaration, which may contain named parameters, would be one of those two.  Any opinion on this?

Nor VarDecl neither FieldDecl contain other declarations, so making them DeclContext is not obvious. DeclContext is used in many places including name lookup and such drastic semantic change can require redesign of other compiler components. And what about such case:

int (* (*abc)(long x))(int x);

Two DeclContexts would be needed here.

I would propose you another way, which probably is less invasive. The parameter names are not attributes of VarDecl, it looks more natural to obtained from corresponding function type, which can be obtained:

VarDecl->getType()->getAs<PointerType>()->getPointeeType()->getAs<FunctionProtoType>()

If FunctionProtoType had method `getDecl` as `RecordDecl` has, you could get the parameter declarations from corresponding FunctionDecl. So you need to construct bogus function declaration when parsing function pointer declaration and attach it to the FunctionProtoType. There is however a problem with different declarations for the same type:

void (*pFn)(int x);
void (*pFn2)(int y);

The variables have the same type, but to keep named parameters you need different FunctionDecls. Probably the bogus declarations should be linked into redeclaration chain.

It is only an idea, I don't know if it is viable.

Thanks,
--Serge


_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Trouble understand DeclContext

Asiri Rathnayake via cfe-dev
I have some thoughts on this proposal, but rather than nitpick it inline, I think the issues would probably be better left to a code review.  The primary concern about my proposal seems to be "it may be risky or infeasible to patch everything else to handle this change," which could be made more concrete by me attempting to actually do it.  Let me know if I'm misunderstanding.  For now, I have a working prototype, but it has some ugly workarounds.  I want to see if I can fix them properly without being too invasive, and how confident I am in the result.

Purely from a semantic perspective, hanging ParmVarDecls off of a VarDecl or FieldDecl seems the correct solution for function pointer parameters.  Going through the type information and the redeclaration chain seems highly unfortunate even if it might be less code motion.

Thanks,
-David


On 02/06/2017 10:20 PM, Serge Pavlov wrote:
2017-02-07 9:41 GMT+07:00 David Fontaine <[hidden email]>:

"The DeclContext is a declaration that is a container for other declarations. All non-leaf nodes of AST inherit it. If a contained declaration itself can contain other declarations (nested class, method of a class etc), it will be a nested DeclContext."


Based on this, it seems that VarDecl and FieldDecl should also inherit DeclContext, because a function pointer declaration, which may contain named parameters, would be one of those two.  Any opinion on this?

Nor VarDecl neither FieldDecl contain other declarations, so making them DeclContext is not obvious. DeclContext is used in many places including name lookup and such drastic semantic change can require redesign of other compiler components. And what about such case:

int (* (*abc)(long x))(int x);

Two DeclContexts would be needed here.

I would propose you another way, which probably is less invasive. The parameter names are not attributes of VarDecl, it looks more natural to obtained from corresponding function type, which can be obtained:

VarDecl->getType()->getAs<PointerType>()->getPointeeType()->getAs<FunctionProtoType>()

If FunctionProtoType had method `getDecl` as `RecordDecl` has, you could get the parameter declarations from corresponding FunctionDecl. So you need to construct bogus function declaration when parsing function pointer declaration and attach it to the FunctionProtoType. There is however a problem with different declarations for the same type:

void (*pFn)(int x);
void (*pFn2)(int y);

The variables have the same type, but to keep named parameters you need different FunctionDecls. Probably the bogus declarations should be linked into redeclaration chain.

It is only an idea, I don't know if it is viable.

Thanks,
--Serge



This email message is for the sole use of the intended recipient(s) and may contain confidential information.  Any unauthorized review, use, disclosure or distribution is prohibited.  If you are not the intended recipient, please contact the sender by reply email and destroy all copies of the original message.


_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Trouble understand DeclContext

Asiri Rathnayake via cfe-dev
On 02/08/2017 12:53 AM, David Fontaine via cfe-dev wrote:
> Purely from a semantic perspective, hanging ParmVarDecls off of a
> VarDecl or FieldDecl seems the correct solution for function pointer
> parameters.  Going through the type information and the redeclaration
> chain seems highly unfortunate even if it might be less code motion.

And if such a ParmVarDecl is of function pointer type, you'd recursively
hang any ParmVarDecls off that ParmVarDecl?

But what about a FunctionDecl whose return type is a function pointer type?
_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Trouble understand DeclContext

Asiri Rathnayake via cfe-dev
On 02/08/2017 12:37 AM, Stephan Bergmann via cfe-dev wrote:
> On 02/08/2017 12:53 AM, David Fontaine via cfe-dev wrote:
>> Purely from a semantic perspective, hanging ParmVarDecls off of a
>> VarDecl or FieldDecl seems the correct solution for function pointer
>> parameters.  Going through the type information and the redeclaration
>> chain seems highly unfortunate even if it might be less code motion.
>
> And if such a ParmVarDecl is of function pointer type, you'd
> recursively hang any ParmVarDecls off that ParmVarDecl?
Correct.  That structure would directly mirror the input source.

> But what about a FunctionDecl whose return type is a function pointer
> type?
I hadn't considered that case.

int (*ugh(int x))(int y);

For my specific use case, I'm fine with x being in the AST and y not
(exactly as it is today), because the attributes I'm interested in
(-Wthread-safety) apply to declarations, not types.  (Are there
attributes that apply to types?  I don't actually know this.)

If we wanted to "fix" this case as well, then the way I see it, clang
would need to understand that individual occurrences of _types_ (at
least, function types) can themselves contain nested declarations.  
Which sounds like a far more drastic change than making VarDecl and
FieldDecl inherit DeclContext.

> _______________________________________________
> cfe-dev mailing list
> [hidden email]
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev


-----------------------------------------------------------------------------------
This email message is for the sole use of the intended recipient(s) and may contain
confidential information.  Any unauthorized review, use, disclosure or distribution
is prohibited.  If you are not the intended recipient, please contact the sender by
reply email and destroy all copies of the original message.
-----------------------------------------------------------------------------------
_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Loading...