1 """Flexible enumeration of C types."""
3 from Enumeration
import *
7 # - struct improvements (flexible arrays, packed &
9 # - objective-c qualified id
10 # - anonymous / transparent unions
14 # - pass arguments of different types (test extension, transparent union)
24 def isPaddingBitField(self
):
27 def getTypeName(self
, printer
):
28 name
= 'T%d' % len(printer
.types
)
29 typedef
= self
.getTypedefDef(name
, printer
)
30 printer
.addDeclaration(typedef
)
33 class BuiltinType(Type
):
34 def __init__(self
, name
, size
, bitFieldSize
=None):
37 self
.bitFieldSize
= bitFieldSize
40 return self
.bitFieldSize
is not None
42 def isPaddingBitField(self
):
43 return self
.bitFieldSize
is 0
45 def getBitFieldSize(self
):
46 assert self
.isBitField()
47 return self
.bitFieldSize
49 def getTypeName(self
, printer
):
59 def __init__(self
, index
, enumerators
):
61 self
.enumerators
= enumerators
63 def getEnumerators(self
):
65 for i
, init
in enumerate(self
.enumerators
):
67 result
= result
+ ', '
68 result
= result
+ 'enum%dval%d' % (self
.index
, i
)
70 result
= result
+ ' = %s' % (init
)
75 return 'enum { %s }' % (self
.getEnumerators())
77 def getTypedefDef(self
, name
, printer
):
78 return 'typedef enum %s { %s } %s;'%(name
, self
.getEnumerators(), name
)
80 class RecordType(Type
):
81 def __init__(self
, index
, isUnion
, fields
):
83 self
.isUnion
= isUnion
90 return "%s : %d;" % (t
, t
.getBitFieldSize())
94 return '%s { %s }'%(('struct','union')[self
.isUnion
],
95 ' '.join(map(getField
, self
.fields
)))
97 def getTypedefDef(self
, name
, printer
):
100 if t
.isPaddingBitField():
101 return '%s : 0;'%(printer
.getTypeName(t
),)
103 return '%s field%d : %d;'%(printer
.getTypeName(t
),i
,
106 return '%s field%d;'%(printer
.getTypeName(t
),i
)
107 fields
= map(getField
, enumerate(self
.fields
))
108 # Name the struct for more readable LLVM IR.
109 return 'typedef %s %s { %s } %s;'%(('struct','union')[self
.isUnion
],
110 name
, ' '.join(fields
), name
)
112 class ArrayType(Type
):
113 def __init__(self
, index
, isVector
, elementType
, size
):
115 # Note that for vectors, this is the size in bytes.
118 assert size
is None or size
>= 0
120 self
.isVector
= isVector
121 self
.elementType
= elementType
124 eltSize
= self
.elementType
.sizeof()
125 assert not (self
.size
% eltSize
)
126 self
.numElements
= self
.size
// eltSize
128 self
.numElements
= self
.size
132 return 'vector (%s)[%d]'%(self
.elementType
,self
.size
)
133 elif self
.size
is not None:
134 return '(%s)[%d]'%(self
.elementType
,self
.size
)
136 return '(%s)[]'%(self
.elementType
,)
138 def getTypedefDef(self
, name
, printer
):
139 elementName
= printer
.getTypeName(self
.elementType
)
141 return 'typedef %s %s __attribute__ ((vector_size (%d)));'%(elementName
,
145 if self
.size
is None:
148 sizeStr
= str(self
.size
)
149 return 'typedef %s %s[%s];'%(elementName
, name
, sizeStr
)
151 class ComplexType(Type
):
152 def __init__(self
, index
, elementType
):
154 self
.elementType
= elementType
157 return '_Complex (%s)'%(self
.elementType
)
159 def getTypedefDef(self
, name
, printer
):
160 return 'typedef _Complex %s %s;'%(printer
.getTypeName(self
.elementType
), name
)
162 class FunctionType(Type
):
163 def __init__(self
, index
, returnType
, argTypes
):
165 self
.returnType
= returnType
166 self
.argTypes
= argTypes
169 if self
.returnType
is None:
172 rt
= str(self
.returnType
)
173 if not self
.argTypes
:
176 at
= ', '.join(map(str, self
.argTypes
))
177 return '%s (*)(%s)'%(rt
, at
)
179 def getTypedefDef(self
, name
, printer
):
180 if self
.returnType
is None:
183 rt
= str(self
.returnType
)
184 if not self
.argTypes
:
187 at
= ', '.join(map(str, self
.argTypes
))
188 return 'typedef %s (*%s)(%s);'%(rt
, name
, at
)
193 class TypeGenerator(object):
197 def setCardinality(self
):
201 T
= self
.cache
.get(N
)
203 assert 0 <= N
< self
.cardinality
204 T
= self
.cache
[N
] = self
.generateType(N
)
207 def generateType(self
, N
):
210 class FixedTypeGenerator(TypeGenerator
):
211 def __init__(self
, types
):
212 TypeGenerator
.__init
__(self
)
214 self
.setCardinality()
216 def setCardinality(self
):
217 self
.cardinality
= len(self
.types
)
219 def generateType(self
, N
):
230 # Compute the number of combinations (n choose k)
231 def num_combinations(n
, k
):
232 return fact(n
) / (fact(k
) * fact(n
- k
))
234 # Enumerate the combinations choosing k elements from the list of values
235 def combinations(values
, k
):
236 # From ActiveState Recipe 190465: Generator for permutations,
237 # combinations, selections of a sequence
240 for i
in xrange(len(values
)-k
+1):
241 for cc
in combinations(values
[i
+1:],k
-1):
244 class EnumTypeGenerator(TypeGenerator
):
245 def __init__(self
, values
, minEnumerators
, maxEnumerators
):
246 TypeGenerator
.__init
__(self
)
248 self
.minEnumerators
= minEnumerators
249 self
.maxEnumerators
= maxEnumerators
250 self
.setCardinality()
252 def setCardinality(self
):
254 for num
in range(self
.minEnumerators
, self
.maxEnumerators
+ 1):
255 self
.cardinality
+= num_combinations(len(self
.values
), num
)
257 def generateType(self
, n
):
258 # Figure out the number of enumerators in this type
259 numEnumerators
= self
.minEnumerators
261 while numEnumerators
< self
.maxEnumerators
:
262 comb
= num_combinations(len(self
.values
), numEnumerators
)
263 if valuesCovered
+ comb
> n
:
265 numEnumerators
= numEnumerators
+ 1
266 valuesCovered
+= comb
268 # Find the requested combination of enumerators and build a
271 for enumerators
in combinations(self
.values
, numEnumerators
):
272 if i
== n
- valuesCovered
:
273 return EnumType(n
, enumerators
)
279 class ComplexTypeGenerator(TypeGenerator
):
280 def __init__(self
, typeGen
):
281 TypeGenerator
.__init
__(self
)
282 self
.typeGen
= typeGen
283 self
.setCardinality()
285 def setCardinality(self
):
286 self
.cardinality
= self
.typeGen
.cardinality
288 def generateType(self
, N
):
289 return ComplexType(N
, self
.typeGen
.get(N
))
291 class VectorTypeGenerator(TypeGenerator
):
292 def __init__(self
, typeGen
, sizes
):
293 TypeGenerator
.__init
__(self
)
294 self
.typeGen
= typeGen
295 self
.sizes
= tuple(map(int,sizes
))
296 self
.setCardinality()
298 def setCardinality(self
):
299 self
.cardinality
= len(self
.sizes
)*self
.typeGen
.cardinality
301 def generateType(self
, N
):
302 S
,T
= getNthPairBounded(N
, len(self
.sizes
), self
.typeGen
.cardinality
)
303 return ArrayType(N
, True, self
.typeGen
.get(T
), self
.sizes
[S
])
305 class FixedArrayTypeGenerator(TypeGenerator
):
306 def __init__(self
, typeGen
, sizes
):
307 TypeGenerator
.__init
__(self
)
308 self
.typeGen
= typeGen
309 self
.sizes
= tuple(size
)
310 self
.setCardinality()
312 def setCardinality(self
):
313 self
.cardinality
= len(self
.sizes
)*self
.typeGen
.cardinality
315 def generateType(self
, N
):
316 S
,T
= getNthPairBounded(N
, len(self
.sizes
), self
.typeGen
.cardinality
)
317 return ArrayType(N
, false
, self
.typeGen
.get(T
), self
.sizes
[S
])
319 class ArrayTypeGenerator(TypeGenerator
):
320 def __init__(self
, typeGen
, maxSize
, useIncomplete
=False, useZero
=False):
321 TypeGenerator
.__init
__(self
)
322 self
.typeGen
= typeGen
323 self
.useIncomplete
= useIncomplete
324 self
.useZero
= useZero
325 self
.maxSize
= int(maxSize
)
326 self
.W
= useIncomplete
+ useZero
+ self
.maxSize
327 self
.setCardinality()
329 def setCardinality(self
):
330 self
.cardinality
= self
.W
* self
.typeGen
.cardinality
332 def generateType(self
, N
):
333 S
,T
= getNthPairBounded(N
, self
.W
, self
.typeGen
.cardinality
)
334 if self
.useIncomplete
:
345 return ArrayType(N
, False, self
.typeGen
.get(T
), size
)
347 class RecordTypeGenerator(TypeGenerator
):
348 def __init__(self
, typeGen
, useUnion
, maxSize
):
349 TypeGenerator
.__init
__(self
)
350 self
.typeGen
= typeGen
351 self
.useUnion
= bool(useUnion
)
352 self
.maxSize
= int(maxSize
)
353 self
.setCardinality()
355 def setCardinality(self
):
356 M
= 1 + self
.useUnion
357 if self
.maxSize
is aleph0
:
358 S
= aleph0
* self
.typeGen
.cardinality
361 for i
in range(self
.maxSize
+1):
362 S
+= M
* (self
.typeGen
.cardinality
** i
)
365 def generateType(self
, N
):
368 isUnion
,I
= (I
&1),I
>>1
369 fields
= map(self
.typeGen
.get
,getNthTuple(I
,self
.maxSize
,self
.typeGen
.cardinality
))
370 return RecordType(N
, isUnion
, fields
)
372 class FunctionTypeGenerator(TypeGenerator
):
373 def __init__(self
, typeGen
, useReturn
, maxSize
):
374 TypeGenerator
.__init
__(self
)
375 self
.typeGen
= typeGen
376 self
.useReturn
= useReturn
377 self
.maxSize
= maxSize
378 self
.setCardinality()
380 def setCardinality(self
):
381 if self
.maxSize
is aleph0
:
382 S
= aleph0
* self
.typeGen
.cardinality()
385 for i
in range(1,self
.maxSize
+1+1):
386 S
+= self
.typeGen
.cardinality
** i
389 for i
in range(self
.maxSize
+1):
390 S
+= self
.typeGen
.cardinality
** i
393 def generateType(self
, N
):
395 # Skip the empty tuple
396 argIndices
= getNthTuple(N
+1, self
.maxSize
+1, self
.typeGen
.cardinality
)
397 retIndex
,argIndices
= argIndices
[0],argIndices
[1:]
398 retTy
= self
.typeGen
.get(retIndex
)
401 argIndices
= getNthTuple(N
, self
.maxSize
, self
.typeGen
.cardinality
)
402 args
= map(self
.typeGen
.get
, argIndices
)
403 return FunctionType(N
, retTy
, args
)
405 class AnyTypeGenerator(TypeGenerator
):
407 TypeGenerator
.__init
__(self
)
410 self
.setCardinality()
411 self
._cardinality
= None
413 def getCardinality(self
):
414 if self
._cardinality
is None:
417 return self
._cardinality
418 def setCardinality(self
):
419 self
.bounds
= [g
.cardinality
for g
in self
.generators
]
420 self
._cardinality
= sum(self
.bounds
)
421 cardinality
= property(getCardinality
, None)
423 def addGenerator(self
, g
):
424 self
.generators
.append(g
)
426 prev
= self
._cardinality
427 self
._cardinality
= None
428 for g
in self
.generators
:
430 self
.setCardinality()
431 if (self
._cardinality
is aleph0
) or prev
==self
._cardinality
:
434 raise RuntimeError,"Infinite loop in setting cardinality"
436 def generateType(self
, N
):
437 index
,M
= getNthPairVariableBounds(N
, self
.bounds
)
438 return self
.generators
[index
].get(M
)
441 fbtg
= FixedTypeGenerator([BuiltinType('char', 4),
442 BuiltinType('char', 4, 0),
443 BuiltinType('int', 4, 5)])
445 fields1
= AnyTypeGenerator()
446 fields1
.addGenerator( fbtg
)
448 fields0
= AnyTypeGenerator()
449 fields0
.addGenerator( fbtg
)
450 # fields0.addGenerator( RecordTypeGenerator(fields1, False, 4) )
452 btg
= FixedTypeGenerator([BuiltinType('char', 4),
453 BuiltinType('int', 4)])
454 etg
= EnumTypeGenerator([None, '-1', '1', '1u'], 0, 3)
456 atg
= AnyTypeGenerator()
457 atg
.addGenerator( btg
)
458 atg
.addGenerator( RecordTypeGenerator(fields0
, False, 4) )
459 atg
.addGenerator( etg
)
460 print 'Cardinality:',atg
.cardinality
462 if i
== atg
.cardinality
:
465 raise RuntimeError,"Cardinality was wrong"
466 except AssertionError:
468 print '%4d: %s'%(i
, atg
.get(i
))
470 if __name__
== '__main__':