-
Notifications
You must be signed in to change notification settings - Fork 609
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement _Atomic
support
#430
Comments
In your example, aren't I'm thinking of two aspects here:
W.r.t. the former, you'll need code to parse the two different forms of
While they have different syntax, they have the same semantics. So my real question is: do the |
Alright, I think I get what you mean. In this example the following holds: _Atomic(int *) a;
_Atomic(int) *b;
_Atomic int *c;
int * _Atomic d;
int _Atomic *e;
a = d;
b = c = e; So they are:
Part 1 and 2 match what you said, so I believe I see now why you do not want a keyword. Is the suggestion for I personally do not like this as I believe the understanding of CST and AST is a bit extreme in your example. I also do not think it is any good to generate different code in this particular case as it may help with some styling warnings. However, I am not going to fight with this as long as you provide some clear explanations on the route to take.
|
Just to clarify; I do not want an AST node. A keyword for To answer your questions:
|
|
How is this nesting in You can write |
Hrrrm, I think I see it finally. I believe I had a fundamental misunderstanding of how C grammar works in regards to Atomic. I did not make a parallel to const here, and thought _Atomic(x) specifier syntax was suggested to lift some semantical restrictions. I read http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1485.pdf and realised that actually I was wrong, and the specifier is here solely for convenience reasons. In my defence I can add that it is quite strange to have two syntaxes with the same expressibility, but oh well. I think I can work with this. |
I went ahead a committed a couple of changes to implement Note that I didn't port over the C generator tests from #431 and I didn't port over your addition of fake headers + end-to-end test. Feel free to update #431 for that, or to create a separate PR. Specifically, the C generator may not work correctly for the new atomic specifiers. Also note that paragraph 3 of section 6.7.2.4 in the standard forbids nesting of the atomic specifier, so something like |
Hi, thanks for your work! I will check it more precisely in the coming days, but for the time being there is an understanding flaw.
I am afraid you might misinterpreted it.
Pointer to an atomic is not an atomic type itself, it is non-atomic. |
Thanks, that makes sense. I've committed another fix. When you look at it, make sure to look at the latest code in |
Hmmmm, I tried, but the implementation is still incorrect, as # This is a bit ugly, but we need to process atomic specifier before qualifiers,
# since _Atomic(int) has a conflict with _Atomic int.
def p_declaration_specifiers_no_type_4(self, p):
""" declaration_specifiers_no_type : atomic_specifier declaration_specifiers_no_type_opt
"""
p[0] = self._add_declaration_specifier(p[2], p[1], 'type') |
With this diff it does work, but I am not positive whether this is what you intended to do: % git diff
diff --git a/pycparser/c_parser.py b/pycparser/c_parser.py
index 7d087f0..4b16457 100644
--- a/pycparser/c_parser.py
+++ b/pycparser/c_parser.py
@@ -779,6 +779,13 @@ class CParser(PLYParser):
"""
p[0] = self._add_declaration_specifier(p[2], p[1], 'function')
+ # This is a bit ugly, but we need to process atomic specifier before qualifiers,
+ # since _Atomic(int) has a conflict with _Atomic int.
+ def p_declaration_specifiers_no_type_4(self, p):
+ """ declaration_specifiers_no_type : atomic_specifier declaration_specifiers_no_type_opt
+ """
+ p[0] = self._add_declaration_specifier(p[2], p[1], 'type')
+
def p_declaration_specifiers_1(self, p):
""" declaration_specifiers : declaration_specifiers type_qualifier
"""
@@ -857,6 +864,15 @@ class CParser(PLYParser):
typ.quals.append('_Atomic')
p[0] = typ
+ # See section 6.7.2.4 of the C11 standard.
+ def p_type_specifier_3(self, p):
+ """ atomic_specifier : _ATOMIC LPAREN type_name RPAREN
+ """
+ typ = p[3]
+ typ.quals.append('_Atomic')
+ p[0] = typ
+
+
def p_type_qualifier(self, p):
""" type_qualifier : CONST
| RESTRICT |
Right, this is a problem for all storage class specifiers like I'm OK with a PR to add your workaround; just please make sure to add several tests with different storage class specifiers. Also if you introduce atomic_specifier once there shouldn't be duplication (it can be used in both rules). |
Alright, added, though I believe it failed again in an interesting manner for generator tests. See the updated PR.
Yeah, did that. Actually had that earlier, just crafted something simple for a PoC. |
The qualifier duplication on |
As mentioned in #428 we need
_Atomic
keyword support for C11. This keyword is rather special, as it can be both aqualifier
and aspecifier
. C standard provides two grammar definitions for this:Depending on whether the
_Atomic
keyword is a specifier or a qualifier it refers to an atomic type. The atomic type can contain another atomic type, i.e. define nested atomic types, and it can also refer to specific parts of the type. As mentioned in the original PR all the following examples are valid:All these samples need to generate different code after being parsed through pycparser and converted back to C, so the implementation needs to treat
_Atomic
qualifier and specifier separately. My suggestion is to follow the grammar of the C standard and use a normal qualifier for_Atomic
qualifier, and a dedicated class like withenum
.The text was updated successfully, but these errors were encountered: