150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor#!/usr/bin/env python
250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor""" ir.py - parse c declarations
350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor(c) 2002, 2003, 2004, 2005 Simon Burton <simon@arrowtheory.com>
550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas GregorReleased under GNU LGPL license.
650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorversion 0.xx
850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor"""
1050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
1150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorimport sys
1250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor#import cPickle as pickle
1350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorimport pickle
1450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
1550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor#from lexer import Lexer
1650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorfrom parse_core import Symbols #, Parser
1750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorimport node as node_module
1850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorimport cparse
1950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorimport genpyx
2050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
2150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorclass Node(genpyx.Node, node_module.Node):
2250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    """
2350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        tree structure
241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    """
2550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    def __init__( self, *args, **kw ):
2650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        node_module.Node.__init__( self, *args, **kw )
2750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        self._marked = False
2850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    def get_marked( self ):
2950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        return self._marked
3050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    def set_marked( self, marked ):
311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump#    if marked:
3250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor#      print "MARK", self
3350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        self._marked = marked
3450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    marked = property( get_marked, set_marked )
3550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump#  def __getstate__( self ):
3750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor#    return self.__class__, tuple( [ item.__getstate__() for item in self ] )
3850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor#  def __setstate__( self, state ):
391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump#    cls, states = state
4050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor#    states = list(states)
4150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor#    for idx, state in enumerate(states):
4250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor#      items[idx] = items[idx].__setstate__(
4350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    def __getstate__(self):
441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        return str(self)
4550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    def __setstate__(self, state):
461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        Node.__init__(self)
471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        self[:] = eval(state)
4850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
4950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor#  _unique_id = 0
501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump#  def get_unique_id(cls):
511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump#    Node._unique_id += 1
5250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor#    return Node._unique_id
5350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor#  get_unique_id = classmethod(get_unique_id)
541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    def __hash__( self ):
561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        return hash( tuple([hash(type(self))]+[hash(item) for item in self]) )
5750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
5850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    def clone(self):
5950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        l = []
601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        for item in self:
6150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            if isinstance(item,Node):
6250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor                item = item.clone()
6350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            l.append(item)
641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        return self.__class__(*l, **self.__dict__)
6550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    def init_from( self, other ): # class method ?
671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        # Warning: shallow init
6850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        self[:] = other
6950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        self.__dict__.update( other.__dict__ )
701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        return self
7150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
7250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor#  def is_struct(self):
731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump#    for x in self:
74cffecd08f1974dc7cc328bd620b2f69daf442fdaDouglas Gregor#      if isinstance(x,Node):
75cffecd08f1974dc7cc328bd620b2f69daf442fdaDouglas Gregor#        if x.is_struct():
76cffecd08f1974dc7cc328bd620b2f69daf442fdaDouglas Gregor#          return 1
77e27ec8ad56dbf1efb2de004b90fbbb86f740e3f1John McCall#    return 0
78e27ec8ad56dbf1efb2de004b90fbbb86f740e3f1John McCall
79e27ec8ad56dbf1efb2de004b90fbbb86f740e3f1John McCall
80e27ec8ad56dbf1efb2de004b90fbbb86f740e3f1John McCall    #def explain(self):
8150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        #l = []
8250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        #for x in self:
8350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            #if isinstance(x,Node):
841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                #l.append(x.explain())
8550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            #else:
8650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor                #l.append(str(x))
8750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        #return string.join(l," ")
8850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            ##(self.__class__.__name__,string.join(l) )
8950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
9050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    def psource(self):
9150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        if hasattr(self,'lines'):
9250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor#      print "# "+string.join(self.lines,"\n# ")+"\n"
9350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            print "# "+"\n# ".join(self.lines)+"\n"
9450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
9550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    def cstr(self,l=None):
9650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        """
9750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            Build a list of tokens; return the joined tokens string
9850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        """
991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        if l is None:
10050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            l = []
10150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        for x in self:
10250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            if isinstance(x,Node):
1031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                x.cstr(l)
1040953e767ff7817f97b3ab20896b229891eeff45bJohn McCall            else:
105a4923eb7c4b04d360cb2747641a5e92818edf804Douglas Gregor                l.insert(0,str(x)+' ')
1060953e767ff7817f97b3ab20896b229891eeff45bJohn McCall        s = ''.join(l)
10750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        return s
108a4923eb7c4b04d360cb2747641a5e92818edf804Douglas Gregor
1091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    def ctype(self): # anon_clone
1100953e767ff7817f97b3ab20896b229891eeff45bJohn McCall        " return clone of self without identifiers "
111a4923eb7c4b04d360cb2747641a5e92818edf804Douglas Gregor        #print "%s.ctype()"%self
1121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        l=[]
11350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        for x in self:
114a4923eb7c4b04d360cb2747641a5e92818edf804Douglas Gregor            if isinstance(x,Node):
11550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor                l.append(x.ctype())
11650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            else:
117a4923eb7c4b04d360cb2747641a5e92818edf804Douglas Gregor                l.append(x)
11850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        #print "%s.__class__(*%s)"%(self,l)
11950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        return self.__class__(*l, **self.__dict__) # XX **self.__dict__ ?
120a4923eb7c4b04d360cb2747641a5e92818edf804Douglas Gregor
1211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    def cbasetype(self):
1221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        " return ctype with all TypeAlias's replaced "
123ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall        # WARNING: we cache results (so do not mutate self!!)
124ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall        l=[]
125ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall        for x in self:
126ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall            if isinstance(x,Node):
127ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall                l.append(x.cbasetype())
128ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall            else:
129ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall                l.append(x)
13050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        #print "%s.__class__(*%s)"%(self,l)
13150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        return self.__class__(*l, **self.__dict__) # XX **self.__dict__ ?
1321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
133e27ec8ad56dbf1efb2de004b90fbbb86f740e3f1John McCall    def signature( self, tank=None ):
134e27ec8ad56dbf1efb2de004b90fbbb86f740e3f1John McCall        if tank is None:
135e27ec8ad56dbf1efb2de004b90fbbb86f740e3f1John McCall            tank = {}
136e27ec8ad56dbf1efb2de004b90fbbb86f740e3f1John McCall        for node in self.nodes():
13750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            if not tank.has_key( type(node) ):
1381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                tank[ type(node) ] = {}
1391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                type(node).tank = tank[type(node)]
14050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            shape = tuple( [ type(_node).__name__ for _node in node ] )
14150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            if not tank[type(node)].has_key(shape):
14250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor                tank[type(node)][shape] = []
14350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            tank[type(node)][shape].append( node )
1441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        return tank
14550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
14650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    def psig( self, tank=None ):
14750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        if tank is None:
14850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            tank = {}
14950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        tank = self.signature(tank)
1501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        for key in tank.keys():
15150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            print key.__name__
152b890f04174d52e41db19b883244abb17a3254ef1Douglas Gregor            for shape in tank[key].keys():
15350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor                print "  ", shape
1541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
15550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor#
15650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor#################################################
1571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
15850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorclass Named(genpyx.Named, Node):
15950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    " has a .name property "
1601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    def get_name(self):
16150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        if self:
16250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            assert type(self[0])==str
1631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            return self[0]
1641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        return None
1651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    def set_name(self, name):
16650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        if self:
167ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall            self[0] = name
168d9ab76bbce7b8a563aa847cfcdcd39d8280f11bdNuno Lopes        else:
169d9ab76bbce7b8a563aa847cfcdcd39d8280f11bdNuno Lopes            self.append(name)
170ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall    name = property(get_name,set_name)
171ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall
172ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall
17350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorclass BasicType(genpyx.BasicType, Named):
17450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    "float double void char int"
17550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    pass
17650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
17750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorclass Qualifier(genpyx.Qualifier, Named):
17850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    "register signed unsigned short long const volatile inline"
17950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    pass
18050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
18150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorclass StorageClass(genpyx.StorageClass, Named):
18250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    "extern static auto"
18350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    pass
18450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
18550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorclass Ellipses(genpyx.Ellipses, Named):
18650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    "..."
18750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    pass
188ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall
189ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCallclass GCCBuiltin(genpyx.GCCBuiltin, BasicType):
190ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall    "things with __builtin prefix"
191ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall    pass
1929d59ecb4d2c2e8efdb214589753826b662246d82Anders Carlsson
1939d59ecb4d2c2e8efdb214589753826b662246d82Anders Carlssonclass Identifier(genpyx.Identifier, Named):
1949d59ecb4d2c2e8efdb214589753826b662246d82Anders Carlsson    """
1959d59ecb4d2c2e8efdb214589753826b662246d82Anders Carlsson        shape = +( str, +ConstExpr )
1969d59ecb4d2c2e8efdb214589753826b662246d82Anders Carlsson    """
1979d59ecb4d2c2e8efdb214589753826b662246d82Anders Carlsson    #def explain(self):
19850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        #if len(self)==1:
19950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            #return "%s"%self.name
20050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        #else:
2011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            #return "%s initialized to %s"%(self.name,
20250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor                #Node(self[1]).explain()) # will handle Initializer
20350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
20450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor#  def ctype(self):
20550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor#    return self.__class__(*self[1:]) #.clone() ?
20650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
20750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor#  def get_name(self):
20850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor#    if self:
20950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor#      return self[0]
21050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor#  def set_name(self, name):
21150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor#    if self:
2121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump#      self[0] = name
21350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor#    else:
21450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor#      self.append(name)
21550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor#  name = property(get_name,set_name)
2161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
21750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    def cstr(self,l=None):
21850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        if l is None:
21950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            l=[]
2201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        if len(self)>1:
22150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            assert len(self)==2
22250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            l.append( '%s = %s'%(self[0],self[1]) )
22350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        elif len(self)==1:
2241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            l.append( str(self[0]) )
22550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        return " ".join(l)
22650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
22750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorclass TypeAlias(genpyx.TypeAlias, Named):
22850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    """
2291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump     typedefed things, eg. size_t
23050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
23150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    """
2321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    def cbasetype( self ):
2331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        node = self.typedef.cbasetype().get_rest()
23450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        return node
2351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
23650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorclass Function(genpyx.Function, Node):
2371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    """
23850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    """
23950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    #def explain(self):
24050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        #if len(self):
24150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            #return "function (%s), returning"%\
24250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor                #", ".join( map(lambda x:x.explain(),self) )
24350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        #else:
24450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            #return "function returning"
24550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
24650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    def cstr(self,l):
24750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        #print '%s.cstr(%s)'%(self,l)
24850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        _l=[]
24950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        assert len(self)
2502ade35e2cfd554e49d35a52047cea98a82787af9Douglas Gregor        i=0
25150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        while isinstance(self[i],Declarator):
25250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            _l.append( self[i].cstr() )
25350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            i=i+1
25450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        l.append( '(%s)'% ', '.join(_l) )
25550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        while i<len(self):
25650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            self[i].cstr(l)
25750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            i=i+1
25850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        return " ".join(l)
25950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
26050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    def return_type(self):
26150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        node = self[-1]
26250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        #assert isinstance(node,DeclarationSpecifiers)
26350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        return Declarator( Identifier(), node )
26450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    ret = property(return_type)
26550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
26650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    def get_args(self):
267fb87b89fc9eb103e19fb8e4b925c23f0bd091b99Douglas Gregor        args = [ arg for arg in self[:-1] if not arg.is_void() ]
26850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        return args
26950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    args = property(get_args)
27050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
27150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    def arg_types(self):
27250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        return [ AbstractDeclarator().init_from( arg.ctype() ) for arg in self[:-1]]
273f4c46193637631fc993d926ff31c7cb18c090d21Sebastian Redl
27450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    def is_varargs(self):
27550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        for node in self.nodes():
276f60946222721d9ba3c059563935c17b84703187aDouglas Gregor            if isinstance(node,Ellipses) or 'va_list' in node:
277f60946222721d9ba3c059563935c17b84703187aDouglas Gregor#        print self, 'is_varargs'
278f60946222721d9ba3c059563935c17b84703187aDouglas Gregor                return True
2798eee119bf4f1693dde17b8552c1f9f81bf2b681eDouglas Gregor#    print self, 'is_varargs'
28050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        return False
28150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor#    return fn.deepfind(Ellipses) or fn.deepfind('va_list')
28250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
28350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    def ctype(self):
28450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        return Function(*self.arg_types()+[self[-1]]) # XX self[-1].ctype
28550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
28650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
28750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorclass Pointer(genpyx.Pointer, Node):
28850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    """
28950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    """
29050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    def get_spec(self):
29150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        if type(self[0])==TypeSpecifiers: # isinstance ??
29250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            return self[0]
29350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    spec = property(get_spec)
29450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
29550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    #def explain(self):
29650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        #return "pointer to"
29750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
29850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    def cstr(self,l):
29950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        assert len(self)
30050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        node=self[0]
30150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        l.insert(0,'*')
30250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        if isinstance(node,Function):
30350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            l.insert(0,'(')
30450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            l.append(')')
30550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        elif isinstance(node,Array):
30650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            l.insert(0,'(')
3071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            l.append(')')
30850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        return Node.cstr(self,l)
30950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
31050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorclass Array(genpyx.Array, Node):
3111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    """
31250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    """
31350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    #def explain(self):
31450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        #s=''
3151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        #if len(self):
31650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            #if type(self[0])==int:
31750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor                #s='0 to %s '%(self[0]-1)
31850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        #return "array %sof"%s
31950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    def has_size(self):
32050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        try:
32150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            int(self.size)
3221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            return True
32350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        except:
32450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            return False
3251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
32650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    def get_size(self):
32750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        if type(self[-1])==str:
32850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            try: return int(self[-1])
3291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            except: return self[-1]
33050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        return self[-1] # None
33150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    size = property(get_size)
33250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
3331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    def get_spec(self):
3341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        if type(self[0])==TypeSpecifiers: # isinstance ??
33550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            return self[0]
33650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    spec = property(get_spec)
3371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
33850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    def to_pointer(self):
33950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        node = Pointer()
34050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        node.init_from( self.clone() )
34150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        node.pop() # pop the size element
34250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        return node
34350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
3441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    def cstr(self,l):
34550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        if self.size is None:
34650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            l.append('[]')
34750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        else:
34850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            l.append('[%s]'%self.size)
34950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        return Node( *self[:-1] ).cstr( l )
35050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
35150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorclass Tag(genpyx.Tag, Named):
35250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    " the tag of a Struct, Union or Enum "
35350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    pass
35450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
35550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorclass Taged(genpyx.Taged, Node):
35650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    "Struct, Union or Enum "
35750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    def get_tag(self):
3580953e767ff7817f97b3ab20896b229891eeff45bJohn McCall        if len(self):
35950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            tag = self[0]
36050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            assert type(tag)==Tag # isinstance ??
3611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        else:
36250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            tag = None
36350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        return tag
36450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    def set_tag(self,tag):
3651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        if len(self):
36650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            self[0] = tag
36750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        else:
36850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            self.append(tag)
3691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    tag = property( get_tag, set_tag )
3701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    def has_members(self):
37150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        return len(self)>1 # more than just a tag
37250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    def get_members(self):
37350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        return self[1:]
37450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    members = property(get_members) # fields ?
3751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
37650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    def ctype(self):
37750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        if not self.tag.name:
37850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            #print "# WARNING : anonymous struct " # OK i think
37950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            return self.clone()
38050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor#    self = self.clone()
38150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor#    return self[:1] # just the tag
38250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        return self.__class__( self.tag, **self.__dict__ ) # just the Tag
38350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor#    return self.__class__( *self, **self.__dict__ )
3841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
38550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    def cbasetype(self):
38650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        return self.ctype() # is this enough ???
3871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump#    return Node.cbasetype(self) # XX lookup my tag if i am empty ..?
38850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
38950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
39050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorclass Compound(genpyx.Compound, Taged):
39150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    "Struct or Union"
3921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
39350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    def cstr(self,_l=None):
3941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        assert isinstance( self[0], Tag )
39550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        tag=''
39650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        if len(self[0]):
39750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            tag=' '+self[0][0]
39850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        if isinstance(self,Struct):
3991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            l=[ 'struct%s '%tag ]
40050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        elif isinstance(self,Union):
40150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            l=[ 'union%s '%tag ]
40250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        if len(self)>1:
40350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            l.append(' { ')
40450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            for decl in self[1:]:
4051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                l.append( decl.cstr()+"; " )
40650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            l.append('} ')
40750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        if _l is None:
40850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            _l=[]
40950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        while l:
41050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            _l.insert( 0, l.pop() )
41150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        # XX empty struct with no tag -> "struct" XX
4121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        return "".join( _l )
41350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
41450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    def ctype(self):
41550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        tp = Taged.ctype(self)
41650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        for i in range(1,len(tp)):
41750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            tp[i] = StructDeclarator().init_from( tp[i] )
4181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        return tp
41950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
42050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorclass Struct(genpyx.Struct, Compound):
42150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    """
42250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    """
42350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    pass
4241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
42550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
42650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorclass Union(genpyx.Union, Compound):
42750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    """
42850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    """
4291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    pass
43050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
43150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
43250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorclass Enum(genpyx.Enum, Taged):
43350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    """
4341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    """
43550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    def cstr(self,_l=None):
43650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        assert isinstance( self[0], Tag )
43750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        tag=''
43850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        if len(self[0]):
4391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            tag=' '+self[0][0]
44050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        l=[ 'enum%s '%tag ]
44150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        if len(self)>1:
44250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            l.append(' { ')
44350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            for node in self[1:]:
44450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor                l.append( node.cstr()+', ' )
44550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            l.append('} ')
44650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        if _l is None:
44750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            _l=[]
44850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        while l:
4491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            _l.insert( 0, l.pop() )
45050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        return ''.join( _l )
45150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
45250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorclass Declarator(genpyx.Declarator, Node):
45350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    """
4541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    """
4551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
45650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    def __eq__(self,other):
4571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        " unordered equality "
45850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        # ordering sometimes gets lost when we do a cbasetype
45950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        if not isinstance(other,Node):
46050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            return False
46150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        a, b = self[:], other[:]
46250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        a.sort()
46350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        b.sort()
46450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        return a == b
46550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
46650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    def __hash__( self ):
46750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        hs = [hash(item) for item in self]
46850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        hs.sort()
46950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        return hash( tuple([hash(type(self))]+hs) )
4701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
47150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    def transform(self):
4721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        return
4731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
47450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    def get_identifier(self):
47550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        if len(self)>1:
4761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            return self[0]
47750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    def set_identifier(self, identifier):
47850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        if len(self)>1:
47950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            self[0] = identifier
48050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        else:
48150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            self.insert(0,identifier)
48250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    identifier = property(get_identifier,set_identifier)
4831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    def get_spec(self):
48550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        spec = self[-1]
48650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        if type(spec)==TypeSpecifiers: # isinstance ??
48750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            return spec
48850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    spec = property(get_spec)
4891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    def get_type_alias(self):
49150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        if self.spec:
49250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            if isinstance(self.spec[0], TypeAlias):
49350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor                return self.spec[0]
49450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    type_alias = property(get_type_alias)
4951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    def get_tagged(self):
49750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        if self.spec:
49850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            return self.spec.tagged # i am a tagged
49950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    tagged = property(get_tagged)
5001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
50150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    def get_compound(self):
50250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        if self.spec:
50350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            return self.spec.compound # i am a compound
5041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    compound = property(get_compound)
50550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
5060953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    def get_struct(self):
50750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        if self.spec:
50850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            return self.spec.struct # i am a struct
50950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    struct = property(get_struct)
5101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    def get_union(self):
51250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        if self.spec:
5131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            return self.spec.union # i am a union
51450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    union = property(get_union)
5150953e767ff7817f97b3ab20896b229891eeff45bJohn McCall
51650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    def get_enum(self):
51750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        if self.spec:
51850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            return self.spec.enum # i am an enum
51950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    enum = property(get_enum)
5201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    def get_function(self):
52250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        if len(self)>1 and type(self[1])==Function: # isinstance ??
5231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            return self[1]
52450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    function = property(get_function)
5250953e767ff7817f97b3ab20896b229891eeff45bJohn McCall
52650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    def get_pointer(self):
5271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        if len(self)>1 and type(self[1])==Pointer: # isinstance ??
52850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            return self[1]
5291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    pointer = property(get_pointer)
5301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
53150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    def get_array(self):
5321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        if len(self)>1 and type(self[1])==Array: # isinstance ??
53350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            return self[1]
5340953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    array = property(get_array)
53550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
53650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    def get_name(self):
53750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        if self.identifier:
53850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            return self.identifier.name
53950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    def set_name(self, name):
54050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        assert self.identifier is not None
54150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        self.identifier.name = name
5421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    name = property(get_name, set_name)
5431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
54450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    def get_rest(self): # XX needs a better name
54550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        if len(self)>1:
54650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            return self[1]
54750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        return self[0]
54850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
54950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    def pointer_to( self ):
55050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        " return Declarator pointing to self's type "
55150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        decl = Declarator(Identifier(), Pointer(self.get_rest().clone()))
5521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        return decl
5531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
55450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    def deref( self ):
55550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        " return (clone of) Declarator that self is pointing to "
5561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        node = self.ctype() # clone
55750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        pointer = node.pointer or node.array
5581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        assert pointer, "cannot dereference non-pointer"
55950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        node[1:2] = pointer
56050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        return node
56150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
56250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    def is_void(self):
56350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        return self.spec and BasicType('void') in self.spec
56450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
56550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    def is_pointer_to_fn(self):
56650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        return self.pointer and self.deref().function
56750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
56850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    def is_pointer_to_char(self):
56950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor#    return self.ctype() == TransUnit("char *a;").transform()[0].ctype()
57050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        node = self.pointer or self.array
57150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        if node:
57250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            spec = node.spec
57350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            if spec and BasicType('char') in spec and not BasicType('unsigned') in spec:
574264ba48dc98f3f843935a485d5b086f7e0fdc4f1Rafael Espindola                return True
57550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        return False
57650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
57750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    def is_callback(self):
5781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        " i am a pointer to a function whose last arg is void* "
5791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        if self.is_pointer_to_fn():
58050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            fn = self.deref().function
581264ba48dc98f3f843935a485d5b086f7e0fdc4f1Rafael Espindola            if fn.args:
58250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor                arg = fn.args[-1]
5831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                if arg.pointer and arg.deref().is_void():
58450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor                    return True
5851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    def is_complete( self, tag_lookup ):
58750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        if self.tagged and self.tagged.tag.name in tag_lookup and not tag_lookup[self.tagged.tag.name].has_members():
588264ba48dc98f3f843935a485d5b086f7e0fdc4f1Rafael Espindola            return False
5897177dee8aee4b432911c91f1b788963bec0cac9fDaniel Dunbar        return True
59050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
59150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    def is_primative( self ):
59250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        "i am a char,short,int,float,double... "
5931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        spec = self.cbasetype().spec
59450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        return spec and spec.find(BasicType)
59550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
5961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    def is_pyxnative( self ):
5971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        # pyrex handles char* too
59850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        # but i don't know if we should make this the default
5991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        # sometimes we want to send a NULL, so ... XXX
60050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        self = self.cbasetype()
60150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        if self.is_void():
60250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            return False
60350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        if self.is_primative():
60450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            return True
60550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        if self.enum:
60650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            return True
6071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump#    pointer = None
60850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor#    if self.pointer:
60950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor#      pointer = self.pointer
6101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump#    elif self.array:
61150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor#      pointer = self.array
61250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor#    if pointer and pointer.spec:
61350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor#      spec = pointer.spec
61450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor#      if BasicType("char") in spec and not Qualifier("unsigned") in spec:
61550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor#        # char*, const char*
61650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor##        print self.deepstr()
61750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor#        return True
61850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        return False
61950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
62050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    def cstr(self,l=None):
62150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        return Node.cstr(self,l).strip()
62250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
62350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    def ctype(self):
62450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        decl=Declarator()
62550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        decl.init_from( self.clone() )
62650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        decl.identifier = Identifier()
62750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        for i in range(1,len(decl)):
62850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            decl[i]=decl[i].ctype()
62950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        return decl
63050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
63150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    def cbasetype(self):
63250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        # WARNING: we cache results (so do not mutate self!!)
6331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        try:
63450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            # this cache improves performance by 50%
6351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            return self.__cbasetype.clone()
63650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        except AttributeError:
63750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            pass
63850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        decl = self.ctype() # gets rid of Identifier names
63950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        for i, node in enumerate(decl):
64050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            decl[i] = decl[i].cbasetype()
6411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump#    return decl.get_rest()
64250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
6431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        done = False
6441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        while not done:
64550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            done = True
64650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            nodes = decl.deepfilter( TypeSpecifiers )
64750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            for node in nodes:
648efed5c832de630715dd42211dd3b2aab5dd97a1bDouglas Gregor                if node.deepfind( TypeSpecifiers ) != node:
64950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor                    # this node has another TypeSpecifier;
6501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                    decl.expose_node( node )
65150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor                    done = False
652c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall                    break # start again...
653c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall
654c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall        # each TypeSpecifier needs to absorb primitive siblings (StorageClass, BasicType etc.)
655c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall        nodes = decl.deepfilter( TypeSpecifiers )
656c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall        for node in nodes:
657c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall            parent = decl.get_parent(node)
658c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall            i = 0
659c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall            while i < len(parent):
660c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall                assert not type(parent[i]) in (TypeAlias, Enum, Struct, Union)
661c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall                if type(parent[i]) in (StorageClass, BasicType, Qualifier):
662c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall                    node.append( parent.pop(i) )
663c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall                else:
664c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall                    i = i + 1
665c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall
666c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall        self.__cbasetype = decl.clone()
667c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall        return decl
668c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall
669c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall    def invalidate(self):
6701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        # flush cache, etc.
6711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        try:
67250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            del self.__cbasetype
6731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        except AttributeError:
67450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            pass
67550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
67650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    def declare_str(self,name):
67750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        " return c string declaring name with same type as self "
67850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        tp = self.ctype()
6791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        tp.name = name
68050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        return tp.cstr()+";"
68150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
68250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorclass Typedef(genpyx.Typedef, Declarator):
68350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    def cstr(self,l=None):
68450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        return 'typedef ' + Declarator.cstr(self,l) #.strip()
68550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
6861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpclass AbstractDeclarator(genpyx.AbstractDeclarator, Declarator):
68750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    """ used in Function; may lack an identifier """
68850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
68950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    #def cstr(self,l=None):
69050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        #return Node.cstr(self,l)
69150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
692a4923eb7c4b04d360cb2747641a5e92818edf804Douglas Gregor#  def ctype(self):
69350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor#    # _type_ ignores the name of our identifier
69450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor#    return Node.ctype(self)
69550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
69650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorclass FieldLength(genpyx.FieldLength, Node):
69750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    """
69850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    """
69950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    #def explain(self):
70050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        #return ""
70150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
70250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    def cstr(self,l):
70350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        l.append(':%s'%self[0])
70450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
70550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorclass StructDeclarator(genpyx.StructDeclarator, Declarator): # also used in Union
706f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor    """
707f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor    """
708f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor    #def explain(self):
70950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        #flen = self.find(FieldLength)
71050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        #if flen is not None:
71150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            #i = self.index(flen)
7121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            #self.pop(i)
71350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            #s = Declarator.explain(self)
714467b27b9a24bdc823218ad1ad0e37673b6cc1e83John McCall            #self.insert(i,flen)
71550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            #width = flen[0]
71650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            #if width > 0:
71750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor                #return s+" bitfield %s wide"%width
71850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            #else:
71950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor                #return s+" alignment bitfield"
72050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        #else:
72150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            #return Declarator.explain(self)
7221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump#  def ctype(self):
7231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump#    return self
72450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    def get_field_length(self):
72550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        if len(self)>1 and isinstance( self[1], FieldLength ):
72650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            return self[1]
7271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    field_length = property(get_field_length)
72850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
72950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
7301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpclass DeclarationSpecifiers(genpyx.DeclarationSpecifiers, Node):
73150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor#class TypeSpecifiers(Node):
73250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    """
73350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    """
73450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    def __eq__(self,other):
73550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        " unordered equality "
73650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        if not isinstance(other,Node):
73750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor            return False
7381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        a, b = self[:], other[:]
73950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        a.sort()
7401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        b.sort()
74150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        return a == b
74250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
74350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    def __hash__( self ):
7441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        hs = [hash(item) for item in self]
74550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        hs.sort()
74650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor        return hash( tuple([hash(type(self))]+hs) )
74750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
74850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor#  def is_struct(self):
749#    return self.find(Struct) is not None
750
751
752class TypeSpecifiers(genpyx.TypeSpecifiers, DeclarationSpecifiers):
753    """
754    """
755    def get_tagged(self):
756        if self and isinstance(self[0],Taged):
757            return self[0]
758    tagged = property(get_tagged)
759
760    def get_compound(self):
761        if self and isinstance(self[0],Compound):
762            return self[0]
763    compound = property(get_compound)
764
765    def get_struct(self):
766        if self and isinstance(self[0],Struct):
767            return self[0]
768    struct = property(get_struct)
769
770    def get_union(self):
771        if self and isinstance(self[0],Union):
772            return self[0]
773    union = property(get_union)
774
775    def get_enum(self):
776        if self and isinstance(self[0],Enum):
777            return self[0]
778    enum = property(get_enum)
779
780    def cbasetype(self):
781        node = Node.cbasetype(self)
782#    node.expose( TypeSpecifiers )
783#    if node.deepfind(TypeSpecifiers) != node:
784        return node
785
786class Initializer(genpyx.Initializer, Node):
787    """
788    """
789    pass
790
791
792
793class Declaration(genpyx.Declaration, Node):
794    """
795    """
796    def do_spec(self):
797        " distribute DeclarationSpecifiers over each Declarator "
798        spec=self[0]
799        assert isinstance(spec,DeclarationSpecifiers), spec.deepstr()
800        self.pop(0)
801        for declarator in self:
802            assert isinstance(declarator,Declarator)
803            #if isinstance(declarator,DeclarationSpecifiers #huh?
804            ##for node in spec:
805                ##declarator.append(node.clone())
806            declarator.append(spec)
807
808    def transform(self):
809        # children go first
810        for node in self.nodes():
811            if isinstance(node,Declaration):
812                node.do_spec()
813            node.file = self.file # overkill ?
814        self.expose(Declaration)
815
816    #def explain(self):
817        #return string.join([x.explain() for x in self],", ")
818        #return string.join(map(lambda x:x.explain(),self),", ")
819
820
821class ParameterDeclaration(genpyx.ParameterDeclaration, Declaration):
822    """
823    """
824    pass
825
826
827class StructDeclaration(genpyx.StructDeclaration, Declaration):
828    """
829    """
830    pass
831
832
833class TransUnit(genpyx.TransUnit, Node):
834    """
835        Top level node.
836    """
837    def __init__( self, item ): # XX __init__ uses different signature ! XX
838        if type(item)==str:
839            node = cparse.TransUnit()
840            node.parse(item)
841        else:
842            node = item
843            assert isinstance( node, cparse.TransUnit ), str(node)
844        Node.__init__(self)
845        self[:] = [ self.convert(child) for child in node ]
846        self.__dict__.update( node.__dict__ )
847        assert "name" not in node.__dict__
848
849        self.syms = {} # map identifier names to their Declarator's
850        self.typedefs = {} # map names to Typedef's
851        self.tag_lookup = {} # map struct, union, enum tags to Taged's
852
853        # XX should call transform here XX
854
855#    print self.deepstr()
856    def __getstate__( self ):
857        nodes = tuple( [ repr(node) for node in self ] )
858        typedefs = tuple( [ (key,repr(val)) for key,val in self.typedefs.items() ] )
859        return nodes, typedefs
860    def __setstate__( self, state ):
861        Node.__init__(self)
862        nodes, typedefs = state
863        nodes = [ eval(node) for node in nodes ]
864        self[:] = nodes
865        typedefs = [ (key,eval(val)) for key,val in typedefs ]
866        self.typedefs = dict(typedefs)
867
868    def convert( self, node ):
869#    name = node.__class__.__name__
870#    cls = globals()[ name ]
871        cls = cls_lookup[ type(node) ]
872        _node = cls()
873        for child in node:
874            if isinstance(child, node_module.Node):
875                child = self.convert( child )
876            else:
877                assert child is None or type(child) in (str, int), type(child)
878            _node.append( child )
879        _node.__dict__.update( node.__dict__ )
880        return _node
881
882    def strip(self,files):
883        " leave only the declarations from <files> "
884        i=0
885        while i<len(self):
886            if self[i].file in files:
887                i=i+1
888            else:
889                self.pop(i)
890
891    def mark(self,cb,verbose=False):
892        " mark our child nodes such that cb(node).. mark dependants too. prune unmarked objects. "
893        # mark the nodes:
894        for node in self:
895            node.marked = cb(self, node)
896            if verbose and node.marked:
897                print '1:', node.cstr()
898        # propagate dependancy:
899        i=len(self)
900        while i:
901            i-=1 # we go backwards
902            for node in self[i].nodes(): # bottom-up search
903                if verbose and self[i].marked and not node.marked:
904                    print '2:', str(node), '<--', self[i].cstr()
905                node.marked = self[i].marked or node.marked
906                if type(node)==TypeAlias:
907                    if verbose and node.marked and not node.typedef.marked:
908                        print '3:', node.typedef.cstr(), '<--', node.cstr()
909                    node.typedef.marked = node.typedef.marked or node.marked
910                if isinstance(node, Taged):
911                    if node.tag.name in self.tag_lookup:
912                        _node = self.tag_lookup[ node.tag.name ] # look-up the def'n
913                        if verbose and node.marked and not _node.marked:
914                            print '4:', _node.cstr(), '<--', self[i].cstr()
915#            _node.marked = _node.marked or self[i].marked
916                        _node.marked = _node.marked or node.marked
917#          else:
918#            # this guy has no tag
919#            print "lost tag:", self[i].cstr()
920
921                 # XX struct defs acquire marks from members, but XX
922                 # XX ordinary definitions do not                 XX
923#        if node.marked and not self[i].marked:
924#          # one of my descendants is marked
925#          if verbose:
926#            print '5:', self[i].cstr(), '<--', node.cstr()
927#          self[i].marked = True
928#    if verbose:
929#      for node in self:
930#        print '-'*79
931#        if node.enum:
932#          print str(node.marked) + ': ' + node.cstr()
933        # prune:
934        f = open(".tmp/pruned.txt","w")
935        f.write("// This file autogenerated by '%s' .\n"%__file__)
936        f.write("// List of functions pruned from parse tree, for various reasons.\n\n")
937        i=0
938        while i<len(self):
939            if not self[i].marked:
940                if verbose: print 'pop:', self[i].cstr()
941                f.write( self[i].cstr() + "\n" )
942                self.pop(i)
943#      elif self[i].compound:
944#        # XXXX for now, rip out all struct members XXXX
945#        self[i].compound[1:] = [] # XX encapsulation
946#        i = i + 1
947            else:
948                i = i + 1
949        for key, value in self.syms.items():
950            if not value.marked:
951                del self.syms[key]
952        for key, value in self.typedefs.items():
953            if not value.marked:
954                del self.typedefs[key]
955        for key, value in self.tag_lookup.items():
956            if not value.marked:
957                del self.tag_lookup[key]
958#    sys.exit(1)
959
960    def assert_no_dups(self):
961        check={}
962        for node in self.nodes():
963            assert not check.has_key(id(node))
964            check[id(node)]=1
965
966    def transform(self, verbose=False, test_parse=False, test_types=False ):
967        i=0
968        while i < len(self):
969            if verbose: print "##"*25
970            declaration=self[i]
971
972            if verbose: declaration.psource()
973            if verbose: print declaration.deepstr(),'\n'
974            assert isinstance(declaration,Declaration)
975            if verbose: print "# expose declarators from declaration"
976
977            # STAGE 1
978            declaration.transform()
979
980            if verbose: print declaration.deepstr(),'\n'
981            self[i:i+1] = declaration # expose declarators from declaration
982
983            for j in range(len(declaration)):
984                declarator=self[i]
985
986                assert isinstance(declarator,Declarator)
987                if verbose: print "# declarator.transform()"
988
989                # STAGE 2
990                declarator.transform()
991
992                if verbose: print declarator.deepstr(),'\n'
993                if verbose: print "# self.visit_declarator(declarator)"
994
995                # STAGE 3
996                self[i] = declarator = self.visit_declarator(declarator)
997
998                # STAGE 4
999                if declarator.name:
1000                    if isinstance(declarator, Typedef):
1001                        if verbose: print "# typedef %s" % declarator.name
1002                        self.typedefs[ declarator.name ] = declarator
1003                    else:
1004                        if verbose: print "# sym %s" % declarator.name
1005                        self.syms[ declarator.name ] = declarator
1006
1007                for node in declarator.nodes():
1008                    if isinstance(node,Taged) and node.tag.name:
1009                        assert type(node.tag.name)==str, node.deepstr()
1010                        taged = self.tag_lookup.get( node.tag.name, None )
1011                        if taged is None:
1012                            if verbose: print "# tag lookup %s = %s" % (declarator.name, node.tag.name)
1013                            self.tag_lookup[ node.tag.name ] = node
1014                        elif not taged.has_members():
1015                            # this is (maybe) the definition of this tag
1016                            if verbose: print "# definition %s = %s" % (declarator.name, node.tag.name)
1017                            self.tag_lookup[ node.tag.name ] = node
1018
1019                # Annotate the TypeAlias's
1020                for node in declarator.deepfilter( TypeAlias ):
1021                    name = node[0]
1022                    assert type( name ) == str
1023                    node.typedef = self.typedefs[ name ]
1024
1025                if verbose: print declarator.deepstr(),'\n'
1026                #print declarator.ctype().deepstr(),'\n'
1027                #assert declarator.clone() == declarator
1028
1029                ###################################################
1030                # TESTS:
1031                if test_parse:
1032                    # test that parse of cstr gives same answer
1033                    cstr = declarator.cstr()+';\n'
1034                    if verbose: print '# '+cstr.replace('\n','\n# ')
1035                    #print
1036                    if isinstance(declarator,Typedef):
1037                        name = declarator[0][0]
1038                        assert type(name)==str
1039                        self.lexer.rmtypedef( name )
1040                    declaration = cparse.Declaration()
1041                    self.lexer.lex( cstr )
1042                    #print self.lexer.err_string()
1043                    declaration.parse(  self.lexer, Symbols() ) # use new name-space
1044                    #declaration.parse(  Lexer( cstr ), Symbols() )
1045                    declaration = self.convert(declaration)
1046                    declaration.transform()
1047                    assert len(declaration)==1
1048                    decl=declaration[0]
1049                    decl.transform()
1050                    decl = self.visit_declarator(decl)
1051                    if decl!=declarator:
1052                        if verbose: print "#???????????"
1053                        if verbose: print decl.deepstr(),'\n\n'
1054                        #if verbose: print declaration.deepstr(),'\n\n'
1055                        #assert 0
1056                    elif verbose: print '# OK\n'
1057
1058                if test_types:
1059                    node = declarator.ctype()
1060                    declare_str= node.declare_str("my_name")
1061                    if verbose: print "# declarator.ctype() "
1062                    if verbose: print node.deepstr(),"\n"
1063                    if verbose: print "#",declare_str.replace('\n','\n# '), '\n'
1064
1065                i=i+1
1066        return self
1067
1068    def visit(self,node):
1069        #print 'visit(%s)'%node
1070        for _node in node:
1071            if isinstance(_node,Declarator):
1072                _node = self.visit_declarator(_node) # XX replace _node
1073            elif isinstance(_node,Node):
1074                _node = self.visit(_node) # XX replace _node
1075        return node
1076
1077    def visit_declarator(self,decl):
1078        assert isinstance(decl,Declarator)
1079
1080        # STAGE 3.a
1081        tp = decl.deepfind(Typedef)
1082        if tp is not None:
1083            decl.deeprm(tp)
1084            tp.init_from( decl ) # warning: shallow init
1085            decl = tp
1086
1087        # STAGE 3.b
1088        i=len(decl)
1089        # accumulate nodes (they become the children of decl)
1090        children=[]
1091        while i:
1092            i=i-1
1093            node=decl.pop(i)
1094            if isinstance(node,Declarator):
1095                node = self.visit_declarator(node) # replace node
1096            else:
1097                node = self.visit(node) # replace node
1098            if isinstance(node,Pointer):
1099                node+=children
1100                children=[node]
1101            elif isinstance(node,Function):
1102                node+=children
1103                children=[node]
1104            elif isinstance(node,Array):
1105                while children:
1106                    node.insert(0,children.pop())
1107                children=[node]
1108                # array size (if any) at end
1109            #elif isinstance(node,Identifier):
1110                #node+=children
1111                #children=[node]
1112            else:
1113                # accumulate
1114                children.insert(0,node)
1115        decl[:]=children
1116        return decl
1117
1118    cstr = None
1119    ctype = None
1120    cbasetype = None
1121
1122
1123# remap the global class definitions in genpyx to
1124# point to the definitions in this module
1125gbl = globals()
1126for key, val in gbl.items():
1127    if type(val)==type:
1128        if issubclass(val,Node):
1129            setattr( genpyx, key, val )
1130assert genpyx.Node == Node
1131
1132cls_lookup = {
1133#  Node : Node ,
1134    cparse.BasicType : BasicType ,
1135    cparse.Qualifier : Qualifier ,
1136    cparse.StorageClass : StorageClass ,
1137    cparse.Ellipses : Ellipses ,
1138    cparse.GCCBuiltin : GCCBuiltin ,
1139    cparse.Identifier : Identifier ,
1140    cparse.TypeAlias : TypeAlias ,
1141    cparse.Function : Function ,
1142    cparse.Pointer : Pointer ,
1143    cparse.Array : Array ,
1144    cparse.Tag : Tag ,
1145    cparse.Compound : Compound ,
1146    cparse.Struct : Struct ,
1147    cparse.Union : Union ,
1148    cparse.Enum : Enum ,
1149    cparse.Declarator : Declarator ,
1150    cparse.Typedef : Typedef ,
1151    cparse.AbstractDeclarator : AbstractDeclarator ,
1152    cparse.FieldLength : FieldLength ,
1153    cparse.StructDeclarator : StructDeclarator ,
1154    cparse.DeclarationSpecifiers : TypeSpecifiers ,
1155    cparse.TypeSpecifiers : TypeSpecifiers ,
1156    cparse.Initializer : Initializer ,
1157    cparse.Declaration : Declaration ,
1158    cparse.ParameterDeclaration : ParameterDeclaration ,
1159    cparse.StructDeclaration : StructDeclaration ,
1160    cparse.TransUnit : TransUnit ,
1161}
1162
1163
1164