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