blob: c74d3111bca9aae9659d99be97c6fa2db7285bb6 [file] [log] [blame]
José Fonseca7ad40262009-09-30 17:17:12 +01001##########################################################################
José Fonseca95442442008-07-08 10:32:53 +09002#
José Fonseca6fac5ae2010-11-29 16:09:13 +00003# Copyright 2008-2010 VMware, Inc.
José Fonseca7ad40262009-09-30 17:17:12 +01004# All Rights Reserved.
José Fonseca95442442008-07-08 10:32:53 +09005#
José Fonseca7ad40262009-09-30 17:17:12 +01006# Permission is hereby granted, free of charge, to any person obtaining a copy
7# of this software and associated documentation files (the "Software"), to deal
8# in the Software without restriction, including without limitation the rights
9# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10# copies of the Software, and to permit persons to whom the Software is
11# furnished to do so, subject to the following conditions:
José Fonseca95442442008-07-08 10:32:53 +090012#
José Fonseca7ad40262009-09-30 17:17:12 +010013# The above copyright notice and this permission notice shall be included in
14# all copies or substantial portions of the Software.
José Fonseca95442442008-07-08 10:32:53 +090015#
José Fonseca7ad40262009-09-30 17:17:12 +010016# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22# THE SOFTWARE.
José Fonseca95442442008-07-08 10:32:53 +090023#
José Fonseca7ad40262009-09-30 17:17:12 +010024##########################################################################/
José Fonseca95442442008-07-08 10:32:53 +090025
José Fonsecad626cf42008-07-07 07:43:16 +090026"""C basic types"""
27
José Fonseca8a56d142008-07-09 12:18:08 +090028
29import debug
30
31
José Fonseca6fac5ae2010-11-29 16:09:13 +000032class Type:
José Fonseca02c25002011-10-15 13:17:26 +010033 """Base class for all types."""
José Fonseca6fac5ae2010-11-29 16:09:13 +000034
José Fonseca02c25002011-10-15 13:17:26 +010035 __tags = set()
José Fonseca6fac5ae2010-11-29 16:09:13 +000036
José Fonseca02c25002011-10-15 13:17:26 +010037 def __init__(self, expr, tag = None):
José Fonseca6fac5ae2010-11-29 16:09:13 +000038 self.expr = expr
José Fonseca6fac5ae2010-11-29 16:09:13 +000039
José Fonseca02c25002011-10-15 13:17:26 +010040 # Generate a default tag, used when naming functions that will operate
41 # on this type, so it should preferrably be something representative of
42 # the type.
43 if tag is None:
44 tag = ''.join([c for c in expr if c.isalnum() or c in '_'])
45 else:
46 for c in tag:
47 assert c.isalnum() or c in '_'
José Fonseca6fac5ae2010-11-29 16:09:13 +000048
José Fonseca02c25002011-10-15 13:17:26 +010049 # Ensure it is unique.
50 if tag in Type.__tags:
51 suffix = 1
52 while tag + str(suffix) in Type.__tags:
53 suffix += 1
54 tag += str(suffix)
55
56 assert tag not in Type.__tags
57 Type.__tags.add(tag)
58
59 self.tag = tag
José Fonseca6fac5ae2010-11-29 16:09:13 +000060
61 def __str__(self):
José Fonseca02c25002011-10-15 13:17:26 +010062 """Return the C/C++ type expression for this type."""
José Fonseca6fac5ae2010-11-29 16:09:13 +000063 return self.expr
64
65 def visit(self, visitor, *args, **kwargs):
66 raise NotImplementedError
67
68
69
70class _Void(Type):
José Fonseca02c25002011-10-15 13:17:26 +010071 """Singleton void type."""
José Fonseca6fac5ae2010-11-29 16:09:13 +000072
73 def __init__(self):
74 Type.__init__(self, "void")
75
76 def visit(self, visitor, *args, **kwargs):
José Fonseca54f304a2012-01-14 19:33:08 +000077 return visitor.visitVoid(self, *args, **kwargs)
José Fonseca6fac5ae2010-11-29 16:09:13 +000078
79Void = _Void()
80
81
82class Literal(Type):
José Fonseca2f2ea482011-10-15 15:10:06 +010083 """Class to describe literal types.
José Fonseca6fac5ae2010-11-29 16:09:13 +000084
José Fonseca2f2ea482011-10-15 15:10:06 +010085 Types which are not defined in terms of other types, such as integers and
86 floats."""
87
88 def __init__(self, expr, kind):
José Fonseca6fac5ae2010-11-29 16:09:13 +000089 Type.__init__(self, expr)
José Fonseca2f2ea482011-10-15 15:10:06 +010090 self.kind = kind
José Fonseca6fac5ae2010-11-29 16:09:13 +000091
92 def visit(self, visitor, *args, **kwargs):
José Fonseca54f304a2012-01-14 19:33:08 +000093 return visitor.visitLiteral(self, *args, **kwargs)
José Fonseca6fac5ae2010-11-29 16:09:13 +000094
95
96class Const(Type):
97
98 def __init__(self, type):
José Fonseca903c2ca2011-09-23 09:43:05 +010099 # While "const foo" and "foo const" are synonymous, "const foo *" and
100 # "foo * const" are not quite the same, and some compilers do enforce
101 # strict const correctness.
102 if isinstance(type, String) or type is WString:
103 # For strings we never intend to say a const pointer to chars, but
104 # rather a point to const chars.
105 expr = "const " + type.expr
106 elif type.expr.startswith("const ") or '*' in type.expr:
José Fonseca6fac5ae2010-11-29 16:09:13 +0000107 expr = type.expr + " const"
108 else:
José Fonseca903c2ca2011-09-23 09:43:05 +0100109 # The most legible
José Fonseca6fac5ae2010-11-29 16:09:13 +0000110 expr = "const " + type.expr
111
José Fonseca02c25002011-10-15 13:17:26 +0100112 Type.__init__(self, expr, 'C' + type.tag)
José Fonseca6fac5ae2010-11-29 16:09:13 +0000113
114 self.type = type
115
116 def visit(self, visitor, *args, **kwargs):
José Fonseca54f304a2012-01-14 19:33:08 +0000117 return visitor.visitConst(self, *args, **kwargs)
José Fonseca6fac5ae2010-11-29 16:09:13 +0000118
119
120class Pointer(Type):
121
122 def __init__(self, type):
José Fonseca02c25002011-10-15 13:17:26 +0100123 Type.__init__(self, type.expr + " *", 'P' + type.tag)
José Fonseca6fac5ae2010-11-29 16:09:13 +0000124 self.type = type
125
126 def visit(self, visitor, *args, **kwargs):
José Fonseca54f304a2012-01-14 19:33:08 +0000127 return visitor.visitPointer(self, *args, **kwargs)
José Fonseca6fac5ae2010-11-29 16:09:13 +0000128
129
José Fonseca59ee88e2012-01-15 14:24:10 +0000130class IntPointer(Type):
131 '''Integer encoded as a pointer.'''
132
133 def visit(self, visitor, *args, **kwargs):
134 return visitor.visitIntPointer(self, *args, **kwargs)
135
136
José Fonsecafbcf6832012-04-05 07:10:30 +0100137class ObjPointer(Type):
138 '''Pointer to an object.'''
139
140 def __init__(self, type):
141 Type.__init__(self, type.expr + " *", 'P' + type.tag)
142 self.type = type
143
144 def visit(self, visitor, *args, **kwargs):
145 return visitor.visitObjPointer(self, *args, **kwargs)
146
147
José Fonseca59ee88e2012-01-15 14:24:10 +0000148class LinearPointer(Type):
José Fonsecafbcf6832012-04-05 07:10:30 +0100149 '''Pointer to a linear range of memory.'''
José Fonseca59ee88e2012-01-15 14:24:10 +0000150
151 def __init__(self, type, size = None):
152 Type.__init__(self, type.expr + " *", 'P' + type.tag)
153 self.type = type
154 self.size = size
155
156 def visit(self, visitor, *args, **kwargs):
157 return visitor.visitLinearPointer(self, *args, **kwargs)
158
159
José Fonsecab89c5932012-04-01 22:47:11 +0200160class Reference(Type):
161 '''C++ references.'''
162
163 def __init__(self, type):
164 Type.__init__(self, type.expr + " &", 'R' + type.tag)
165 self.type = type
166
167 def visit(self, visitor, *args, **kwargs):
168 return visitor.visitReference(self, *args, **kwargs)
169
170
José Fonseca6fac5ae2010-11-29 16:09:13 +0000171class Handle(Type):
172
José Fonseca8a844ae2010-12-06 18:50:52 +0000173 def __init__(self, name, type, range=None, key=None):
José Fonseca02c25002011-10-15 13:17:26 +0100174 Type.__init__(self, type.expr, 'P' + type.tag)
José Fonseca6fac5ae2010-11-29 16:09:13 +0000175 self.name = name
176 self.type = type
177 self.range = range
José Fonseca8a844ae2010-12-06 18:50:52 +0000178 self.key = key
José Fonseca6fac5ae2010-11-29 16:09:13 +0000179
180 def visit(self, visitor, *args, **kwargs):
José Fonseca54f304a2012-01-14 19:33:08 +0000181 return visitor.visitHandle(self, *args, **kwargs)
José Fonseca6fac5ae2010-11-29 16:09:13 +0000182
183
184def ConstPointer(type):
185 return Pointer(Const(type))
186
187
188class Enum(Type):
189
José Fonseca02c25002011-10-15 13:17:26 +0100190 __id = 0
191
José Fonseca6fac5ae2010-11-29 16:09:13 +0000192 def __init__(self, name, values):
193 Type.__init__(self, name)
José Fonseca02c25002011-10-15 13:17:26 +0100194
195 self.id = Enum.__id
196 Enum.__id += 1
197
José Fonseca6fac5ae2010-11-29 16:09:13 +0000198 self.values = list(values)
José Fonseca02c25002011-10-15 13:17:26 +0100199
José Fonseca6fac5ae2010-11-29 16:09:13 +0000200 def visit(self, visitor, *args, **kwargs):
José Fonseca54f304a2012-01-14 19:33:08 +0000201 return visitor.visitEnum(self, *args, **kwargs)
José Fonseca6fac5ae2010-11-29 16:09:13 +0000202
203
204def FakeEnum(type, values):
205 return Enum(type.expr, values)
206
207
208class Bitmask(Type):
209
José Fonseca02c25002011-10-15 13:17:26 +0100210 __id = 0
211
José Fonseca6fac5ae2010-11-29 16:09:13 +0000212 def __init__(self, type, values):
213 Type.__init__(self, type.expr)
José Fonseca02c25002011-10-15 13:17:26 +0100214
215 self.id = Bitmask.__id
216 Bitmask.__id += 1
217
José Fonseca6fac5ae2010-11-29 16:09:13 +0000218 self.type = type
219 self.values = values
220
221 def visit(self, visitor, *args, **kwargs):
José Fonseca54f304a2012-01-14 19:33:08 +0000222 return visitor.visitBitmask(self, *args, **kwargs)
José Fonseca6fac5ae2010-11-29 16:09:13 +0000223
224Flags = Bitmask
225
226
227class Array(Type):
228
229 def __init__(self, type, length):
230 Type.__init__(self, type.expr + " *")
231 self.type = type
232 self.length = length
233
234 def visit(self, visitor, *args, **kwargs):
José Fonseca54f304a2012-01-14 19:33:08 +0000235 return visitor.visitArray(self, *args, **kwargs)
José Fonseca6fac5ae2010-11-29 16:09:13 +0000236
237
238class Blob(Type):
239
240 def __init__(self, type, size):
241 Type.__init__(self, type.expr + ' *')
242 self.type = type
243 self.size = size
244
245 def visit(self, visitor, *args, **kwargs):
José Fonseca54f304a2012-01-14 19:33:08 +0000246 return visitor.visitBlob(self, *args, **kwargs)
José Fonseca6fac5ae2010-11-29 16:09:13 +0000247
248
249class Struct(Type):
250
José Fonseca02c25002011-10-15 13:17:26 +0100251 __id = 0
252
José Fonseca6fac5ae2010-11-29 16:09:13 +0000253 def __init__(self, name, members):
254 Type.__init__(self, name)
José Fonseca02c25002011-10-15 13:17:26 +0100255
256 self.id = Struct.__id
257 Struct.__id += 1
258
José Fonseca6fac5ae2010-11-29 16:09:13 +0000259 self.name = name
260 self.members = members
261
262 def visit(self, visitor, *args, **kwargs):
José Fonseca54f304a2012-01-14 19:33:08 +0000263 return visitor.visitStruct(self, *args, **kwargs)
José Fonseca6fac5ae2010-11-29 16:09:13 +0000264
265
266class Alias(Type):
267
268 def __init__(self, expr, type):
269 Type.__init__(self, expr)
270 self.type = type
271
272 def visit(self, visitor, *args, **kwargs):
José Fonseca54f304a2012-01-14 19:33:08 +0000273 return visitor.visitAlias(self, *args, **kwargs)
José Fonseca6fac5ae2010-11-29 16:09:13 +0000274
José Fonseca6fac5ae2010-11-29 16:09:13 +0000275class Arg:
276
José Fonseca9dd8f702012-04-07 10:42:50 +0100277 def __init__(self, type, name, input=True, output=False):
José Fonseca6fac5ae2010-11-29 16:09:13 +0000278 self.type = type
279 self.name = name
José Fonseca9dd8f702012-04-07 10:42:50 +0100280 self.input = input
José Fonseca6fac5ae2010-11-29 16:09:13 +0000281 self.output = output
282 self.index = None
283
284 def __str__(self):
285 return '%s %s' % (self.type, self.name)
286
287
José Fonseca9dd8f702012-04-07 10:42:50 +0100288def In(type, name):
289 return Arg(type, name, input=True, output=False)
290
291def Out(type, name):
292 return Arg(type, name, input=False, output=True)
293
294def InOut(type, name):
295 return Arg(type, name, input=True, output=True)
296
297
José Fonseca6fac5ae2010-11-29 16:09:13 +0000298class Function:
299
José Fonseca46a48392011-10-14 11:34:27 +0100300 # 0-3 are reserved to memcpy, malloc, free, and realloc
301 __id = 4
José Fonseca6fac5ae2010-11-29 16:09:13 +0000302
José Fonsecabca0f412011-04-24 20:53:38 +0100303 def __init__(self, type, name, args, call = '', fail = None, sideeffects=True):
José Fonseca6fac5ae2010-11-29 16:09:13 +0000304 self.id = Function.__id
305 Function.__id += 1
306
307 self.type = type
308 self.name = name
309
310 self.args = []
311 index = 0
312 for arg in args:
José Fonseca8384ccb2011-05-25 10:12:02 +0100313 if not isinstance(arg, Arg):
314 if isinstance(arg, tuple):
315 arg_type, arg_name = arg
316 else:
317 arg_type = arg
318 arg_name = "arg%u" % index
José Fonseca6fac5ae2010-11-29 16:09:13 +0000319 arg = Arg(arg_type, arg_name)
320 arg.index = index
321 index += 1
322 self.args.append(arg)
323
324 self.call = call
325 self.fail = fail
326 self.sideeffects = sideeffects
José Fonseca6fac5ae2010-11-29 16:09:13 +0000327
328 def prototype(self, name=None):
329 if name is not None:
330 name = name.strip()
331 else:
332 name = self.name
333 s = name
334 if self.call:
335 s = self.call + ' ' + s
336 if name.startswith('*'):
337 s = '(' + s + ')'
338 s = self.type.expr + ' ' + s
339 s += "("
340 if self.args:
341 s += ", ".join(["%s %s" % (arg.type, arg.name) for arg in self.args])
342 else:
343 s += "void"
344 s += ")"
345 return s
346
José Fonseca568ecc22012-01-15 13:57:03 +0000347 def argNames(self):
348 return [arg.name for arg in self.args]
349
José Fonseca6fac5ae2010-11-29 16:09:13 +0000350
351def StdFunction(*args, **kwargs):
352 kwargs.setdefault('call', '__stdcall')
353 return Function(*args, **kwargs)
354
355
356def FunctionPointer(type, name, args, **kwargs):
357 # XXX: We should probably treat function pointers (callbacks or not) in a generic fashion
358 return Opaque(name)
359
360
361class Interface(Type):
362
363 def __init__(self, name, base=None):
364 Type.__init__(self, name)
365 self.name = name
366 self.base = base
367 self.methods = []
368
369 def visit(self, visitor, *args, **kwargs):
José Fonseca54f304a2012-01-14 19:33:08 +0000370 return visitor.visitInterface(self, *args, **kwargs)
José Fonseca6fac5ae2010-11-29 16:09:13 +0000371
José Fonseca54f304a2012-01-14 19:33:08 +0000372 def iterMethods(self):
José Fonseca6fac5ae2010-11-29 16:09:13 +0000373 if self.base is not None:
José Fonseca54f304a2012-01-14 19:33:08 +0000374 for method in self.base.iterMethods():
José Fonseca6fac5ae2010-11-29 16:09:13 +0000375 yield method
376 for method in self.methods:
377 yield method
378 raise StopIteration
379
José Fonseca4220b1b2012-02-03 19:05:29 +0000380 def iterBaseMethods(self):
381 if self.base is not None:
382 for iface, method in self.base.iterBaseMethods():
383 yield iface, method
384 for method in self.methods:
385 yield self, method
386 raise StopIteration
387
José Fonseca6fac5ae2010-11-29 16:09:13 +0000388
389class Method(Function):
390
José Fonseca16037322012-04-01 22:45:09 +0200391 def __init__(self, type, name, args, const=False, sideeffects=True):
392 Function.__init__(self, type, name, args, call = '__stdcall', sideeffects=sideeffects)
José Fonseca6fac5ae2010-11-29 16:09:13 +0000393 for index in range(len(self.args)):
394 self.args[index].index = index + 1
José Fonseca9dbeda62012-02-03 19:05:54 +0000395 self.const = const
396
397 def prototype(self, name=None):
398 s = Function.prototype(self, name)
399 if self.const:
400 s += ' const'
401 return s
José Fonseca6fac5ae2010-11-29 16:09:13 +0000402
403
José Fonseca6fac5ae2010-11-29 16:09:13 +0000404class String(Type):
405
José Fonseca280a1762012-01-31 15:10:13 +0000406 def __init__(self, expr = "char *", length = None, kind = 'String'):
José Fonseca6fac5ae2010-11-29 16:09:13 +0000407 Type.__init__(self, expr)
408 self.length = length
José Fonseca280a1762012-01-31 15:10:13 +0000409 self.kind = kind
José Fonseca6fac5ae2010-11-29 16:09:13 +0000410
411 def visit(self, visitor, *args, **kwargs):
José Fonseca54f304a2012-01-14 19:33:08 +0000412 return visitor.visitString(self, *args, **kwargs)
José Fonseca6fac5ae2010-11-29 16:09:13 +0000413
José Fonseca6fac5ae2010-11-29 16:09:13 +0000414
415class Opaque(Type):
416 '''Opaque pointer.'''
417
418 def __init__(self, expr):
419 Type.__init__(self, expr)
420
421 def visit(self, visitor, *args, **kwargs):
José Fonseca54f304a2012-01-14 19:33:08 +0000422 return visitor.visitOpaque(self, *args, **kwargs)
José Fonseca6fac5ae2010-11-29 16:09:13 +0000423
424
425def OpaquePointer(type, *args):
426 return Opaque(type.expr + ' *')
427
428def OpaqueArray(type, size):
429 return Opaque(type.expr + ' *')
430
431def OpaqueBlob(type, size):
432 return Opaque(type.expr + ' *')
José Fonseca8a56d142008-07-09 12:18:08 +0900433
José Fonseca501f2862010-11-19 20:41:18 +0000434
José Fonseca16d46dd2011-10-13 09:52:52 +0100435class Polymorphic(Type):
436
José Fonseca54f304a2012-01-14 19:33:08 +0000437 def __init__(self, defaultType, switchExpr, switchTypes):
438 Type.__init__(self, defaultType.expr)
439 self.defaultType = defaultType
440 self.switchExpr = switchExpr
441 self.switchTypes = switchTypes
José Fonseca16d46dd2011-10-13 09:52:52 +0100442
443 def visit(self, visitor, *args, **kwargs):
José Fonseca54f304a2012-01-14 19:33:08 +0000444 return visitor.visitPolymorphic(self, *args, **kwargs)
José Fonseca16d46dd2011-10-13 09:52:52 +0100445
José Fonseca54f304a2012-01-14 19:33:08 +0000446 def iterSwitch(self):
José Fonseca46161112011-10-14 10:04:55 +0100447 cases = [['default']]
José Fonseca54f304a2012-01-14 19:33:08 +0000448 types = [self.defaultType]
José Fonseca46161112011-10-14 10:04:55 +0100449
José Fonseca54f304a2012-01-14 19:33:08 +0000450 for expr, type in self.switchTypes:
José Fonseca46161112011-10-14 10:04:55 +0100451 case = 'case %s' % expr
452 try:
453 i = types.index(type)
454 except ValueError:
455 cases.append([case])
456 types.append(type)
457 else:
458 cases[i].append(case)
459
460 return zip(cases, types)
461
José Fonseca16d46dd2011-10-13 09:52:52 +0100462
José Fonseca501f2862010-11-19 20:41:18 +0000463class Visitor:
José Fonseca9c4a2572012-01-13 23:21:10 +0000464 '''Abstract visitor for the type hierarchy.'''
José Fonseca501f2862010-11-19 20:41:18 +0000465
466 def visit(self, type, *args, **kwargs):
467 return type.visit(self, *args, **kwargs)
468
José Fonseca54f304a2012-01-14 19:33:08 +0000469 def visitVoid(self, void, *args, **kwargs):
José Fonseca501f2862010-11-19 20:41:18 +0000470 raise NotImplementedError
471
José Fonseca54f304a2012-01-14 19:33:08 +0000472 def visitLiteral(self, literal, *args, **kwargs):
José Fonseca501f2862010-11-19 20:41:18 +0000473 raise NotImplementedError
474
José Fonseca54f304a2012-01-14 19:33:08 +0000475 def visitString(self, string, *args, **kwargs):
José Fonseca2defc982010-11-22 16:59:10 +0000476 raise NotImplementedError
477
José Fonseca54f304a2012-01-14 19:33:08 +0000478 def visitConst(self, const, *args, **kwargs):
José Fonseca501f2862010-11-19 20:41:18 +0000479 raise NotImplementedError
480
José Fonseca54f304a2012-01-14 19:33:08 +0000481 def visitStruct(self, struct, *args, **kwargs):
José Fonseca501f2862010-11-19 20:41:18 +0000482 raise NotImplementedError
483
José Fonseca54f304a2012-01-14 19:33:08 +0000484 def visitArray(self, array, *args, **kwargs):
José Fonseca501f2862010-11-19 20:41:18 +0000485 raise NotImplementedError
486
José Fonseca54f304a2012-01-14 19:33:08 +0000487 def visitBlob(self, blob, *args, **kwargs):
José Fonseca885f2652010-11-20 11:22:25 +0000488 raise NotImplementedError
489
José Fonseca54f304a2012-01-14 19:33:08 +0000490 def visitEnum(self, enum, *args, **kwargs):
José Fonseca501f2862010-11-19 20:41:18 +0000491 raise NotImplementedError
492
José Fonseca54f304a2012-01-14 19:33:08 +0000493 def visitBitmask(self, bitmask, *args, **kwargs):
José Fonseca501f2862010-11-19 20:41:18 +0000494 raise NotImplementedError
495
José Fonseca54f304a2012-01-14 19:33:08 +0000496 def visitPointer(self, pointer, *args, **kwargs):
José Fonseca501f2862010-11-19 20:41:18 +0000497 raise NotImplementedError
498
José Fonseca59ee88e2012-01-15 14:24:10 +0000499 def visitIntPointer(self, pointer, *args, **kwargs):
500 raise NotImplementedError
501
José Fonsecafbcf6832012-04-05 07:10:30 +0100502 def visitObjPointer(self, pointer, *args, **kwargs):
503 raise NotImplementedError
504
José Fonseca59ee88e2012-01-15 14:24:10 +0000505 def visitLinearPointer(self, pointer, *args, **kwargs):
506 raise NotImplementedError
507
José Fonsecab89c5932012-04-01 22:47:11 +0200508 def visitReference(self, reference, *args, **kwargs):
509 raise NotImplementedError
510
José Fonseca54f304a2012-01-14 19:33:08 +0000511 def visitHandle(self, handle, *args, **kwargs):
José Fonseca50d78d82010-11-23 22:13:14 +0000512 raise NotImplementedError
513
José Fonseca54f304a2012-01-14 19:33:08 +0000514 def visitAlias(self, alias, *args, **kwargs):
José Fonseca501f2862010-11-19 20:41:18 +0000515 raise NotImplementedError
516
José Fonseca54f304a2012-01-14 19:33:08 +0000517 def visitOpaque(self, opaque, *args, **kwargs):
José Fonseca501f2862010-11-19 20:41:18 +0000518 raise NotImplementedError
519
José Fonseca54f304a2012-01-14 19:33:08 +0000520 def visitInterface(self, interface, *args, **kwargs):
José Fonsecac356d6a2010-11-23 14:27:25 +0000521 raise NotImplementedError
522
José Fonseca54f304a2012-01-14 19:33:08 +0000523 def visitPolymorphic(self, polymorphic, *args, **kwargs):
José Fonseca16d46dd2011-10-13 09:52:52 +0100524 raise NotImplementedError
José Fonseca54f304a2012-01-14 19:33:08 +0000525 #return self.visit(polymorphic.defaultType, *args, **kwargs)
José Fonseca16d46dd2011-10-13 09:52:52 +0100526
José Fonsecac356d6a2010-11-23 14:27:25 +0000527
528class OnceVisitor(Visitor):
José Fonseca9c4a2572012-01-13 23:21:10 +0000529 '''Visitor that guarantees that each type is visited only once.'''
José Fonsecac356d6a2010-11-23 14:27:25 +0000530
531 def __init__(self):
532 self.__visited = set()
533
534 def visit(self, type, *args, **kwargs):
535 if type not in self.__visited:
536 self.__visited.add(type)
537 return type.visit(self, *args, **kwargs)
538 return None
539
José Fonseca501f2862010-11-19 20:41:18 +0000540
José Fonsecac9edb832010-11-20 09:03:10 +0000541class Rebuilder(Visitor):
José Fonseca9c4a2572012-01-13 23:21:10 +0000542 '''Visitor which rebuild types as it visits them.
543
544 By itself it is a no-op -- it is intended to be overwritten.
545 '''
José Fonsecac9edb832010-11-20 09:03:10 +0000546
José Fonseca54f304a2012-01-14 19:33:08 +0000547 def visitVoid(self, void):
José Fonsecac9edb832010-11-20 09:03:10 +0000548 return void
549
José Fonseca54f304a2012-01-14 19:33:08 +0000550 def visitLiteral(self, literal):
José Fonsecac9edb832010-11-20 09:03:10 +0000551 return literal
552
José Fonseca54f304a2012-01-14 19:33:08 +0000553 def visitString(self, string):
José Fonseca2defc982010-11-22 16:59:10 +0000554 return string
555
José Fonseca54f304a2012-01-14 19:33:08 +0000556 def visitConst(self, const):
José Fonsecaf182eda2012-04-05 19:59:56 +0100557 const_type = self.visit(const.type)
558 if const_type is const.type:
559 return const
560 else:
561 return Const(const_type)
José Fonsecac9edb832010-11-20 09:03:10 +0000562
José Fonseca54f304a2012-01-14 19:33:08 +0000563 def visitStruct(self, struct):
José Fonseca06aa2842011-05-05 07:55:54 +0100564 members = [(self.visit(type), name) for type, name in struct.members]
José Fonsecac9edb832010-11-20 09:03:10 +0000565 return Struct(struct.name, members)
566
José Fonseca54f304a2012-01-14 19:33:08 +0000567 def visitArray(self, array):
José Fonsecac9edb832010-11-20 09:03:10 +0000568 type = self.visit(array.type)
569 return Array(type, array.length)
570
José Fonseca54f304a2012-01-14 19:33:08 +0000571 def visitBlob(self, blob):
José Fonseca885f2652010-11-20 11:22:25 +0000572 type = self.visit(blob.type)
573 return Blob(type, blob.size)
574
José Fonseca54f304a2012-01-14 19:33:08 +0000575 def visitEnum(self, enum):
José Fonsecac9edb832010-11-20 09:03:10 +0000576 return enum
577
José Fonseca54f304a2012-01-14 19:33:08 +0000578 def visitBitmask(self, bitmask):
José Fonsecac9edb832010-11-20 09:03:10 +0000579 type = self.visit(bitmask.type)
580 return Bitmask(type, bitmask.values)
581
José Fonseca54f304a2012-01-14 19:33:08 +0000582 def visitPointer(self, pointer):
José Fonsecaf182eda2012-04-05 19:59:56 +0100583 pointer_type = self.visit(pointer.type)
584 if pointer_type is pointer.type:
585 return pointer
586 else:
587 return Pointer(pointer_type)
José Fonsecac9edb832010-11-20 09:03:10 +0000588
José Fonseca59ee88e2012-01-15 14:24:10 +0000589 def visitIntPointer(self, pointer):
590 return pointer
591
José Fonsecafbcf6832012-04-05 07:10:30 +0100592 def visitObjPointer(self, pointer):
José Fonsecaf182eda2012-04-05 19:59:56 +0100593 pointer_type = self.visit(pointer.type)
594 if pointer_type is pointer.type:
595 return pointer
596 else:
597 return ObjPointer(pointer_type)
José Fonsecafbcf6832012-04-05 07:10:30 +0100598
José Fonseca59ee88e2012-01-15 14:24:10 +0000599 def visitLinearPointer(self, pointer):
José Fonsecaf182eda2012-04-05 19:59:56 +0100600 pointer_type = self.visit(pointer.type)
601 if pointer_type is pointer.type:
602 return pointer
603 else:
604 return LinearPointer(pointer_type)
José Fonseca59ee88e2012-01-15 14:24:10 +0000605
José Fonsecab89c5932012-04-01 22:47:11 +0200606 def visitReference(self, reference):
José Fonsecaf182eda2012-04-05 19:59:56 +0100607 reference_type = self.visit(reference.type)
608 if reference_type is reference.type:
609 return reference
610 else:
611 return Reference(reference_type)
José Fonsecab89c5932012-04-01 22:47:11 +0200612
José Fonseca54f304a2012-01-14 19:33:08 +0000613 def visitHandle(self, handle):
José Fonsecaf182eda2012-04-05 19:59:56 +0100614 handle_type = self.visit(handle.type)
615 if handle_type is handle.type:
616 return handle
617 else:
618 return Handle(handle.name, handle_type, range=handle.range, key=handle.key)
José Fonseca50d78d82010-11-23 22:13:14 +0000619
José Fonseca54f304a2012-01-14 19:33:08 +0000620 def visitAlias(self, alias):
José Fonsecaf182eda2012-04-05 19:59:56 +0100621 alias_type = self.visit(alias.type)
622 if alias_type is alias.type:
623 return alias
624 else:
625 return Alias(alias.expr, alias_type)
José Fonsecac9edb832010-11-20 09:03:10 +0000626
José Fonseca54f304a2012-01-14 19:33:08 +0000627 def visitOpaque(self, opaque):
José Fonsecac9edb832010-11-20 09:03:10 +0000628 return opaque
629
José Fonseca7814edf2012-01-31 10:55:49 +0000630 def visitInterface(self, interface, *args, **kwargs):
631 return interface
632
José Fonseca54f304a2012-01-14 19:33:08 +0000633 def visitPolymorphic(self, polymorphic):
634 defaultType = self.visit(polymorphic.defaultType)
635 switchExpr = polymorphic.switchExpr
636 switchTypes = [(expr, self.visit(type)) for expr, type in polymorphic.switchTypes]
637 return Polymorphic(defaultType, switchExpr, switchTypes)
José Fonseca16d46dd2011-10-13 09:52:52 +0100638
José Fonsecac9edb832010-11-20 09:03:10 +0000639
José Fonsecae6a50bd2010-11-24 10:12:22 +0000640class Collector(Visitor):
José Fonseca9c4a2572012-01-13 23:21:10 +0000641 '''Visitor which collects all unique types as it traverses them.'''
José Fonsecae6a50bd2010-11-24 10:12:22 +0000642
643 def __init__(self):
644 self.__visited = set()
645 self.types = []
646
647 def visit(self, type):
648 if type in self.__visited:
649 return
650 self.__visited.add(type)
651 Visitor.visit(self, type)
652 self.types.append(type)
653
José Fonseca54f304a2012-01-14 19:33:08 +0000654 def visitVoid(self, literal):
José Fonsecae6a50bd2010-11-24 10:12:22 +0000655 pass
656
José Fonseca54f304a2012-01-14 19:33:08 +0000657 def visitLiteral(self, literal):
José Fonsecae6a50bd2010-11-24 10:12:22 +0000658 pass
659
José Fonseca54f304a2012-01-14 19:33:08 +0000660 def visitString(self, string):
José Fonsecae6a50bd2010-11-24 10:12:22 +0000661 pass
662
José Fonseca54f304a2012-01-14 19:33:08 +0000663 def visitConst(self, const):
José Fonsecae6a50bd2010-11-24 10:12:22 +0000664 self.visit(const.type)
665
José Fonseca54f304a2012-01-14 19:33:08 +0000666 def visitStruct(self, struct):
José Fonsecae6a50bd2010-11-24 10:12:22 +0000667 for type, name in struct.members:
668 self.visit(type)
669
José Fonseca54f304a2012-01-14 19:33:08 +0000670 def visitArray(self, array):
José Fonsecae6a50bd2010-11-24 10:12:22 +0000671 self.visit(array.type)
672
José Fonseca54f304a2012-01-14 19:33:08 +0000673 def visitBlob(self, array):
José Fonsecae6a50bd2010-11-24 10:12:22 +0000674 pass
675
José Fonseca54f304a2012-01-14 19:33:08 +0000676 def visitEnum(self, enum):
José Fonsecae6a50bd2010-11-24 10:12:22 +0000677 pass
678
José Fonseca54f304a2012-01-14 19:33:08 +0000679 def visitBitmask(self, bitmask):
José Fonsecae6a50bd2010-11-24 10:12:22 +0000680 self.visit(bitmask.type)
681
José Fonseca54f304a2012-01-14 19:33:08 +0000682 def visitPointer(self, pointer):
José Fonsecae6a50bd2010-11-24 10:12:22 +0000683 self.visit(pointer.type)
684
José Fonseca59ee88e2012-01-15 14:24:10 +0000685 def visitIntPointer(self, pointer):
686 pass
687
José Fonsecafbcf6832012-04-05 07:10:30 +0100688 def visitObjPointer(self, pointer):
689 self.visit(pointer.type)
690
José Fonseca59ee88e2012-01-15 14:24:10 +0000691 def visitLinearPointer(self, pointer):
692 self.visit(pointer.type)
693
José Fonsecab89c5932012-04-01 22:47:11 +0200694 def visitReference(self, reference):
695 self.visit(reference.type)
696
José Fonseca54f304a2012-01-14 19:33:08 +0000697 def visitHandle(self, handle):
José Fonsecae6a50bd2010-11-24 10:12:22 +0000698 self.visit(handle.type)
699
José Fonseca54f304a2012-01-14 19:33:08 +0000700 def visitAlias(self, alias):
José Fonsecae6a50bd2010-11-24 10:12:22 +0000701 self.visit(alias.type)
702
José Fonseca54f304a2012-01-14 19:33:08 +0000703 def visitOpaque(self, opaque):
José Fonsecae6a50bd2010-11-24 10:12:22 +0000704 pass
705
José Fonseca54f304a2012-01-14 19:33:08 +0000706 def visitInterface(self, interface):
José Fonseca87d1cc62010-11-29 15:57:25 +0000707 if interface.base is not None:
708 self.visit(interface.base)
José Fonseca54f304a2012-01-14 19:33:08 +0000709 for method in interface.iterMethods():
José Fonseca87d1cc62010-11-29 15:57:25 +0000710 for arg in method.args:
711 self.visit(arg.type)
712 self.visit(method.type)
José Fonsecae6a50bd2010-11-24 10:12:22 +0000713
José Fonseca54f304a2012-01-14 19:33:08 +0000714 def visitPolymorphic(self, polymorphic):
715 self.visit(polymorphic.defaultType)
716 for expr, type in polymorphic.switchTypes:
José Fonseca16d46dd2011-10-13 09:52:52 +0100717 self.visit(type)
718
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000719
720class API:
José Fonseca9c4a2572012-01-13 23:21:10 +0000721 '''API abstraction.
722
723 Essentially, a collection of types, functions, and interfaces.
724 '''
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000725
José Fonseca68ec4122011-02-20 11:25:25 +0000726 def __init__(self, name = None):
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000727 self.name = name
728 self.headers = []
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000729 self.functions = []
730 self.interfaces = []
731
José Fonseca44703822012-01-31 10:48:58 +0000732 def getAllTypes(self):
José Fonsecae6a50bd2010-11-24 10:12:22 +0000733 collector = Collector()
734 for function in self.functions:
735 for arg in function.args:
736 collector.visit(arg.type)
737 collector.visit(function.type)
738 for interface in self.interfaces:
739 collector.visit(interface)
José Fonseca54f304a2012-01-14 19:33:08 +0000740 for method in interface.iterMethods():
José Fonsecae6a50bd2010-11-24 10:12:22 +0000741 for arg in method.args:
742 collector.visit(arg.type)
743 collector.visit(method.type)
744 return collector.types
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000745
José Fonseca2ef6d5b2012-01-31 10:56:38 +0000746 def getAllInterfaces(self):
747 types = self.getAllTypes()
748 interfaces = [type for type in types if isinstance(type, Interface)]
749 for interface in self.interfaces:
750 if interface not in interfaces:
751 interfaces.append(interface)
752 return interfaces
753
José Fonseca54f304a2012-01-14 19:33:08 +0000754 def addFunction(self, function):
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000755 self.functions.append(function)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000756
José Fonseca54f304a2012-01-14 19:33:08 +0000757 def addFunctions(self, functions):
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000758 for function in functions:
José Fonseca54f304a2012-01-14 19:33:08 +0000759 self.addFunction(function)
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000760
José Fonseca54f304a2012-01-14 19:33:08 +0000761 def addInterface(self, interface):
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000762 self.interfaces.append(interface)
763
José Fonseca54f304a2012-01-14 19:33:08 +0000764 def addInterfaces(self, interfaces):
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000765 self.interfaces.extend(interfaces)
766
José Fonseca54f304a2012-01-14 19:33:08 +0000767 def addApi(self, api):
José Fonseca68ec4122011-02-20 11:25:25 +0000768 self.headers.extend(api.headers)
José Fonseca54f304a2012-01-14 19:33:08 +0000769 self.addFunctions(api.functions)
770 self.addInterfaces(api.interfaces)
José Fonseca68ec4122011-02-20 11:25:25 +0000771
José Fonsecaeccec3e2011-02-20 09:01:25 +0000772 def get_function_by_name(self, name):
773 for function in self.functions:
774 if function.name == name:
775 return function
776 return None
777
José Fonseca8fbdd3a2010-11-23 20:55:07 +0000778
José Fonseca51c1ef82010-11-15 16:09:14 +0000779Bool = Literal("bool", "Bool")
780SChar = Literal("signed char", "SInt")
781UChar = Literal("unsigned char", "UInt")
782Short = Literal("short", "SInt")
783Int = Literal("int", "SInt")
784Long = Literal("long", "SInt")
785LongLong = Literal("long long", "SInt")
786UShort = Literal("unsigned short", "UInt")
787UInt = Literal("unsigned int", "UInt")
788ULong = Literal("unsigned long", "UInt")
José Fonseca28f034f2010-11-22 20:31:25 +0000789ULongLong = Literal("unsigned long long", "UInt")
José Fonseca51c1ef82010-11-15 16:09:14 +0000790Float = Literal("float", "Float")
José Fonseca9ff74442011-05-07 01:17:49 +0100791Double = Literal("double", "Double")
José Fonseca51c1ef82010-11-15 16:09:14 +0000792SizeT = Literal("size_t", "UInt")
José Fonseca280a1762012-01-31 15:10:13 +0000793
794# C string (i.e., zero terminated)
795CString = String()
796WString = String("wchar_t *", kind="WString")
José Fonsecad626cf42008-07-07 07:43:16 +0900797
José Fonseca2250a0e2010-11-26 15:01:29 +0000798Int8 = Literal("int8_t", "SInt")
799UInt8 = Literal("uint8_t", "UInt")
800Int16 = Literal("int16_t", "SInt")
801UInt16 = Literal("uint16_t", "UInt")
802Int32 = Literal("int32_t", "SInt")
803UInt32 = Literal("uint32_t", "UInt")
804Int64 = Literal("int64_t", "SInt")
805UInt64 = Literal("uint64_t", "UInt")