@@ -240,6 +240,38 @@ def __iter__(self):
240240
241241 attr_names = ()
242242
243+
244+ class _StructUnionEnumMixin :
245+ def __init__ (self , * args , attributes = None , ** kwargs ):
246+ super ().__init__ (* args , ** kwargs )
247+ self .attributes = attributes
248+
249+ def children (self ):
250+ children = list (super ().children ())
251+ if self .attributes :
252+ children .append (("attributes" , self .attributes ))
253+ return children
254+
255+ def __iter__ (self ):
256+ yield from super ().__iter__ ()
257+ if self .attributes :
258+ yield self .attributes
259+
260+
261+ class EnumExt (_StructUnionEnumMixin , c_ast .Enum ):
262+ pass
263+
264+
265+ class EnumeratorExt (_StructUnionEnumMixin , c_ast .Enumerator ):
266+ pass
267+
268+
269+ class StructExt (_StructUnionEnumMixin , c_ast .Struct ):
270+ pass
271+
272+
273+ class UnionExt (_StructUnionEnumMixin , c_ast .Union ):
274+ pass
243275# }}}
244276
245277
@@ -468,6 +500,181 @@ def p_direct_abstract_declarator_6(self, p):
468500
469501 p [0 ] = self ._type_modify_decl (decl = p [1 ], modifier = func )
470502
503+ def _select_struct_union_class (self , token ):
504+ klass = super ()._select_struct_union_class (token )
505+ return {
506+ c_ast .Struct : StructExt ,
507+ c_ast .Union : UnionExt ,
508+ }[klass ]
509+
510+ def p_struct_or_union_specifier_with_attr_1 (self , p ):
511+ """ struct_or_union_specifier : struct_or_union ID brace_open brace_close attributes_opt
512+ | struct_or_union TYPEID brace_open brace_close attributes_opt
513+ """
514+ klass = self ._select_struct_union_class (p [1 ])
515+ p [0 ] = klass (
516+ name = p [2 ],
517+ decls = [],
518+ attributes = p [5 ],
519+ coord = self ._token_coord (p , 2 ))
520+
521+ def p_struct_or_union_specifier_with_attr_2 (self , p ):
522+ """ struct_or_union_specifier : struct_or_union attributes_opt ID brace_open brace_close
523+ | struct_or_union attributes_opt TYPEID brace_open brace_close
524+ """
525+ klass = self ._select_struct_union_class (p [1 ])
526+ p [0 ] = klass (
527+ name = p [3 ],
528+ decls = [],
529+ attributes = p [2 ],
530+ coord = self ._token_coord (p , 3 ))
531+
532+ def p_struct_or_union_specifier_with_attr_3 (self , p ):
533+ """ struct_or_union_specifier : attributes_opt struct_or_union ID brace_open brace_close
534+ | attributes_opt struct_or_union TYPEID brace_open brace_close
535+ """
536+ klass = self ._select_struct_union_class (p [2 ])
537+ p [0 ] = klass (
538+ name = p [3 ],
539+ decls = [],
540+ attributes = p [1 ],
541+ coord = self ._token_coord (p , 3 ))
542+
543+ def p_struct_or_union_specifier_with_attr_4 (self , p ):
544+ """ struct_or_union_specifier : struct_or_union ID brace_open struct_declaration_list brace_close attributes_opt
545+ | struct_or_union TYPEID brace_open struct_declaration_list brace_close attributes_opt
546+ """
547+ klass = self ._select_struct_union_class (p [1 ])
548+ p [0 ] = klass (
549+ name = p [2 ],
550+ decls = p [4 ],
551+ attributes = p [6 ],
552+ coord = self ._token_coord (p , 2 ))
553+
554+ def p_struct_or_union_specifier_with_attr_5 (self , p ):
555+ """ struct_or_union_specifier : struct_or_union attributes_opt ID brace_open struct_declaration_list brace_close
556+ | struct_or_union attributes_opt TYPEID brace_open struct_declaration_list brace_close
557+ """
558+ klass = self ._select_struct_union_class (p [1 ])
559+ p [0 ] = klass (
560+ name = p [3 ],
561+ decls = p [5 ],
562+ attributes = p [2 ],
563+ coord = self ._token_coord (p , 3 ))
564+
565+ def p_struct_or_union_specifier_with_attr_6 (self , p ):
566+ """ struct_or_union_specifier : attributes_opt struct_or_union ID brace_open struct_declaration_list brace_close
567+ | attributes_opt struct_or_union TYPEID brace_open struct_declaration_list brace_close
568+ """
569+ klass = self ._select_struct_union_class (p [2 ])
570+ p [0 ] = klass (
571+ name = p [3 ],
572+ decls = p [5 ],
573+ attributes = p [1 ],
574+ coord = self ._token_coord (p , 3 ))
575+
576+ def p_struct_or_union_specifier_with_attr_7 (self , p ):
577+ """ struct_or_union_specifier : struct_or_union attributes_opt ID
578+ | struct_or_union attributes_opt TYPEID
579+ """
580+ klass = self ._select_struct_union_class (p [1 ])
581+ # None means no list of members
582+ p [0 ] = klass (
583+ name = p [3 ],
584+ decls = None ,
585+ attributes = p [2 ],
586+ coord = self ._token_coord (p , 3 ))
587+
588+ def p_struct_or_union_specifier_with_attr_8 (self , p ):
589+ """ struct_or_union_specifier : struct_or_union brace_open brace_close attributes_opt
590+ """
591+ klass = self ._select_struct_union_class (p [1 ])
592+ p [0 ] = klass (
593+ name = None ,
594+ decls = [],
595+ attributes = p [4 ],
596+ coord = self ._token_coord (p , 2 ))
597+
598+ def p_struct_or_union_specifier_with_attr_9 (self , p ):
599+ """ struct_or_union_specifier : struct_or_union attributes_opt brace_open brace_close
600+ """
601+ klass = self ._select_struct_union_class (p [1 ])
602+ p [0 ] = klass (
603+ name = None ,
604+ decls = [],
605+ attributes = p [2 ],
606+ coord = self ._token_coord (p , 3 ))
607+
608+ def p_struct_or_union_specifier_with_attr_10 (self , p ):
609+ """ struct_or_union_specifier : struct_or_union brace_open struct_declaration_list brace_close attributes_opt
610+ """
611+ klass = self ._select_struct_union_class (p [1 ])
612+ p [0 ] = klass (
613+ name = None ,
614+ decls = p [3 ],
615+ attributes = p [5 ],
616+ coord = self ._token_coord (p , 2 ))
617+
618+ def p_struct_or_union_specifier_with_attr_11 (self , p ):
619+ """ struct_or_union_specifier : struct_or_union attributes_opt brace_open struct_declaration_list brace_close
620+ """
621+ klass = self ._select_struct_union_class (p [1 ])
622+ p [0 ] = klass (
623+ name = None ,
624+ decls = p [4 ],
625+ attributes = p [2 ],
626+ coord = self ._token_coord (p , 3 ))
627+
628+ def p_enum_specifier_with_attr_1 (self , p ):
629+ """ enum_specifier : ENUM attributes_opt ID
630+ | ENUM attributes_opt TYPEID
631+ """
632+ p [0 ] = EnumExt (p [3 ], None , self ._token_coord (p , 1 ), attributes = p [2 ])
633+
634+ def p_enum_specifier_with_attr_2 (self , p ):
635+ """ enum_specifier : ENUM attributes_opt brace_open enumerator_list brace_close
636+ """
637+ p [0 ] = EnumExt (None , p [4 ], self ._token_coord (p , 1 ), attributes = p [2 ])
638+
639+ def p_enum_specifier_with_attr_3 (self , p ):
640+ """ enum_specifier : ENUM brace_open enumerator_list brace_close attributes_opt
641+ """
642+ p [0 ] = EnumExt (None , p [3 ], self ._token_coord (p , 1 ), attributes = p [5 ])
643+
644+ def p_enum_specifier_with_attr_4 (self , p ):
645+ """ enum_specifier : ENUM attributes_opt ID brace_open enumerator_list brace_close
646+ | ENUM attributes_opt TYPEID brace_open enumerator_list brace_close
647+ """
648+ p [0 ] = EnumExt (p [3 ], p [5 ], self ._token_coord (p , 1 ), attributes = p [2 ])
649+
650+ def p_enum_specifier_with_attr_5 (self , p ):
651+ """ enum_specifier : ENUM ID brace_open enumerator_list brace_close attributes_opt
652+ | ENUM TYPEID brace_open enumerator_list brace_close attributes_opt
653+ """
654+ p [0 ] = EnumExt (p [2 ], p [4 ], self ._token_coord (p , 1 ), attributes = p [6 ])
655+
656+ def p_enumerator (self , p ):
657+ """ enumerator : ID
658+ | ID EQUALS constant_expression
659+ | ID attributes_opt
660+ | ID attributes_opt EQUALS constant_expression
661+ """
662+ if len (p ) in (2 , 4 ):
663+ super ().p_enumerator (p )
664+ else :
665+ if len (p ) == 3 :
666+ enumerator = EnumeratorExt (
667+ p [1 ], None ,
668+ self ._token_coord (p , 1 ),
669+ attributes = p [2 ])
670+ else :
671+ enumerator = EnumeratorExt (
672+ p [1 ], p [4 ],
673+ self ._token_coord (p , 1 ),
674+ attributes = p [2 ])
675+ self ._add_identifier (enumerator .name , enumerator .coord )
676+ p [0 ] = enumerator
677+
471678 # }}}
472679# }}}
473680
0 commit comments