145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#!/usr/bin/env python
245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org""" ir.py - parse c declarations
345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org(c) 2002, 2003, 2004, 2005 Simon Burton <simon@arrowtheory.com>
545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgReleased under GNU LGPL license.
645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgversion 0.xx
845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org"""
1045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
1145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgimport sys
1245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#import cPickle as pickle
1345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgimport pickle
1445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
1545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#from lexer import Lexer
1645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgfrom parse_core import Symbols #, Parser
1745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgimport node as node_module
1845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgimport cparse
1945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgimport genpyx
2045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
2145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgclass Node(genpyx.Node, node_module.Node):
2245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    """
2345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        tree structure
2445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    """
2545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def __init__( self, *args, **kw ):
2645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        node_module.Node.__init__( self, *args, **kw )
2745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        self._marked = False
2845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def get_marked( self ):
2945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return self._marked
3045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def set_marked( self, marked ):
3145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#    if marked:
3245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#      print "MARK", self
3345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        self._marked = marked
3445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    marked = property( get_marked, set_marked )
3545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
3645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#  def __getstate__( self ):
3745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#    return self.__class__, tuple( [ item.__getstate__() for item in self ] )
3845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#  def __setstate__( self, state ):
3945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#    cls, states = state
4045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#    states = list(states)
4145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#    for idx, state in enumerate(states):
4245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#      items[idx] = items[idx].__setstate__(
4345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def __getstate__(self):
4445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return str(self)
4545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def __setstate__(self, state):
4645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        Node.__init__(self)
4745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        self[:] = eval(state)
4845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
4945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#  _unique_id = 0
5045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#  def get_unique_id(cls):
5145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#    Node._unique_id += 1
5245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#    return Node._unique_id
5345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#  get_unique_id = classmethod(get_unique_id)
5445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
5545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def __hash__( self ):
5645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return hash( tuple([hash(type(self))]+[hash(item) for item in self]) )
5745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
5845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def clone(self):
5945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        l = []
6045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        for item in self:
6145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            if isinstance(item,Node):
6245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                item = item.clone()
6345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            l.append(item)
6445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return self.__class__(*l, **self.__dict__)
6545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
6645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def init_from( self, other ): # class method ?
6745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        # Warning: shallow init
6845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        self[:] = other
6945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        self.__dict__.update( other.__dict__ )
7045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return self
7145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
7245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#  def is_struct(self):
7345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#    for x in self:
7445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#      if isinstance(x,Node):
7545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#        if x.is_struct():
7645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#          return 1
7745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#    return 0
7845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
7945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
8045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    #def explain(self):
8145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        #l = []
8245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        #for x in self:
8345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            #if isinstance(x,Node):
8445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                #l.append(x.explain())
8545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            #else:
8645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                #l.append(str(x))
8745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        #return string.join(l," ")
8845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            ##(self.__class__.__name__,string.join(l) )
8945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
9045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def psource(self):
9145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if hasattr(self,'lines'):
9245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#      print "# "+string.join(self.lines,"\n# ")+"\n"
9345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            print "# "+"\n# ".join(self.lines)+"\n"
9445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
9545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def cstr(self,l=None):
9645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        """
9745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            Build a list of tokens; return the joined tokens string
9845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        """
9945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if l is None:
10045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            l = []
10145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        for x in self:
10245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            if isinstance(x,Node):
10345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                x.cstr(l)
10445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            else:
10545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                l.insert(0,str(x)+' ')
10645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        s = ''.join(l)
10745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return s
10845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
10945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def ctype(self): # anon_clone
11045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        " return clone of self without identifiers "
11145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        #print "%s.ctype()"%self
11245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        l=[]
11345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        for x in self:
11445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            if isinstance(x,Node):
11545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                l.append(x.ctype())
11645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            else:
11745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                l.append(x)
11845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        #print "%s.__class__(*%s)"%(self,l)
11945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return self.__class__(*l, **self.__dict__) # XX **self.__dict__ ?
12045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
12145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def cbasetype(self):
12245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        " return ctype with all TypeAlias's replaced "
12345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        # WARNING: we cache results (so do not mutate self!!)
12445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        l=[]
12545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        for x in self:
12645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            if isinstance(x,Node):
12745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                l.append(x.cbasetype())
12845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            else:
12945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                l.append(x)
13045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        #print "%s.__class__(*%s)"%(self,l)
13145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return self.__class__(*l, **self.__dict__) # XX **self.__dict__ ?
13245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
13345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def signature( self, tank=None ):
13445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if tank is None:
13545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            tank = {}
13645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        for node in self.nodes():
13745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            if not tank.has_key( type(node) ):
13845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                tank[ type(node) ] = {}
13945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                type(node).tank = tank[type(node)]
14045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            shape = tuple( [ type(_node).__name__ for _node in node ] )
14145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            if not tank[type(node)].has_key(shape):
14245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                tank[type(node)][shape] = []
14345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            tank[type(node)][shape].append( node )
14445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return tank
14545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
14645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def psig( self, tank=None ):
14745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if tank is None:
14845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            tank = {}
14945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        tank = self.signature(tank)
15045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        for key in tank.keys():
15145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            print key.__name__
15245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            for shape in tank[key].keys():
15345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                print "  ", shape
15445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
15545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#
15645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#################################################
15745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
15845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgclass Named(genpyx.Named, Node):
15945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    " has a .name property "
16045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def get_name(self):
16145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if self:
16245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            assert type(self[0])==str
16345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            return self[0]
16445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return None
16545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def set_name(self, name):
16645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if self:
16745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            self[0] = name
16845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        else:
16945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            self.append(name)
17045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    name = property(get_name,set_name)
17145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
17245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
17345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgclass BasicType(genpyx.BasicType, Named):
17445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    "float double void char int"
17545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    pass
17645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
17745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgclass Qualifier(genpyx.Qualifier, Named):
17845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    "register signed unsigned short long const volatile inline"
17945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    pass
18045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
18145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgclass StorageClass(genpyx.StorageClass, Named):
18245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    "extern static auto"
18345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    pass
18445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
18545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgclass Ellipses(genpyx.Ellipses, Named):
18645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    "..."
18745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    pass
18845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
18945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgclass GCCBuiltin(genpyx.GCCBuiltin, BasicType):
19045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    "things with __builtin prefix"
19145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    pass
19245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
19345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgclass Identifier(genpyx.Identifier, Named):
19445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    """
19545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        shape = +( str, +ConstExpr )
19645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    """
19745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    #def explain(self):
19845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        #if len(self)==1:
19945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            #return "%s"%self.name
20045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        #else:
20145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            #return "%s initialized to %s"%(self.name,
20245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                #Node(self[1]).explain()) # will handle Initializer
20345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
20445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#  def ctype(self):
20545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#    return self.__class__(*self[1:]) #.clone() ?
20645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
20745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#  def get_name(self):
20845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#    if self:
20945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#      return self[0]
21045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#  def set_name(self, name):
21145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#    if self:
21245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#      self[0] = name
21345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#    else:
21445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#      self.append(name)
21545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#  name = property(get_name,set_name)
21645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
21745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def cstr(self,l=None):
21845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if l is None:
21945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            l=[]
22045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if len(self)>1:
22145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            assert len(self)==2
22245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            l.append( '%s = %s'%(self[0],self[1]) )
22345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        elif len(self)==1:
22445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            l.append( str(self[0]) )
22545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return " ".join(l)
22645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
22745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgclass TypeAlias(genpyx.TypeAlias, Named):
22845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    """
22945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org     typedefed things, eg. size_t
23045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
23145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    """
23245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def cbasetype( self ):
23345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        node = self.typedef.cbasetype().get_rest()
23445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return node
23545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
23645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgclass Function(genpyx.Function, Node):
23745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    """
23845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    """
23945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    #def explain(self):
24045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        #if len(self):
24145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            #return "function (%s), returning"%\
24245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                #", ".join( map(lambda x:x.explain(),self) )
24345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        #else:
24445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            #return "function returning"
24545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
24645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def cstr(self,l):
24745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        #print '%s.cstr(%s)'%(self,l)
24845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        _l=[]
24945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        assert len(self)
25045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        i=0
25145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        while isinstance(self[i],Declarator):
25245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            _l.append( self[i].cstr() )
25345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            i=i+1
25445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        l.append( '(%s)'% ', '.join(_l) )
25545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        while i<len(self):
25645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            self[i].cstr(l)
25745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            i=i+1
25845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return " ".join(l)
25945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
26045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def return_type(self):
26145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        node = self[-1]
26245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        #assert isinstance(node,DeclarationSpecifiers)
26345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return Declarator( Identifier(), node )
26445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    ret = property(return_type)
26545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
26645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def get_args(self):
26745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        args = [ arg for arg in self[:-1] if not arg.is_void() ]
26845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return args
26945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    args = property(get_args)
27045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
27145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def arg_types(self):
27245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return [ AbstractDeclarator().init_from( arg.ctype() ) for arg in self[:-1]]
27345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
27445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def is_varargs(self):
27545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        for node in self.nodes():
27645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            if isinstance(node,Ellipses) or 'va_list' in node:
27745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#        print self, 'is_varargs'
27845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                return True
27945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#    print self, 'is_varargs'
28045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return False
28145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#    return fn.deepfind(Ellipses) or fn.deepfind('va_list')
28245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
28345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def ctype(self):
28445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return Function(*self.arg_types()+[self[-1]]) # XX self[-1].ctype
28545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
28645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
28745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgclass Pointer(genpyx.Pointer, Node):
28845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    """
28945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    """
29045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def get_spec(self):
29145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if type(self[0])==TypeSpecifiers: # isinstance ??
29245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            return self[0]
29345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    spec = property(get_spec)
29445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
29545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    #def explain(self):
29645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        #return "pointer to"
29745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
29845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def cstr(self,l):
29945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        assert len(self)
30045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        node=self[0]
30145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        l.insert(0,'*')
30245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if isinstance(node,Function):
30345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            l.insert(0,'(')
30445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            l.append(')')
30545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        elif isinstance(node,Array):
30645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            l.insert(0,'(')
30745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            l.append(')')
30845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return Node.cstr(self,l)
30945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
31045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgclass Array(genpyx.Array, Node):
31145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    """
31245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    """
31345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    #def explain(self):
31445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        #s=''
31545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        #if len(self):
31645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            #if type(self[0])==int:
31745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                #s='0 to %s '%(self[0]-1)
31845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        #return "array %sof"%s
31945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def has_size(self):
32045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        try:
32145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            int(self.size)
32245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            return True
32345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        except:
32445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            return False
32545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
32645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def get_size(self):
32745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if type(self[-1])==str:
32845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            try: return int(self[-1])
32945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            except: return self[-1]
33045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return self[-1] # None
33145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    size = property(get_size)
33245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
33345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def get_spec(self):
33445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if type(self[0])==TypeSpecifiers: # isinstance ??
33545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            return self[0]
33645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    spec = property(get_spec)
33745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
33845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def to_pointer(self):
33945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        node = Pointer()
34045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        node.init_from( self.clone() )
34145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        node.pop() # pop the size element
34245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return node
34345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
34445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def cstr(self,l):
34545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if self.size is None:
34645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            l.append('[]')
34745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        else:
34845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            l.append('[%s]'%self.size)
34945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return Node( *self[:-1] ).cstr( l )
35045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
35145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgclass Tag(genpyx.Tag, Named):
35245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    " the tag of a Struct, Union or Enum "
35345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    pass
35445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
35545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgclass Taged(genpyx.Taged, Node):
35645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    "Struct, Union or Enum "
35745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def get_tag(self):
35845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if len(self):
35945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            tag = self[0]
36045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            assert type(tag)==Tag # isinstance ??
36145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        else:
36245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            tag = None
36345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return tag
36445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def set_tag(self,tag):
36545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if len(self):
36645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            self[0] = tag
36745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        else:
36845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            self.append(tag)
36945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    tag = property( get_tag, set_tag )
37045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def has_members(self):
37145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return len(self)>1 # more than just a tag
37245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def get_members(self):
37345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return self[1:]
37445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    members = property(get_members) # fields ?
37545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
37645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def ctype(self):
37745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if not self.tag.name:
37845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            #print "# WARNING : anonymous struct " # OK i think
37945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            return self.clone()
38045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#    self = self.clone()
38145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#    return self[:1] # just the tag
38245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return self.__class__( self.tag, **self.__dict__ ) # just the Tag
38345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#    return self.__class__( *self, **self.__dict__ )
38445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
38545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def cbasetype(self):
38645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return self.ctype() # is this enough ???
38745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#    return Node.cbasetype(self) # XX lookup my tag if i am empty ..?
38845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
38945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
39045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgclass Compound(genpyx.Compound, Taged):
39145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    "Struct or Union"
39245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
39345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def cstr(self,_l=None):
39445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        assert isinstance( self[0], Tag )
39545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        tag=''
39645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if len(self[0]):
39745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            tag=' '+self[0][0]
39845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if isinstance(self,Struct):
39945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            l=[ 'struct%s '%tag ]
40045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        elif isinstance(self,Union):
40145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            l=[ 'union%s '%tag ]
40245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if len(self)>1:
40345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            l.append(' { ')
40445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            for decl in self[1:]:
40545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                l.append( decl.cstr()+"; " )
40645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            l.append('} ')
40745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if _l is None:
40845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            _l=[]
40945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        while l:
41045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            _l.insert( 0, l.pop() )
41145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        # XX empty struct with no tag -> "struct" XX
41245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return "".join( _l )
41345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
41445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def ctype(self):
41545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        tp = Taged.ctype(self)
41645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        for i in range(1,len(tp)):
41745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            tp[i] = StructDeclarator().init_from( tp[i] )
41845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return tp
41945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
42045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgclass Struct(genpyx.Struct, Compound):
42145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    """
42245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    """
42345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    pass
42445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
42545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
42645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgclass Union(genpyx.Union, Compound):
42745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    """
42845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    """
42945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    pass
43045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
43145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
43245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgclass Enum(genpyx.Enum, Taged):
43345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    """
43445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    """
43545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def cstr(self,_l=None):
43645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        assert isinstance( self[0], Tag )
43745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        tag=''
43845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if len(self[0]):
43945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            tag=' '+self[0][0]
44045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        l=[ 'enum%s '%tag ]
44145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if len(self)>1:
44245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            l.append(' { ')
44345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            for node in self[1:]:
44445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                l.append( node.cstr()+', ' )
44545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            l.append('} ')
44645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if _l is None:
44745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            _l=[]
44845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        while l:
44945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            _l.insert( 0, l.pop() )
45045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return ''.join( _l )
45145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
45245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgclass Declarator(genpyx.Declarator, Node):
45345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    """
45445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    """
45545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
45645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def __eq__(self,other):
45745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        " unordered equality "
45845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        # ordering sometimes gets lost when we do a cbasetype
45945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if not isinstance(other,Node):
46045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            return False
46145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        a, b = self[:], other[:]
46245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        a.sort()
46345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        b.sort()
46445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return a == b
46545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
46645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def __hash__( self ):
46745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        hs = [hash(item) for item in self]
46845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        hs.sort()
46945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return hash( tuple([hash(type(self))]+hs) )
47045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
47145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def transform(self):
47245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return
47345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
47445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def get_identifier(self):
47545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if len(self)>1:
47645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            return self[0]
47745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def set_identifier(self, identifier):
47845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if len(self)>1:
47945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            self[0] = identifier
48045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        else:
48145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            self.insert(0,identifier)
48245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    identifier = property(get_identifier,set_identifier)
48345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
48445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def get_spec(self):
48545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        spec = self[-1]
48645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if type(spec)==TypeSpecifiers: # isinstance ??
48745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            return spec
48845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    spec = property(get_spec)
48945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
49045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def get_type_alias(self):
49145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if self.spec:
49245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            if isinstance(self.spec[0], TypeAlias):
49345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                return self.spec[0]
49445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    type_alias = property(get_type_alias)
49545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
49645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def get_tagged(self):
49745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if self.spec:
49845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            return self.spec.tagged # i am a tagged
49945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    tagged = property(get_tagged)
50045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
50145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def get_compound(self):
50245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if self.spec:
50345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            return self.spec.compound # i am a compound
50445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    compound = property(get_compound)
50545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
50645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def get_struct(self):
50745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if self.spec:
50845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            return self.spec.struct # i am a struct
50945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    struct = property(get_struct)
51045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
51145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def get_union(self):
51245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if self.spec:
51345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            return self.spec.union # i am a union
51445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    union = property(get_union)
51545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
51645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def get_enum(self):
51745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if self.spec:
51845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            return self.spec.enum # i am an enum
51945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    enum = property(get_enum)
52045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
52145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def get_function(self):
52245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if len(self)>1 and type(self[1])==Function: # isinstance ??
52345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            return self[1]
52445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    function = property(get_function)
52545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
52645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def get_pointer(self):
52745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if len(self)>1 and type(self[1])==Pointer: # isinstance ??
52845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            return self[1]
52945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    pointer = property(get_pointer)
53045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
53145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def get_array(self):
53245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if len(self)>1 and type(self[1])==Array: # isinstance ??
53345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            return self[1]
53445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    array = property(get_array)
53545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
53645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def get_name(self):
53745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if self.identifier:
53845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            return self.identifier.name
53945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def set_name(self, name):
54045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        assert self.identifier is not None
54145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        self.identifier.name = name
54245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    name = property(get_name, set_name)
54345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
54445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def get_rest(self): # XX needs a better name
54545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if len(self)>1:
54645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            return self[1]
54745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return self[0]
54845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
54945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def pointer_to( self ):
55045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        " return Declarator pointing to self's type "
55145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        decl = Declarator(Identifier(), Pointer(self.get_rest().clone()))
55245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return decl
55345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
55445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def deref( self ):
55545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        " return (clone of) Declarator that self is pointing to "
55645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        node = self.ctype() # clone
55745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        pointer = node.pointer or node.array
55845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        assert pointer, "cannot dereference non-pointer"
55945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        node[1:2] = pointer
56045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return node
56145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
56245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def is_void(self):
56345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return self.spec and BasicType('void') in self.spec
56445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
56545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def is_pointer_to_fn(self):
56645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return self.pointer and self.deref().function
56745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
56845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def is_pointer_to_char(self):
56945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#    return self.ctype() == TransUnit("char *a;").transform()[0].ctype()
57045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        node = self.pointer or self.array
57145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if node:
57245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            spec = node.spec
57345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            if spec and BasicType('char') in spec and not BasicType('unsigned') in spec:
57445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                return True
57545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return False
57645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
57745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def is_callback(self):
57845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        " i am a pointer to a function whose last arg is void* "
57945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if self.is_pointer_to_fn():
58045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            fn = self.deref().function
58145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            if fn.args:
58245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                arg = fn.args[-1]
58345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                if arg.pointer and arg.deref().is_void():
58445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    return True
58545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
58645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def is_complete( self, tag_lookup ):
58745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if self.tagged and self.tagged.tag.name in tag_lookup and not tag_lookup[self.tagged.tag.name].has_members():
58845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            return False
58945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return True
59045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
59145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def is_primative( self ):
59245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        "i am a char,short,int,float,double... "
59345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        spec = self.cbasetype().spec
59445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return spec and spec.find(BasicType)
59545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
59645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def is_pyxnative( self ):
59745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        # pyrex handles char* too
59845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        # but i don't know if we should make this the default
59945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        # sometimes we want to send a NULL, so ... XXX
60045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        self = self.cbasetype()
60145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if self.is_void():
60245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            return False
60345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if self.is_primative():
60445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            return True
60545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if self.enum:
60645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            return True
60745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#    pointer = None
60845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#    if self.pointer:
60945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#      pointer = self.pointer
61045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#    elif self.array:
61145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#      pointer = self.array
61245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#    if pointer and pointer.spec:
61345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#      spec = pointer.spec
61445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#      if BasicType("char") in spec and not Qualifier("unsigned") in spec:
61545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#        # char*, const char*
61645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org##        print self.deepstr()
61745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#        return True
61845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return False
61945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
62045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def cstr(self,l=None):
62145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return Node.cstr(self,l).strip()
62245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
62345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def ctype(self):
62445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        decl=Declarator()
62545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        decl.init_from( self.clone() )
62645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        decl.identifier = Identifier()
62745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        for i in range(1,len(decl)):
62845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            decl[i]=decl[i].ctype()
62945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return decl
63045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
63145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def cbasetype(self):
63245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        # WARNING: we cache results (so do not mutate self!!)
63345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        try:
63445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            # this cache improves performance by 50%
63545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            return self.__cbasetype.clone()
63645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        except AttributeError:
63745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            pass
63845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        decl = self.ctype() # gets rid of Identifier names
63945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        for i, node in enumerate(decl):
64045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            decl[i] = decl[i].cbasetype()
64145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#    return decl.get_rest()
64245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
64345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        done = False
64445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        while not done:
64545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            done = True
64645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            nodes = decl.deepfilter( TypeSpecifiers )
64745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            for node in nodes:
64845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                if node.deepfind( TypeSpecifiers ) != node:
64945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    # this node has another TypeSpecifier;
65045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    decl.expose_node( node )
65145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    done = False
65245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    break # start again...
65345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
65445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        # each TypeSpecifier needs to absorb primitive siblings (StorageClass, BasicType etc.)
65545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        nodes = decl.deepfilter( TypeSpecifiers )
65645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        for node in nodes:
65745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            parent = decl.get_parent(node)
65845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            i = 0
65945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            while i < len(parent):
66045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                assert not type(parent[i]) in (TypeAlias, Enum, Struct, Union)
66145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                if type(parent[i]) in (StorageClass, BasicType, Qualifier):
66245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    node.append( parent.pop(i) )
66345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                else:
66445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    i = i + 1
66545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
66645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        self.__cbasetype = decl.clone()
66745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return decl
66845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
66945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def invalidate(self):
67045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        # flush cache, etc.
67145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        try:
67245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            del self.__cbasetype
67345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        except AttributeError:
67445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            pass
67545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
67645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def declare_str(self,name):
67745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        " return c string declaring name with same type as self "
67845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        tp = self.ctype()
67945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        tp.name = name
68045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return tp.cstr()+";"
68145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
68245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgclass Typedef(genpyx.Typedef, Declarator):
68345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def cstr(self,l=None):
68445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return 'typedef ' + Declarator.cstr(self,l) #.strip()
68545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
68645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgclass AbstractDeclarator(genpyx.AbstractDeclarator, Declarator):
68745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    """ used in Function; may lack an identifier """
68845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
68945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    #def cstr(self,l=None):
69045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        #return Node.cstr(self,l)
69145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
69245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#  def ctype(self):
69345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#    # _type_ ignores the name of our identifier
69445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#    return Node.ctype(self)
69545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
69645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgclass FieldLength(genpyx.FieldLength, Node):
69745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    """
69845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    """
69945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    #def explain(self):
70045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        #return ""
70145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
70245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def cstr(self,l):
70345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        l.append(':%s'%self[0])
70445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
70545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgclass StructDeclarator(genpyx.StructDeclarator, Declarator): # also used in Union
70645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    """
70745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    """
70845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    #def explain(self):
70945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        #flen = self.find(FieldLength)
71045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        #if flen is not None:
71145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            #i = self.index(flen)
71245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            #self.pop(i)
71345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            #s = Declarator.explain(self)
71445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            #self.insert(i,flen)
71545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            #width = flen[0]
71645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            #if width > 0:
71745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                #return s+" bitfield %s wide"%width
71845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            #else:
71945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                #return s+" alignment bitfield"
72045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        #else:
72145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            #return Declarator.explain(self)
72245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#  def ctype(self):
72345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#    return self
72445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def get_field_length(self):
72545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if len(self)>1 and isinstance( self[1], FieldLength ):
72645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            return self[1]
72745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    field_length = property(get_field_length)
72845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
72945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
73045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgclass DeclarationSpecifiers(genpyx.DeclarationSpecifiers, Node):
73145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#class TypeSpecifiers(Node):
73245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    """
73345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    """
73445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def __eq__(self,other):
73545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        " unordered equality "
73645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if not isinstance(other,Node):
73745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            return False
73845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        a, b = self[:], other[:]
73945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        a.sort()
74045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        b.sort()
74145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return a == b
74245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
74345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def __hash__( self ):
74445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        hs = [hash(item) for item in self]
74545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        hs.sort()
74645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return hash( tuple([hash(type(self))]+hs) )
74745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
74845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#  def is_struct(self):
74945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#    return self.find(Struct) is not None
75045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
75145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
75245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgclass TypeSpecifiers(genpyx.TypeSpecifiers, DeclarationSpecifiers):
75345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    """
75445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    """
75545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def get_tagged(self):
75645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if self and isinstance(self[0],Taged):
75745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            return self[0]
75845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    tagged = property(get_tagged)
75945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
76045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def get_compound(self):
76145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if self and isinstance(self[0],Compound):
76245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            return self[0]
76345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    compound = property(get_compound)
76445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
76545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def get_struct(self):
76645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if self and isinstance(self[0],Struct):
76745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            return self[0]
76845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    struct = property(get_struct)
76945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
77045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def get_union(self):
77145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if self and isinstance(self[0],Union):
77245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            return self[0]
77345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    union = property(get_union)
77445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
77545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def get_enum(self):
77645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if self and isinstance(self[0],Enum):
77745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            return self[0]
77845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    enum = property(get_enum)
77945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
78045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def cbasetype(self):
78145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        node = Node.cbasetype(self)
78245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#    node.expose( TypeSpecifiers )
78345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#    if node.deepfind(TypeSpecifiers) != node:
78445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return node
78545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
78645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgclass Initializer(genpyx.Initializer, Node):
78745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    """
78845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    """
78945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    pass
79045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
79145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
79245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
79345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgclass Declaration(genpyx.Declaration, Node):
79445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    """
79545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    """
79645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def do_spec(self):
79745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        " distribute DeclarationSpecifiers over each Declarator "
79845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        spec=self[0]
79945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        assert isinstance(spec,DeclarationSpecifiers), spec.deepstr()
80045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        self.pop(0)
80145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        for declarator in self:
80245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            assert isinstance(declarator,Declarator)
80345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            #if isinstance(declarator,DeclarationSpecifiers #huh?
80445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            ##for node in spec:
80545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                ##declarator.append(node.clone())
80645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            declarator.append(spec)
80745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
80845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def transform(self):
80945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        # children go first
81045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        for node in self.nodes():
81145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            if isinstance(node,Declaration):
81245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                node.do_spec()
81345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            node.file = self.file # overkill ?
81445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        self.expose(Declaration)
81545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
81645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    #def explain(self):
81745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        #return string.join([x.explain() for x in self],", ")
81845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        #return string.join(map(lambda x:x.explain(),self),", ")
81945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
82045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
82145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgclass ParameterDeclaration(genpyx.ParameterDeclaration, Declaration):
82245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    """
82345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    """
82445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    pass
82545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
82645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
82745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgclass StructDeclaration(genpyx.StructDeclaration, Declaration):
82845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    """
82945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    """
83045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    pass
83145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
83245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
83345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgclass TransUnit(genpyx.TransUnit, Node):
83445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    """
83545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        Top level node.
83645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    """
83745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def __init__( self, item ): # XX __init__ uses different signature ! XX
83845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if type(item)==str:
83945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            node = cparse.TransUnit()
84045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            node.parse(item)
84145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        else:
84245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            node = item
84345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            assert isinstance( node, cparse.TransUnit ), str(node)
84445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        Node.__init__(self)
84545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        self[:] = [ self.convert(child) for child in node ]
84645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        self.__dict__.update( node.__dict__ )
84745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        assert "name" not in node.__dict__
84845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
84945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        self.syms = {} # map identifier names to their Declarator's
85045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        self.typedefs = {} # map names to Typedef's
85145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        self.tag_lookup = {} # map struct, union, enum tags to Taged's
85245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
85345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        # XX should call transform here XX
85445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
85545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#    print self.deepstr()
85645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def __getstate__( self ):
85745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        nodes = tuple( [ repr(node) for node in self ] )
85845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        typedefs = tuple( [ (key,repr(val)) for key,val in self.typedefs.items() ] )
85945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return nodes, typedefs
86045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def __setstate__( self, state ):
86145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        Node.__init__(self)
86245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        nodes, typedefs = state
86345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        nodes = [ eval(node) for node in nodes ]
86445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        self[:] = nodes
86545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        typedefs = [ (key,eval(val)) for key,val in typedefs ]
86645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        self.typedefs = dict(typedefs)
86745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
86845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def convert( self, node ):
86945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#    name = node.__class__.__name__
87045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#    cls = globals()[ name ]
87145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        cls = cls_lookup[ type(node) ]
87245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        _node = cls()
87345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        for child in node:
87445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            if isinstance(child, node_module.Node):
87545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                child = self.convert( child )
87645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            else:
87745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                assert child is None or type(child) in (str, int), type(child)
87845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            _node.append( child )
87945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        _node.__dict__.update( node.__dict__ )
88045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return _node
88145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
88245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def strip(self,files):
88345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        " leave only the declarations from <files> "
88445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        i=0
88545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        while i<len(self):
88645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            if self[i].file in files:
88745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                i=i+1
88845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            else:
88945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                self.pop(i)
89045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
89145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def mark(self,cb,verbose=False):
89245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        " mark our child nodes such that cb(node).. mark dependants too. prune unmarked objects. "
89345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        # mark the nodes:
89445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        for node in self:
89545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            node.marked = cb(self, node)
89645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            if verbose and node.marked:
89745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                print '1:', node.cstr()
89845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        # propagate dependancy:
89945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        i=len(self)
90045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        while i:
90145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            i-=1 # we go backwards
90245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            for node in self[i].nodes(): # bottom-up search
90345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                if verbose and self[i].marked and not node.marked:
90445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    print '2:', str(node), '<--', self[i].cstr()
90545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                node.marked = self[i].marked or node.marked
90645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                if type(node)==TypeAlias:
90745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    if verbose and node.marked and not node.typedef.marked:
90845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                        print '3:', node.typedef.cstr(), '<--', node.cstr()
90945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    node.typedef.marked = node.typedef.marked or node.marked
91045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                if isinstance(node, Taged):
91145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    if node.tag.name in self.tag_lookup:
91245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                        _node = self.tag_lookup[ node.tag.name ] # look-up the def'n
91345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                        if verbose and node.marked and not _node.marked:
91445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                            print '4:', _node.cstr(), '<--', self[i].cstr()
91545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#            _node.marked = _node.marked or self[i].marked
91645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                        _node.marked = _node.marked or node.marked
91745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#          else:
91845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#            # this guy has no tag
91945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#            print "lost tag:", self[i].cstr()
92045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
92145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                 # XX struct defs acquire marks from members, but XX
92245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                 # XX ordinary definitions do not                 XX
92345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#        if node.marked and not self[i].marked:
92445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#          # one of my descendants is marked
92545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#          if verbose:
92645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#            print '5:', self[i].cstr(), '<--', node.cstr()
92745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#          self[i].marked = True
92845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#    if verbose:
92945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#      for node in self:
93045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#        print '-'*79
93145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#        if node.enum:
93245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#          print str(node.marked) + ': ' + node.cstr()
93345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        # prune:
93445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        f = open(".tmp/pruned.txt","w")
93545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        f.write("// This file autogenerated by '%s' .\n"%__file__)
93645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        f.write("// List of functions pruned from parse tree, for various reasons.\n\n")
93745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        i=0
93845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        while i<len(self):
93945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            if not self[i].marked:
94045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                if verbose: print 'pop:', self[i].cstr()
94145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                f.write( self[i].cstr() + "\n" )
94245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                self.pop(i)
94345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#      elif self[i].compound:
94445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#        # XXXX for now, rip out all struct members XXXX
94545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#        self[i].compound[1:] = [] # XX encapsulation
94645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#        i = i + 1
94745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            else:
94845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                i = i + 1
94945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        for key, value in self.syms.items():
95045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            if not value.marked:
95145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                del self.syms[key]
95245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        for key, value in self.typedefs.items():
95345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            if not value.marked:
95445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                del self.typedefs[key]
95545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        for key, value in self.tag_lookup.items():
95645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            if not value.marked:
95745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                del self.tag_lookup[key]
95845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#    sys.exit(1)
95945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
96045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def assert_no_dups(self):
96145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        check={}
96245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        for node in self.nodes():
96345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            assert not check.has_key(id(node))
96445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            check[id(node)]=1
96545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
96645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def transform(self, verbose=False, test_parse=False, test_types=False ):
96745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        i=0
96845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        while i < len(self):
96945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            if verbose: print "##"*25
97045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            declaration=self[i]
97145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
97245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            if verbose: declaration.psource()
97345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            if verbose: print declaration.deepstr(),'\n'
97445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            assert isinstance(declaration,Declaration)
97545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            if verbose: print "# expose declarators from declaration"
97645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
97745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            # STAGE 1
97845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            declaration.transform()
97945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
98045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            if verbose: print declaration.deepstr(),'\n'
98145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            self[i:i+1] = declaration # expose declarators from declaration
98245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
98345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            for j in range(len(declaration)):
98445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                declarator=self[i]
98545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
98645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                assert isinstance(declarator,Declarator)
98745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                if verbose: print "# declarator.transform()"
98845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
98945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                # STAGE 2
99045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                declarator.transform()
99145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
99245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                if verbose: print declarator.deepstr(),'\n'
99345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                if verbose: print "# self.visit_declarator(declarator)"
99445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
99545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                # STAGE 3
99645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                self[i] = declarator = self.visit_declarator(declarator)
99745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
99845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                # STAGE 4
99945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                if declarator.name:
100045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    if isinstance(declarator, Typedef):
100145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                        if verbose: print "# typedef %s" % declarator.name
100245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                        self.typedefs[ declarator.name ] = declarator
100345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    else:
100445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                        if verbose: print "# sym %s" % declarator.name
100545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                        self.syms[ declarator.name ] = declarator
100645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
100745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                for node in declarator.nodes():
100845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    if isinstance(node,Taged) and node.tag.name:
100945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                        assert type(node.tag.name)==str, node.deepstr()
101045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                        taged = self.tag_lookup.get( node.tag.name, None )
101145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                        if taged is None:
101245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                            if verbose: print "# tag lookup %s = %s" % (declarator.name, node.tag.name)
101345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                            self.tag_lookup[ node.tag.name ] = node
101445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                        elif not taged.has_members():
101545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                            # this is (maybe) the definition of this tag
101645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                            if verbose: print "# definition %s = %s" % (declarator.name, node.tag.name)
101745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                            self.tag_lookup[ node.tag.name ] = node
101845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
101945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                # Annotate the TypeAlias's
102045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                for node in declarator.deepfilter( TypeAlias ):
102145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    name = node[0]
102245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    assert type( name ) == str
102345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    node.typedef = self.typedefs[ name ]
102445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
102545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                if verbose: print declarator.deepstr(),'\n'
102645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                #print declarator.ctype().deepstr(),'\n'
102745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                #assert declarator.clone() == declarator
102845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
102945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                ###################################################
103045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                # TESTS:
103145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                if test_parse:
103245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    # test that parse of cstr gives same answer
103345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    cstr = declarator.cstr()+';\n'
103445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    if verbose: print '# '+cstr.replace('\n','\n# ')
103545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    #print
103645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    if isinstance(declarator,Typedef):
103745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                        name = declarator[0][0]
103845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                        assert type(name)==str
103945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                        self.lexer.rmtypedef( name )
104045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    declaration = cparse.Declaration()
104145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    self.lexer.lex( cstr )
104245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    #print self.lexer.err_string()
104345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    declaration.parse(  self.lexer, Symbols() ) # use new name-space
104445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    #declaration.parse(  Lexer( cstr ), Symbols() )
104545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    declaration = self.convert(declaration)
104645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    declaration.transform()
104745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    assert len(declaration)==1
104845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    decl=declaration[0]
104945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    decl.transform()
105045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    decl = self.visit_declarator(decl)
105145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    if decl!=declarator:
105245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                        if verbose: print "#???????????"
105345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                        if verbose: print decl.deepstr(),'\n\n'
105445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                        #if verbose: print declaration.deepstr(),'\n\n'
105545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                        #assert 0
105645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    elif verbose: print '# OK\n'
105745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
105845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                if test_types:
105945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    node = declarator.ctype()
106045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    declare_str= node.declare_str("my_name")
106145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    if verbose: print "# declarator.ctype() "
106245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    if verbose: print node.deepstr(),"\n"
106345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    if verbose: print "#",declare_str.replace('\n','\n# '), '\n'
106445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
106545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                i=i+1
106645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return self
106745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
106845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def visit(self,node):
106945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        #print 'visit(%s)'%node
107045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        for _node in node:
107145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            if isinstance(_node,Declarator):
107245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                _node = self.visit_declarator(_node) # XX replace _node
107345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            elif isinstance(_node,Node):
107445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                _node = self.visit(_node) # XX replace _node
107545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return node
107645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
107745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def visit_declarator(self,decl):
107845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        assert isinstance(decl,Declarator)
107945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
108045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        # STAGE 3.a
108145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        tp = decl.deepfind(Typedef)
108245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if tp is not None:
108345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            decl.deeprm(tp)
108445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            tp.init_from( decl ) # warning: shallow init
108545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            decl = tp
108645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
108745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        # STAGE 3.b
108845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        i=len(decl)
108945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        # accumulate nodes (they become the children of decl)
109045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        children=[]
109145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        while i:
109245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            i=i-1
109345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            node=decl.pop(i)
109445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            if isinstance(node,Declarator):
109545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                node = self.visit_declarator(node) # replace node
109645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            else:
109745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                node = self.visit(node) # replace node
109845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            if isinstance(node,Pointer):
109945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                node+=children
110045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                children=[node]
110145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            elif isinstance(node,Function):
110245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                node+=children
110345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                children=[node]
110445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            elif isinstance(node,Array):
110545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                while children:
110645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    node.insert(0,children.pop())
110745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                children=[node]
110845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                # array size (if any) at end
110945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            #elif isinstance(node,Identifier):
111045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                #node+=children
111145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                #children=[node]
111245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            else:
111345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                # accumulate
111445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                children.insert(0,node)
111545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        decl[:]=children
111645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return decl
111745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
111845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cstr = None
111945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    ctype = None
112045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cbasetype = None
112145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
112245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
112345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org# remap the global class definitions in genpyx to
112445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org# point to the definitions in this module
112545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orggbl = globals()
112645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgfor key, val in gbl.items():
112745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if type(val)==type:
112845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if issubclass(val,Node):
112945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            setattr( genpyx, key, val )
113045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgassert genpyx.Node == Node
113145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
113245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgcls_lookup = {
113345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#  Node : Node ,
113445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cparse.BasicType : BasicType ,
113545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cparse.Qualifier : Qualifier ,
113645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cparse.StorageClass : StorageClass ,
113745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cparse.Ellipses : Ellipses ,
113845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cparse.GCCBuiltin : GCCBuiltin ,
113945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cparse.Identifier : Identifier ,
114045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cparse.TypeAlias : TypeAlias ,
114145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cparse.Function : Function ,
114245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cparse.Pointer : Pointer ,
114345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cparse.Array : Array ,
114445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cparse.Tag : Tag ,
114545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cparse.Compound : Compound ,
114645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cparse.Struct : Struct ,
114745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cparse.Union : Union ,
114845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cparse.Enum : Enum ,
114945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cparse.Declarator : Declarator ,
115045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cparse.Typedef : Typedef ,
115145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cparse.AbstractDeclarator : AbstractDeclarator ,
115245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cparse.FieldLength : FieldLength ,
115345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cparse.StructDeclarator : StructDeclarator ,
115445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cparse.DeclarationSpecifiers : TypeSpecifiers ,
115545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cparse.TypeSpecifiers : TypeSpecifiers ,
115645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cparse.Initializer : Initializer ,
115745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cparse.Declaration : Declaration ,
115845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cparse.ParameterDeclaration : ParameterDeclaration ,
115945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cparse.StructDeclaration : StructDeclaration ,
116045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cparse.TransUnit : TransUnit ,
116145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
116245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
116345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
1164