@@ -476,7 +476,7 @@ def test_node_visitor():
476476 'Asm' : [0 , 1 ],
477477 # PreprocessorLine is OpenCL, not GNU
478478 'PreprocessorLine' : [0 , 0 ],
479- 'TypeOfDeclaration' : [0 , 2 ],
479+ 'TypeOfDeclaration' : [0 , 4 ],
480480 'TypeOfExpression' : [0 , 1 ],
481481 'FuncDeclExt' : [0 , 1 ],
482482 }
@@ -514,6 +514,7 @@ def visit_FuncDeclExt(self, node):
514514 int func1(int a, int b) {
515515 __typeof__(a) _a = __builtin_types_compatible_p(long char, short int);
516516 __typeof__ (__typeof__ (char *)[4]) y;
517+ typeof (typeof (char *)[4]) z;
517518 asm("rdtsc" : "=A" (val));
518519 __attribute__((unused)) static int c;
519520 }
@@ -530,6 +531,53 @@ def visit_FuncDeclExt(self, node):
530531 assert visit_num [0 ] == visit_num [1 ], assert_msg
531532
532533
534+ def test_typeof_reproduction ():
535+ src = """
536+ int func(int a, int b) {
537+ __typeof__(a) _a = a;
538+ typeof(b) _b = b;
539+
540+ __typeof__ (__typeof__ (char *)[4]) y;
541+ typeof (typeof (char *)[4]) z;
542+ }
543+ """
544+ assert _round_trip_matches (src )
545+
546+ import pycparserext .ext_c_parser as ext_c_parser
547+ from pycparser .c_ast import NodeVisitor
548+
549+ # key is type of visit, value is
550+ # [actual # __typeof__, expected # __typeof__,
551+ # actual # typeof, expected # typeof]
552+ visits = {
553+ 'TypeOfDeclaration' : [0 , 2 , 0 , 2 ],
554+ 'TypeOfExpression' : [0 , 1 , 0 , 1 ],
555+ }
556+
557+ class TestVisitor (NodeVisitor ):
558+ def visit_TypeOfDeclaration (self , node ):
559+ idx = 0 if node .typeof_keyword == '__typeof__' else 2
560+ visits ['TypeOfDeclaration' ][idx ] += 1
561+ NodeVisitor .generic_visit (self , node )
562+
563+ def visit_TypeOfExpression (self , node ):
564+ idx = 0 if node .typeof_keyword == '__typeof__' else 2
565+ visits ['TypeOfExpression' ][idx ] += 1
566+ NodeVisitor .generic_visit (self , node )
567+
568+ parser = ext_c_parser .GnuCParser ()
569+ ast = parser .parse (src )
570+ ast .show ()
571+ TestVisitor ().visit (ast )
572+ for visit_type , visit_num in visits .items ():
573+ assert_msg = '{}: Should have visited ({}, {}), got ({}, {})' .format (
574+ visit_type ,
575+ visit_num [1 ], visit_num [3 ],
576+ visit_num [0 ], visit_num [2 ])
577+ assert visit_num [0 ] == visit_num [1 ] and \
578+ visit_num [2 ] == visit_num [3 ], assert_msg
579+
580+
533581if __name__ == "__main__" :
534582 import sys
535583 if len (sys .argv ) > 1 :
0 commit comments