1#
2#   Cython/Python language types
3#
4
5from Code import UtilityCode, LazyUtilityCode, TempitaUtilityCode
6import StringEncoding
7import Naming
8import copy
9from Errors import error
10
11class BaseType(object):
12    #
13    #  Base class for all Cython types including pseudo-types.
14
15    # List of attribute names of any subtypes
16    subtypes = []
17
18    def can_coerce_to_pyobject(self, env):
19        return False
20
21    def cast_code(self, expr_code):
22        return "((%s)%s)" % (self.declaration_code(""), expr_code)
23
24    def specialization_name(self):
25        # This is not entirely robust.
26        safe = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_0123456789'
27        all = []
28        for c in self.declaration_code("").replace("unsigned ", "unsigned_").replace("long long", "long_long").replace(" ", "__"):
29            if c in safe:
30                all.append(c)
31            else:
32                all.append('_%x_' % ord(c))
33        return ''.join(all)
34
35    def base_declaration_code(self, base_code, entity_code):
36        if entity_code:
37            return "%s %s" % (base_code, entity_code)
38        else:
39            return base_code
40
41    def __deepcopy__(self, memo):
42        """
43        Types never need to be copied, if we do copy, Unfortunate Things
44        Will Happen!
45        """
46        return self
47
48    def get_fused_types(self, result=None, seen=None, subtypes=None):
49        subtypes = subtypes or self.subtypes
50        if subtypes:
51            if result is None:
52                result = []
53                seen = set()
54
55            for attr in subtypes:
56                list_or_subtype = getattr(self, attr)
57                if list_or_subtype:
58                    if isinstance(list_or_subtype, BaseType):
59                        list_or_subtype.get_fused_types(result, seen)
60                    else:
61                        for subtype in list_or_subtype:
62                            subtype.get_fused_types(result, seen)
63
64            return result
65
66        return None
67
68    def specialize_fused(self, env):
69        if env.fused_to_specific:
70            return self.specialize(env.fused_to_specific)
71
72        return self
73
74    def _get_fused_types(self):
75        """
76        Add this indirection for the is_fused property to allow overriding
77        get_fused_types in subclasses.
78        """
79        return self.get_fused_types()
80
81    is_fused = property(_get_fused_types, doc="Whether this type or any of its "
82                                             "subtypes is a fused type")
83
84    def deduce_template_params(self, actual):
85        """
86        Deduce any template params in this (argument) type given the actual
87        argument type.
88
89        http://en.cppreference.com/w/cpp/language/function_template#Template_argument_deduction
90        """
91        if self == actual:
92            return {}
93        else:
94            return None
95
96    def __lt__(self, other):
97        """
98        For sorting. The sorting order should correspond to the preference of
99        conversion from Python types.
100
101        Override to provide something sensible. This is only implemented so that
102        python 3 doesn't trip
103        """
104        return id(type(self)) < id(type(other))
105
106    def py_type_name(self):
107        """
108        Return the name of the Python type that can coerce to this type.
109        """
110
111    def typeof_name(self):
112        """
113        Return the string with which fused python functions can be indexed.
114        """
115        if self.is_builtin_type or self.py_type_name() == 'object':
116            index_name = self.py_type_name()
117        else:
118            index_name = str(self)
119
120        return index_name
121
122    def check_for_null_code(self, cname):
123        """
124        Return the code for a NULL-check in case an UnboundLocalError should
125        be raised if an entry of this type is referenced before assignment.
126        Returns None if no check should be performed.
127        """
128        return None
129
130    def invalid_value(self):
131        """
132        Returns the most invalid value an object of this type can assume as a
133        C expression string. Returns None if no such value exists.
134        """
135
136
137class PyrexType(BaseType):
138    #
139    #  Base class for all Cython types
140    #
141    #  is_pyobject           boolean     Is a Python object type
142    #  is_extension_type     boolean     Is a Python extension type
143    #  is_final_type         boolean     Is a final extension type
144    #  is_numeric            boolean     Is a C numeric type
145    #  is_int                boolean     Is a C integer type
146    #  is_float              boolean     Is a C floating point type
147    #  is_complex            boolean     Is a C complex type
148    #  is_void               boolean     Is the C void type
149    #  is_array              boolean     Is a C array type
150    #  is_ptr                boolean     Is a C pointer type
151    #  is_null_ptr           boolean     Is the type of NULL
152    #  is_reference          boolean     Is a C reference type
153    #  is_const              boolean     Is a C const type.
154    #  is_cfunction          boolean     Is a C function type
155    #  is_struct_or_union    boolean     Is a C struct or union type
156    #  is_struct             boolean     Is a C struct type
157    #  is_enum               boolean     Is a C enum type
158    #  is_typedef            boolean     Is a typedef type
159    #  is_string             boolean     Is a C char * type
160    #  is_pyunicode_ptr      boolean     Is a C PyUNICODE * type
161    #  is_cpp_string         boolean     Is a C++ std::string type
162    #  is_unicode_char       boolean     Is either Py_UCS4 or Py_UNICODE
163    #  is_returncode         boolean     Is used only to signal exceptions
164    #  is_error              boolean     Is the dummy error type
165    #  is_buffer             boolean     Is buffer access type
166    #  has_attributes        boolean     Has C dot-selectable attributes
167    #  default_value         string      Initial value
168    #  entry                 Entry       The Entry for this type
169    #
170    #  declaration_code(entity_code,
171    #      for_display = 0, dll_linkage = None, pyrex = 0)
172    #    Returns a code fragment for the declaration of an entity
173    #    of this type, given a code fragment for the entity.
174    #    * If for_display, this is for reading by a human in an error
175    #      message; otherwise it must be valid C code.
176    #    * If dll_linkage is not None, it must be 'DL_EXPORT' or
177    #      'DL_IMPORT', and will be added to the base type part of
178    #      the declaration.
179    #    * If pyrex = 1, this is for use in a 'cdef extern'
180    #      statement of a Cython include file.
181    #
182    #  assignable_from(src_type)
183    #    Tests whether a variable of this type can be
184    #    assigned a value of type src_type.
185    #
186    #  same_as(other_type)
187    #    Tests whether this type represents the same type
188    #    as other_type.
189    #
190    #  as_argument_type():
191    #    Coerces array and C function types into pointer type for use as
192    #    a formal argument type.
193    #
194
195    is_pyobject = 0
196    is_unspecified = 0
197    is_extension_type = 0
198    is_final_type = 0
199    is_builtin_type = 0
200    is_numeric = 0
201    is_int = 0
202    is_float = 0
203    is_complex = 0
204    is_void = 0
205    is_array = 0
206    is_ptr = 0
207    is_null_ptr = 0
208    is_reference = 0
209    is_const = 0
210    is_cfunction = 0
211    is_struct_or_union = 0
212    is_cpp_class = 0
213    is_cpp_string = 0
214    is_struct = 0
215    is_enum = 0
216    is_typedef = 0
217    is_string = 0
218    is_pyunicode_ptr = 0
219    is_unicode_char = 0
220    is_returncode = 0
221    is_error = 0
222    is_buffer = 0
223    is_memoryviewslice = 0
224    has_attributes = 0
225    default_value = ""
226
227    def resolve(self):
228        # If a typedef, returns the base type.
229        return self
230
231    def specialize(self, values):
232        # TODO(danilo): Override wherever it makes sense.
233        return self
234
235    def literal_code(self, value):
236        # Returns a C code fragment representing a literal
237        # value of this type.
238        return str(value)
239
240    def __str__(self):
241        return self.declaration_code("", for_display = 1).strip()
242
243    def same_as(self, other_type, **kwds):
244        return self.same_as_resolved_type(other_type.resolve(), **kwds)
245
246    def same_as_resolved_type(self, other_type):
247        return self == other_type or other_type is error_type
248
249    def subtype_of(self, other_type):
250        return self.subtype_of_resolved_type(other_type.resolve())
251
252    def subtype_of_resolved_type(self, other_type):
253        return self.same_as(other_type)
254
255    def assignable_from(self, src_type):
256        return self.assignable_from_resolved_type(src_type.resolve())
257
258    def assignable_from_resolved_type(self, src_type):
259        return self.same_as(src_type)
260
261    def as_argument_type(self):
262        return self
263
264    def is_complete(self):
265        # A type is incomplete if it is an unsized array,
266        # a struct whose attributes are not defined, etc.
267        return 1
268
269    def is_simple_buffer_dtype(self):
270        return (self.is_int or self.is_float or self.is_complex or self.is_pyobject or
271                self.is_extension_type or self.is_ptr)
272
273    def struct_nesting_depth(self):
274        # Returns the number levels of nested structs. This is
275        # used for constructing a stack for walking the run-time
276        # type information of the struct.
277        return 1
278
279    def global_init_code(self, entry, code):
280        # abstract
281        pass
282
283    def needs_nonecheck(self):
284        return 0
285
286
287def public_decl(base_code, dll_linkage):
288    if dll_linkage:
289        return "%s(%s)" % (dll_linkage, base_code)
290    else:
291        return base_code
292
293def create_typedef_type(name, base_type, cname, is_external=0):
294    is_fused = base_type.is_fused
295    if base_type.is_complex or is_fused:
296        if is_external:
297            if is_fused:
298                msg = "Fused"
299            else:
300                msg = "Complex"
301
302            raise ValueError("%s external typedefs not supported" % msg)
303
304        return base_type
305    else:
306        return CTypedefType(name, base_type, cname, is_external)
307
308
309class CTypedefType(BaseType):
310    #
311    #  Pseudo-type defined with a ctypedef statement in a
312    #  'cdef extern from' block.
313    #  Delegates most attribute lookups to the base type.
314    #  (Anything not defined here or in the BaseType is delegated.)
315    #
316    #  qualified_name      string
317    #  typedef_name        string
318    #  typedef_cname       string
319    #  typedef_base_type   PyrexType
320    #  typedef_is_external bool
321
322    is_typedef = 1
323    typedef_is_external = 0
324
325    to_py_utility_code = None
326    from_py_utility_code = None
327
328    subtypes = ['typedef_base_type']
329
330    def __init__(self, name, base_type, cname, is_external=0):
331        assert not base_type.is_complex
332        self.typedef_name = name
333        self.typedef_cname = cname
334        self.typedef_base_type = base_type
335        self.typedef_is_external = is_external
336
337    def invalid_value(self):
338        return self.typedef_base_type.invalid_value()
339
340    def resolve(self):
341        return self.typedef_base_type.resolve()
342
343    def declaration_code(self, entity_code,
344            for_display = 0, dll_linkage = None, pyrex = 0):
345        if pyrex or for_display:
346            base_code = self.typedef_name
347        else:
348            base_code = public_decl(self.typedef_cname, dll_linkage)
349        return self.base_declaration_code(base_code, entity_code)
350
351    def as_argument_type(self):
352        return self
353
354    def cast_code(self, expr_code):
355        # If self is really an array (rather than pointer), we can't cast.
356        # For example, the gmp mpz_t.
357        if self.typedef_base_type.is_array:
358            base_type = self.typedef_base_type.base_type
359            return CPtrType(base_type).cast_code(expr_code)
360        else:
361            return BaseType.cast_code(self, expr_code)
362
363    def __repr__(self):
364        return "<CTypedefType %s>" % self.typedef_cname
365
366    def __str__(self):
367        return self.typedef_name
368
369    def _create_utility_code(self, template_utility_code,
370                             template_function_name):
371        type_name = self.typedef_cname.replace(" ","_").replace("::","__")
372        utility_code = template_utility_code.specialize(
373            type     = self.typedef_cname,
374            TypeName = type_name)
375        function_name = template_function_name % type_name
376        return utility_code, function_name
377
378    def create_to_py_utility_code(self, env):
379        if self.typedef_is_external:
380            if not self.to_py_utility_code:
381                base_type = self.typedef_base_type
382                if type(base_type) is CIntType:
383                    self.to_py_function = "__Pyx_PyInt_From_" + self.specialization_name()
384                    env.use_utility_code(TempitaUtilityCode.load(
385                        "CIntToPy", "TypeConversion.c",
386                        context={"TYPE": self.declaration_code(''),
387                                 "TO_PY_FUNCTION": self.to_py_function}))
388                    return True
389                elif base_type.is_float:
390                    pass # XXX implement!
391                elif base_type.is_complex:
392                    pass # XXX implement!
393                    pass
394            if self.to_py_utility_code:
395                env.use_utility_code(self.to_py_utility_code)
396                return True
397        # delegation
398        return self.typedef_base_type.create_to_py_utility_code(env)
399
400    def create_from_py_utility_code(self, env):
401        if self.typedef_is_external:
402            if not self.from_py_utility_code:
403                base_type = self.typedef_base_type
404                if type(base_type) is CIntType:
405                    self.from_py_function = "__Pyx_PyInt_As_" + self.specialization_name()
406                    env.use_utility_code(TempitaUtilityCode.load(
407                        "CIntFromPy", "TypeConversion.c",
408                        context={"TYPE": self.declaration_code(''),
409                                 "FROM_PY_FUNCTION": self.from_py_function}))
410                    return True
411                elif base_type.is_float:
412                    pass # XXX implement!
413                elif base_type.is_complex:
414                    pass # XXX implement!
415            if self.from_py_utility_code:
416                env.use_utility_code(self.from_py_utility_code)
417                return True
418        # delegation
419        return self.typedef_base_type.create_from_py_utility_code(env)
420
421    def overflow_check_binop(self, binop, env, const_rhs=False):
422        env.use_utility_code(UtilityCode.load("Common", "Overflow.c"))
423        type = self.declaration_code("")
424        name = self.specialization_name()
425        if binop == "lshift":
426            env.use_utility_code(TempitaUtilityCode.load(
427                "LeftShift", "Overflow.c",
428                context={'TYPE': type, 'NAME': name, 'SIGNED': self.signed}))
429        else:
430            if const_rhs:
431                binop += "_const"
432            _load_overflow_base(env)
433            env.use_utility_code(TempitaUtilityCode.load(
434                "SizeCheck", "Overflow.c",
435                context={'TYPE': type, 'NAME': name}))
436            env.use_utility_code(TempitaUtilityCode.load(
437                "Binop", "Overflow.c",
438                context={'TYPE': type, 'NAME': name, 'BINOP': binop}))
439        return "__Pyx_%s_%s_checking_overflow" % (binop, name)
440
441    def error_condition(self, result_code):
442        if self.typedef_is_external:
443            if self.exception_value:
444                condition = "(%s == (%s)%s)" % (
445                    result_code, self.typedef_cname, self.exception_value)
446                if self.exception_check:
447                    condition += " && PyErr_Occurred()"
448                return condition
449        # delegation
450        return self.typedef_base_type.error_condition(result_code)
451
452    def __getattr__(self, name):
453        return getattr(self.typedef_base_type, name)
454
455    def py_type_name(self):
456        return self.typedef_base_type.py_type_name()
457
458    def can_coerce_to_pyobject(self, env):
459        return self.typedef_base_type.can_coerce_to_pyobject(env)
460
461
462class MemoryViewSliceType(PyrexType):
463
464    is_memoryviewslice = 1
465
466    has_attributes = 1
467    scope = None
468
469    # These are special cased in Defnode
470    from_py_function = None
471    to_py_function = None
472
473    exception_value = None
474    exception_check = True
475
476    subtypes = ['dtype']
477
478    def __init__(self, base_dtype, axes):
479        """
480        MemoryViewSliceType(base, axes)
481
482        Base is the C base type; axes is a list of (access, packing) strings,
483        where access is one of 'full', 'direct' or 'ptr' and packing is one of
484        'contig', 'strided' or 'follow'.  There is one (access, packing) tuple
485        for each dimension.
486
487        the access specifiers determine whether the array data contains
488        pointers that need to be dereferenced along that axis when
489        retrieving/setting:
490
491        'direct' -- No pointers stored in this dimension.
492        'ptr' -- Pointer stored in this dimension.
493        'full' -- Check along this dimension, don't assume either.
494
495        the packing specifiers specify how the array elements are layed-out
496        in memory.
497
498        'contig' -- The data are contiguous in memory along this dimension.
499                At most one dimension may be specified as 'contig'.
500        'strided' -- The data aren't contiguous along this dimenison.
501        'follow' -- Used for C/Fortran contiguous arrays, a 'follow' dimension
502            has its stride automatically computed from extents of the other
503            dimensions to ensure C or Fortran memory layout.
504
505        C-contiguous memory has 'direct' as the access spec, 'contig' as the
506        *last* axis' packing spec and 'follow' for all other packing specs.
507
508        Fortran-contiguous memory has 'direct' as the access spec, 'contig' as
509        the *first* axis' packing spec and 'follow' for all other packing
510        specs.
511        """
512        import MemoryView
513
514        self.dtype = base_dtype
515        self.axes = axes
516        self.ndim = len(axes)
517        self.flags = MemoryView.get_buf_flags(self.axes)
518
519        self.is_c_contig, self.is_f_contig = MemoryView.is_cf_contig(self.axes)
520        assert not (self.is_c_contig and self.is_f_contig)
521
522        self.mode = MemoryView.get_mode(axes)
523        self.writable_needed = False
524
525        if not self.dtype.is_fused:
526            self.dtype_name = MemoryView.mangle_dtype_name(self.dtype)
527
528    def same_as_resolved_type(self, other_type):
529        return ((other_type.is_memoryviewslice and
530            self.dtype.same_as(other_type.dtype) and
531            self.axes == other_type.axes) or
532            other_type is error_type)
533
534    def needs_nonecheck(self):
535        return True
536
537    def is_complete(self):
538        # incomplete since the underlying struct doesn't have a cython.memoryview object.
539        return 0
540
541    def declaration_code(self, entity_code,
542            for_display = 0, dll_linkage = None, pyrex = 0):
543        # XXX: we put these guards in for now...
544        assert not pyrex
545        assert not dll_linkage
546        import MemoryView
547        return self.base_declaration_code(
548                MemoryView.memviewslice_cname,
549                entity_code)
550
551    def attributes_known(self):
552        if self.scope is None:
553            import Symtab
554
555            self.scope = scope = Symtab.CClassScope(
556                    'mvs_class_'+self.specialization_suffix(),
557                    None,
558                    visibility='extern')
559
560            scope.parent_type = self
561            scope.directives = {}
562
563            scope.declare_var('_data', c_char_ptr_type, None,
564                              cname='data', is_cdef=1)
565
566        return True
567
568    def declare_attribute(self, attribute, env, pos):
569        import MemoryView, Options
570
571        scope = self.scope
572
573        if attribute == 'shape':
574            scope.declare_var('shape',
575                    c_array_type(c_py_ssize_t_type,
576                                 Options.buffer_max_dims),
577                    pos,
578                    cname='shape',
579                    is_cdef=1)
580
581        elif attribute == 'strides':
582            scope.declare_var('strides',
583                    c_array_type(c_py_ssize_t_type,
584                                 Options.buffer_max_dims),
585                    pos,
586                    cname='strides',
587                    is_cdef=1)
588
589        elif attribute == 'suboffsets':
590            scope.declare_var('suboffsets',
591                    c_array_type(c_py_ssize_t_type,
592                                 Options.buffer_max_dims),
593                    pos,
594                    cname='suboffsets',
595                    is_cdef=1)
596
597        elif attribute in ("copy", "copy_fortran"):
598            ndim = len(self.axes)
599
600            to_axes_c = [('direct', 'contig')]
601            to_axes_f = [('direct', 'contig')]
602            if ndim - 1:
603                to_axes_c = [('direct', 'follow')]*(ndim-1) + to_axes_c
604                to_axes_f = to_axes_f + [('direct', 'follow')]*(ndim-1)
605
606            to_memview_c = MemoryViewSliceType(self.dtype, to_axes_c)
607            to_memview_f = MemoryViewSliceType(self.dtype, to_axes_f)
608
609            for to_memview, cython_name in [(to_memview_c, "copy"),
610                                            (to_memview_f, "copy_fortran")]:
611                entry = scope.declare_cfunction(cython_name,
612                            CFuncType(self, [CFuncTypeArg("memviewslice", self, None)]),
613                            pos=pos,
614                            defining=1,
615                            cname=MemoryView.copy_c_or_fortran_cname(to_memview))
616
617                #entry.utility_code_definition = \
618                env.use_utility_code(MemoryView.get_copy_new_utility(pos, self, to_memview))
619
620            MemoryView.use_cython_array_utility_code(env)
621
622        elif attribute in ("is_c_contig", "is_f_contig"):
623            # is_c_contig and is_f_contig functions
624            for (c_or_f, cython_name) in (('c', 'is_c_contig'), ('f', 'is_f_contig')):
625
626                is_contig_name = \
627                        MemoryView.get_is_contig_func_name(c_or_f, self.ndim)
628
629                cfunctype = CFuncType(
630                        return_type=c_bint_type,
631                        args=[CFuncTypeArg("memviewslice", self, None)],
632                        exception_value="-1",
633                )
634
635                entry = scope.declare_cfunction(cython_name,
636                            cfunctype,
637                            pos=pos,
638                            defining=1,
639                            cname=is_contig_name)
640
641                entry.utility_code_definition = MemoryView.get_is_contig_utility(
642                                            attribute == 'is_c_contig', self.ndim)
643
644        return True
645
646    def specialization_suffix(self):
647        return "%s_%s" % (self.axes_to_name(), self.dtype_name)
648
649    def can_coerce_to_pyobject(self, env):
650        return True
651
652    def check_for_null_code(self, cname):
653        return cname + '.memview'
654
655    def create_from_py_utility_code(self, env):
656        import MemoryView, Buffer
657
658        # We don't have 'code', so use a LazyUtilityCode with a callback.
659        def lazy_utility_callback(code):
660            context['dtype_typeinfo'] = Buffer.get_type_information_cname(
661                                                          code, self.dtype)
662            return TempitaUtilityCode.load(
663                        "ObjectToMemviewSlice", "MemoryView_C.c", context=context)
664
665        env.use_utility_code(Buffer.acquire_utility_code)
666        env.use_utility_code(MemoryView.memviewslice_init_code)
667        env.use_utility_code(LazyUtilityCode(lazy_utility_callback))
668
669        if self.is_c_contig:
670            c_or_f_flag = "__Pyx_IS_C_CONTIG"
671        elif self.is_f_contig:
672            c_or_f_flag = "__Pyx_IS_F_CONTIG"
673        else:
674            c_or_f_flag = "0"
675
676        suffix = self.specialization_suffix()
677        funcname = "__Pyx_PyObject_to_MemoryviewSlice_" + suffix
678
679        context = dict(
680            MemoryView.context,
681            buf_flag = self.flags,
682            ndim = self.ndim,
683            axes_specs = ', '.join(self.axes_to_code()),
684            dtype_typedecl = self.dtype.declaration_code(""),
685            struct_nesting_depth = self.dtype.struct_nesting_depth(),
686            c_or_f_flag = c_or_f_flag,
687            funcname = funcname,
688        )
689
690        self.from_py_function = funcname
691        return True
692
693    def create_to_py_utility_code(self, env):
694        return True
695
696    def get_to_py_function(self, env, obj):
697        to_py_func, from_py_func = self.dtype_object_conversion_funcs(env)
698        to_py_func = "(PyObject *(*)(char *)) " + to_py_func
699        from_py_func = "(int (*)(char *, PyObject *)) " + from_py_func
700
701        tup = (obj.result(), self.ndim, to_py_func, from_py_func,
702               self.dtype.is_pyobject)
703        return "__pyx_memoryview_fromslice(%s, %s, %s, %s, %d);" % tup
704
705    def dtype_object_conversion_funcs(self, env):
706        get_function = "__pyx_memview_get_%s" % self.dtype_name
707        set_function = "__pyx_memview_set_%s" % self.dtype_name
708
709        context = dict(
710            get_function = get_function,
711            set_function = set_function,
712        )
713
714        if self.dtype.is_pyobject:
715            utility_name = "MemviewObjectToObject"
716        else:
717            to_py = self.dtype.create_to_py_utility_code(env)
718            from_py = self.dtype.create_from_py_utility_code(env)
719            if not (to_py or from_py):
720                return "NULL", "NULL"
721
722            if not self.dtype.to_py_function:
723                get_function = "NULL"
724
725            if not self.dtype.from_py_function:
726                set_function = "NULL"
727
728            utility_name = "MemviewDtypeToObject"
729            error_condition = (self.dtype.error_condition('value') or
730                               'PyErr_Occurred()')
731            context.update(
732                to_py_function = self.dtype.to_py_function,
733                from_py_function = self.dtype.from_py_function,
734                dtype = self.dtype.declaration_code(""),
735                error_condition = error_condition,
736            )
737
738        utility = TempitaUtilityCode.load(
739                        utility_name, "MemoryView_C.c", context=context)
740        env.use_utility_code(utility)
741        return get_function, set_function
742
743    def axes_to_code(self):
744        """Return a list of code constants for each axis"""
745        import MemoryView
746        d = MemoryView._spec_to_const
747        return ["(%s | %s)" % (d[a], d[p]) for a, p in self.axes]
748
749    def axes_to_name(self):
750        """Return an abbreviated name for our axes"""
751        import MemoryView
752        d = MemoryView._spec_to_abbrev
753        return "".join(["%s%s" % (d[a], d[p]) for a, p in self.axes])
754
755    def error_condition(self, result_code):
756        return "!%s.memview" % result_code
757
758    def __str__(self):
759        import MemoryView
760
761        axes_code_list = []
762        for idx, (access, packing) in enumerate(self.axes):
763            flag = MemoryView.get_memoryview_flag(access, packing)
764            if flag == "strided":
765                axes_code_list.append(":")
766            else:
767                if flag == 'contiguous':
768                    have_follow = [p for a, p in self.axes[idx - 1:idx + 2]
769                                         if p == 'follow']
770                    if have_follow or self.ndim == 1:
771                        flag = '1'
772
773                axes_code_list.append("::" + flag)
774
775        if self.dtype.is_pyobject:
776            dtype_name = self.dtype.name
777        else:
778            dtype_name = self.dtype
779
780        return "%s[%s]" % (dtype_name, ", ".join(axes_code_list))
781
782    def specialize(self, values):
783        """This does not validate the base type!!"""
784        dtype = self.dtype.specialize(values)
785        if dtype is not self.dtype:
786            return MemoryViewSliceType(dtype, self.axes)
787
788        return self
789
790    def cast_code(self, expr_code):
791        return expr_code
792
793
794class BufferType(BaseType):
795    #
796    #  Delegates most attribute lookups to the base type.
797    #  (Anything not defined here or in the BaseType is delegated.)
798    #
799    # dtype            PyrexType
800    # ndim             int
801    # mode             str
802    # negative_indices bool
803    # cast             bool
804    # is_buffer        bool
805    # writable         bool
806
807    is_buffer = 1
808    writable = True
809
810    subtypes = ['dtype']
811
812    def __init__(self, base, dtype, ndim, mode, negative_indices, cast):
813        self.base = base
814        self.dtype = dtype
815        self.ndim = ndim
816        self.buffer_ptr_type = CPtrType(dtype)
817        self.mode = mode
818        self.negative_indices = negative_indices
819        self.cast = cast
820
821    def as_argument_type(self):
822        return self
823
824    def specialize(self, values):
825        dtype = self.dtype.specialize(values)
826        if dtype is not self.dtype:
827            return BufferType(self.base, dtype, self.ndim, self.mode,
828                              self.negative_indices, self.cast)
829        return self
830
831    def __getattr__(self, name):
832        return getattr(self.base, name)
833
834    def __repr__(self):
835        return "<BufferType %r>" % self.base
836
837    def __str__(self):
838        # avoid ', ', as fused functions split the signature string on ', '
839        cast_str = ''
840        if self.cast:
841            cast_str = ',cast=True'
842
843        return "%s[%s,ndim=%d%s]" % (self.base, self.dtype, self.ndim,
844                                      cast_str)
845
846    def assignable_from(self, other_type):
847        if other_type.is_buffer:
848            return (self.same_as(other_type, compare_base=False) and
849                    self.base.assignable_from(other_type.base))
850
851        return self.base.assignable_from(other_type)
852
853    def same_as(self, other_type, compare_base=True):
854        if not other_type.is_buffer:
855            return other_type.same_as(self.base)
856
857        return (self.dtype.same_as(other_type.dtype) and
858                self.ndim == other_type.ndim and
859                self.mode == other_type.mode and
860                self.cast == other_type.cast and
861                (not compare_base or self.base.same_as(other_type.base)))
862
863
864class PyObjectType(PyrexType):
865    #
866    #  Base class for all Python object types (reference-counted).
867    #
868    #  buffer_defaults  dict or None     Default options for bu
869
870    name = "object"
871    is_pyobject = 1
872    default_value = "0"
873    buffer_defaults = None
874    is_extern = False
875    is_subclassed = False
876    is_gc_simple = False
877
878    def __str__(self):
879        return "Python object"
880
881    def __repr__(self):
882        return "<PyObjectType>"
883
884    def can_coerce_to_pyobject(self, env):
885        return True
886
887    def default_coerced_ctype(self):
888        """The default C type that this Python type coerces to, or None."""
889        return None
890
891    def assignable_from(self, src_type):
892        # except for pointers, conversion will be attempted
893        return not src_type.is_ptr or src_type.is_string or src_type.is_pyunicode_ptr
894
895    def declaration_code(self, entity_code,
896            for_display = 0, dll_linkage = None, pyrex = 0):
897        if pyrex or for_display:
898            base_code = "object"
899        else:
900            base_code = public_decl("PyObject", dll_linkage)
901            entity_code = "*%s" % entity_code
902        return self.base_declaration_code(base_code, entity_code)
903
904    def as_pyobject(self, cname):
905        if (not self.is_complete()) or self.is_extension_type:
906            return "(PyObject *)" + cname
907        else:
908            return cname
909
910    def py_type_name(self):
911        return "object"
912
913    def __lt__(self, other):
914        """
915        Make sure we sort highest, as instance checking on py_type_name
916        ('object') is always true
917        """
918        return False
919
920    def global_init_code(self, entry, code):
921        code.put_init_var_to_py_none(entry, nanny=False)
922
923    def check_for_null_code(self, cname):
924        return cname
925
926
927builtin_types_that_cannot_create_refcycles = set([
928    'bool', 'int', 'long', 'float', 'complex',
929    'bytearray', 'bytes', 'unicode', 'str', 'basestring'
930])
931
932
933class BuiltinObjectType(PyObjectType):
934    #  objstruct_cname  string           Name of PyObject struct
935
936    is_builtin_type = 1
937    has_attributes = 1
938    base_type = None
939    module_name = '__builtin__'
940
941    # fields that let it look like an extension type
942    vtabslot_cname = None
943    vtabstruct_cname = None
944    vtabptr_cname = None
945    typedef_flag = True
946    is_external = True
947
948    def __init__(self, name, cname, objstruct_cname=None):
949        self.name = name
950        self.cname = cname
951        self.typeptr_cname = "(&%s)" % cname
952        self.objstruct_cname = objstruct_cname
953        self.is_gc_simple = name in builtin_types_that_cannot_create_refcycles
954
955    def set_scope(self, scope):
956        self.scope = scope
957        if scope:
958            scope.parent_type = self
959
960    def __str__(self):
961        return "%s object" % self.name
962
963    def __repr__(self):
964        return "<%s>"% self.cname
965
966    def default_coerced_ctype(self):
967        if self.name in ('bytes', 'bytearray'):
968            return c_char_ptr_type
969        elif self.name == 'bool':
970            return c_bint_type
971        elif self.name == 'float':
972            return c_double_type
973        return None
974
975    def assignable_from(self, src_type):
976        if isinstance(src_type, BuiltinObjectType):
977            if self.name == 'basestring':
978                return src_type.name in ('str', 'unicode', 'basestring')
979            else:
980                return src_type.name == self.name
981        elif src_type.is_extension_type:
982            # FIXME: This is an ugly special case that we currently
983            # keep supporting.  It allows users to specify builtin
984            # types as external extension types, while keeping them
985            # compatible with the real builtin types.  We already
986            # generate a warning for it.  Big TODO: remove!
987            return (src_type.module_name == '__builtin__' and
988                    src_type.name == self.name)
989        else:
990            return True
991
992    def typeobj_is_available(self):
993        return True
994
995    def attributes_known(self):
996        return True
997
998    def subtype_of(self, type):
999        return type.is_pyobject and type.assignable_from(self)
1000
1001    def type_check_function(self, exact=True):
1002        type_name = self.name
1003        if type_name == 'str':
1004            type_check = 'PyString_Check'
1005        elif type_name == 'basestring':
1006            type_check = '__Pyx_PyBaseString_Check'
1007        elif type_name == 'bytearray':
1008            type_check = 'PyByteArray_Check'
1009        elif type_name == 'frozenset':
1010            type_check = 'PyFrozenSet_Check'
1011        else:
1012            type_check = 'Py%s_Check' % type_name.capitalize()
1013        if exact and type_name not in ('bool', 'slice'):
1014            type_check += 'Exact'
1015        return type_check
1016
1017    def isinstance_code(self, arg):
1018        return '%s(%s)' % (self.type_check_function(exact=False), arg)
1019
1020    def type_test_code(self, arg, notnone=False, exact=True):
1021        type_check = self.type_check_function(exact=exact)
1022        check = 'likely(%s(%s))' % (type_check, arg)
1023        if not notnone:
1024            check += '||((%s) == Py_None)' % arg
1025        if self.name == 'basestring':
1026            name = '(PY_MAJOR_VERSION < 3 ? "basestring" : "str")'
1027            space_for_name = 16
1028        else:
1029            name = '"%s"' % self.name
1030            # avoid wasting too much space but limit number of different format strings
1031            space_for_name = (len(self.name) // 16 + 1) * 16
1032        error = '(PyErr_Format(PyExc_TypeError, "Expected %%.%ds, got %%.200s", %s, Py_TYPE(%s)->tp_name), 0)' % (
1033            space_for_name, name, arg)
1034        return check + '||' + error
1035
1036    def declaration_code(self, entity_code,
1037            for_display = 0, dll_linkage = None, pyrex = 0):
1038        if pyrex or for_display:
1039            base_code = self.name
1040        else:
1041            base_code = public_decl("PyObject", dll_linkage)
1042            entity_code = "*%s" % entity_code
1043        return self.base_declaration_code(base_code, entity_code)
1044
1045    def cast_code(self, expr_code, to_object_struct = False):
1046        return "((%s*)%s)" % (
1047            to_object_struct and self.objstruct_cname or "PyObject", # self.objstruct_cname may be None
1048            expr_code)
1049
1050    def py_type_name(self):
1051        return self.name
1052
1053
1054
1055class PyExtensionType(PyObjectType):
1056    #
1057    #  A Python extension type.
1058    #
1059    #  name             string
1060    #  scope            CClassScope      Attribute namespace
1061    #  visibility       string
1062    #  typedef_flag     boolean
1063    #  base_type        PyExtensionType or None
1064    #  module_name      string or None   Qualified name of defining module
1065    #  objstruct_cname  string           Name of PyObject struct
1066    #  objtypedef_cname string           Name of PyObject struct typedef
1067    #  typeobj_cname    string or None   C code fragment referring to type object
1068    #  typeptr_cname    string or None   Name of pointer to external type object
1069    #  vtabslot_cname   string           Name of C method table member
1070    #  vtabstruct_cname string           Name of C method table struct
1071    #  vtabptr_cname    string           Name of pointer to C method table
1072    #  vtable_cname     string           Name of C method table definition
1073    #  defered_declarations [thunk]      Used to declare class hierarchies in order
1074
1075    is_extension_type = 1
1076    has_attributes = 1
1077
1078    objtypedef_cname = None
1079
1080    def __init__(self, name, typedef_flag, base_type, is_external=0):
1081        self.name = name
1082        self.scope = None
1083        self.typedef_flag = typedef_flag
1084        if base_type is not None:
1085            base_type.is_subclassed = True
1086        self.base_type = base_type
1087        self.module_name = None
1088        self.objstruct_cname = None
1089        self.typeobj_cname = None
1090        self.typeptr_cname = None
1091        self.vtabslot_cname = None
1092        self.vtabstruct_cname = None
1093        self.vtabptr_cname = None
1094        self.vtable_cname = None
1095        self.is_external = is_external
1096        self.defered_declarations = []
1097
1098    def set_scope(self, scope):
1099        self.scope = scope
1100        if scope:
1101            scope.parent_type = self
1102
1103    def needs_nonecheck(self):
1104        return True
1105
1106    def subtype_of_resolved_type(self, other_type):
1107        if other_type.is_extension_type or other_type.is_builtin_type:
1108            return self is other_type or (
1109                self.base_type and self.base_type.subtype_of(other_type))
1110        else:
1111            return other_type is py_object_type
1112
1113    def typeobj_is_available(self):
1114        # Do we have a pointer to the type object?
1115        return self.typeptr_cname
1116
1117    def typeobj_is_imported(self):
1118        # If we don't know the C name of the type object but we do
1119        # know which module it's defined in, it will be imported.
1120        return self.typeobj_cname is None and self.module_name is not None
1121
1122    def assignable_from(self, src_type):
1123        if self == src_type:
1124            return True
1125        if isinstance(src_type, PyExtensionType):
1126            if src_type.base_type is not None:
1127                return self.assignable_from(src_type.base_type)
1128        if isinstance(src_type, BuiltinObjectType):
1129            # FIXME: This is an ugly special case that we currently
1130            # keep supporting.  It allows users to specify builtin
1131            # types as external extension types, while keeping them
1132            # compatible with the real builtin types.  We already
1133            # generate a warning for it.  Big TODO: remove!
1134            return (self.module_name == '__builtin__' and
1135                    self.name == src_type.name)
1136        return False
1137
1138    def declaration_code(self, entity_code,
1139            for_display = 0, dll_linkage = None, pyrex = 0, deref = 0):
1140        if pyrex or for_display:
1141            base_code = self.name
1142        else:
1143            if self.typedef_flag:
1144                objstruct = self.objstruct_cname
1145            else:
1146                objstruct = "struct %s" % self.objstruct_cname
1147            base_code = public_decl(objstruct, dll_linkage)
1148            if deref:
1149                assert not entity_code
1150            else:
1151                entity_code = "*%s" % entity_code
1152        return self.base_declaration_code(base_code, entity_code)
1153
1154    def type_test_code(self, py_arg, notnone=False):
1155
1156        none_check = "((%s) == Py_None)" % py_arg
1157        type_check = "likely(__Pyx_TypeTest(%s, %s))" % (
1158            py_arg, self.typeptr_cname)
1159        if notnone:
1160            return type_check
1161        else:
1162            return "likely(%s || %s)" % (none_check, type_check)
1163
1164    def attributes_known(self):
1165        return self.scope is not None
1166
1167    def __str__(self):
1168        return self.name
1169
1170    def __repr__(self):
1171        return "<PyExtensionType %s%s>" % (self.scope.class_name,
1172            ("", " typedef")[self.typedef_flag])
1173
1174    def py_type_name(self):
1175        if not self.module_name:
1176            return self.name
1177
1178        return "__import__(%r, None, None, ['']).%s" % (self.module_name,
1179                                                        self.name)
1180
1181class CType(PyrexType):
1182    #
1183    #  Base class for all C types (non-reference-counted).
1184    #
1185    #  to_py_function     string     C function for converting to Python object
1186    #  from_py_function   string     C function for constructing from Python object
1187    #
1188
1189    to_py_function = None
1190    from_py_function = None
1191    exception_value = None
1192    exception_check = 1
1193
1194    def create_to_py_utility_code(self, env):
1195        return self.to_py_function is not None
1196
1197    def create_from_py_utility_code(self, env):
1198        return self.from_py_function is not None
1199
1200    def can_coerce_to_pyobject(self, env):
1201        return self.create_to_py_utility_code(env)
1202
1203    def error_condition(self, result_code):
1204        conds = []
1205        if self.is_string or self.is_pyunicode_ptr:
1206            conds.append("(!%s)" % result_code)
1207        elif self.exception_value is not None:
1208            conds.append("(%s == (%s)%s)" % (result_code, self.sign_and_name(), self.exception_value))
1209        if self.exception_check:
1210            conds.append("PyErr_Occurred()")
1211        if len(conds) > 0:
1212            return " && ".join(conds)
1213        else:
1214            return 0
1215
1216
1217class CConstType(BaseType):
1218
1219    is_const = 1
1220
1221    def __init__(self, const_base_type):
1222        self.const_base_type = const_base_type
1223        if const_base_type.has_attributes and const_base_type.scope is not None:
1224            import Symtab
1225            self.scope = Symtab.CConstScope(const_base_type.scope)
1226
1227    def __repr__(self):
1228        return "<CConstType %s>" % repr(self.const_base_type)
1229
1230    def __str__(self):
1231        return self.declaration_code("", for_display=1)
1232
1233    def declaration_code(self, entity_code,
1234            for_display = 0, dll_linkage = None, pyrex = 0):
1235        return self.const_base_type.declaration_code("const %s" % entity_code, for_display, dll_linkage, pyrex)
1236
1237    def specialize(self, values):
1238        base_type = self.const_base_type.specialize(values)
1239        if base_type == self.const_base_type:
1240            return self
1241        else:
1242            return CConstType(base_type)
1243
1244    def deduce_template_params(self, actual):
1245        return self.const_base_type.deduce_template_params(actual)
1246
1247    def create_to_py_utility_code(self, env):
1248        if self.const_base_type.create_to_py_utility_code(env):
1249            self.to_py_function = self.const_base_type.to_py_function
1250            return True
1251
1252    def __getattr__(self, name):
1253        return getattr(self.const_base_type, name)
1254
1255
1256class FusedType(CType):
1257    """
1258    Represents a Fused Type. All it needs to do is keep track of the types
1259    it aggregates, as it will be replaced with its specific version wherever
1260    needed.
1261
1262    See http://wiki.cython.org/enhancements/fusedtypes
1263
1264    types           [PyrexType]             is the list of types to be fused
1265    name            str                     the name of the ctypedef
1266    """
1267
1268    is_fused = 1
1269    exception_check = 0
1270
1271    def __init__(self, types, name=None):
1272        self.types = types
1273        self.name = name
1274
1275    def declaration_code(self, entity_code, for_display = 0,
1276                         dll_linkage = None, pyrex = 0):
1277        if pyrex or for_display:
1278            return self.name
1279
1280        raise Exception("This may never happen, please report a bug")
1281
1282    def __repr__(self):
1283        return 'FusedType(name=%r)' % self.name
1284
1285    def specialize(self, values):
1286        return values[self]
1287
1288    def get_fused_types(self, result=None, seen=None):
1289        if result is None:
1290            return [self]
1291
1292        if self not in seen:
1293            result.append(self)
1294            seen.add(self)
1295
1296
1297class CVoidType(CType):
1298    #
1299    #   C "void" type
1300    #
1301
1302    is_void = 1
1303
1304    def __repr__(self):
1305        return "<CVoidType>"
1306
1307    def declaration_code(self, entity_code,
1308            for_display = 0, dll_linkage = None, pyrex = 0):
1309        if pyrex or for_display:
1310            base_code = "void"
1311        else:
1312            base_code = public_decl("void", dll_linkage)
1313        return self.base_declaration_code(base_code, entity_code)
1314
1315    def is_complete(self):
1316        return 0
1317
1318class InvisibleVoidType(CVoidType):
1319    #
1320    #   For use with C++ constructors and destructors return types.
1321    #   Acts like void, but does not print out a declaration.
1322    #
1323    def declaration_code(self, entity_code,
1324            for_display = 0, dll_linkage = None, pyrex = 0):
1325        if pyrex or for_display:
1326            base_code = "[void]"
1327        else:
1328            base_code = public_decl("", dll_linkage)
1329        return self.base_declaration_code(base_code, entity_code)
1330
1331
1332class CNumericType(CType):
1333    #
1334    #   Base class for all C numeric types.
1335    #
1336    #   rank      integer     Relative size
1337    #   signed    integer     0 = unsigned, 1 = unspecified, 2 = explicitly signed
1338    #
1339
1340    is_numeric = 1
1341    default_value = "0"
1342    has_attributes = True
1343    scope = None
1344
1345    sign_words = ("unsigned ", "", "signed ")
1346
1347    def __init__(self, rank, signed = 1):
1348        self.rank = rank
1349        self.signed = signed
1350
1351    def sign_and_name(self):
1352        s = self.sign_words[self.signed]
1353        n = rank_to_type_name[self.rank]
1354        return s + n
1355
1356    def __repr__(self):
1357        return "<CNumericType %s>" % self.sign_and_name()
1358
1359    def declaration_code(self, entity_code,
1360            for_display = 0, dll_linkage = None, pyrex = 0):
1361        type_name = self.sign_and_name()
1362        if pyrex or for_display:
1363            base_code = type_name.replace('PY_LONG_LONG', 'long long')
1364        else:
1365            base_code = public_decl(type_name, dll_linkage)
1366        return self.base_declaration_code(base_code, entity_code)
1367
1368    def attributes_known(self):
1369        if self.scope is None:
1370            import Symtab
1371            self.scope = scope = Symtab.CClassScope(
1372                    '',
1373                    None,
1374                    visibility="extern")
1375            scope.parent_type = self
1376            scope.directives = {}
1377            scope.declare_cfunction(
1378                    "conjugate",
1379                    CFuncType(self, [CFuncTypeArg("self", self, None)], nogil=True),
1380                    pos=None,
1381                    defining=1,
1382                    cname=" ")
1383        return True
1384
1385    def __lt__(self, other):
1386        """Sort based on rank, preferring signed over unsigned"""
1387        if other.is_numeric:
1388            return self.rank > other.rank and self.signed >= other.signed
1389
1390        # Prefer numeric types over others
1391        return True
1392
1393    def py_type_name(self):
1394        if self.rank <= 4:
1395            return "(int, long)"
1396        return "float"
1397
1398
1399class ForbidUseClass:
1400    def __repr__(self):
1401        raise RuntimeError()
1402    def __str__(self):
1403        raise RuntimeError()
1404ForbidUse = ForbidUseClass()
1405
1406
1407class CIntType(CNumericType):
1408
1409    is_int = 1
1410    typedef_flag = 0
1411    to_py_function = None
1412    from_py_function = None
1413    exception_value = -1
1414
1415    def create_to_py_utility_code(self, env):
1416        if type(self).to_py_function is None:
1417            self.to_py_function = "__Pyx_PyInt_From_" + self.specialization_name()
1418            env.use_utility_code(TempitaUtilityCode.load(
1419                "CIntToPy", "TypeConversion.c",
1420                context={"TYPE": self.declaration_code(''),
1421                         "TO_PY_FUNCTION": self.to_py_function}))
1422        return True
1423
1424    def create_from_py_utility_code(self, env):
1425        if type(self).from_py_function is None:
1426            self.from_py_function = "__Pyx_PyInt_As_" + self.specialization_name()
1427            env.use_utility_code(TempitaUtilityCode.load(
1428                "CIntFromPy", "TypeConversion.c",
1429                context={"TYPE": self.declaration_code(''),
1430                         "FROM_PY_FUNCTION": self.from_py_function}))
1431        return True
1432
1433    def get_to_py_type_conversion(self):
1434        if self.rank < list(rank_to_type_name).index('int'):
1435            # This assumes sizeof(short) < sizeof(int)
1436            return "PyInt_FromLong"
1437        else:
1438            # Py{Int|Long}_From[Unsigned]Long[Long]
1439            Prefix = "Int"
1440            SignWord = ""
1441            TypeName = "Long"
1442            if not self.signed:
1443                Prefix = "Long"
1444                SignWord = "Unsigned"
1445            if self.rank >= list(rank_to_type_name).index('PY_LONG_LONG'):
1446                Prefix = "Long"
1447                TypeName = "LongLong"
1448            return "Py%s_From%s%s" % (Prefix, SignWord, TypeName)
1449
1450    def get_from_py_type_conversion(self):
1451        type_name = rank_to_type_name[self.rank]
1452        type_name = type_name.replace("PY_LONG_LONG", "long long")
1453        TypeName = type_name.title().replace(" ", "")
1454        SignWord = self.sign_words[self.signed].strip().title()
1455        if self.rank >= list(rank_to_type_name).index('long'):
1456            utility_code = c_long_from_py_function
1457        else:
1458            utility_code = c_int_from_py_function
1459        utility_code.specialize(self,
1460                                SignWord=SignWord,
1461                                TypeName=TypeName)
1462        func_name = "__Pyx_PyInt_As%s%s" % (SignWord, TypeName)
1463        return func_name
1464
1465    def assignable_from_resolved_type(self, src_type):
1466        return src_type.is_int or src_type.is_enum or src_type is error_type
1467
1468    def invalid_value(self):
1469        if rank_to_type_name[int(self.rank)] == 'char':
1470            return "'?'"
1471        else:
1472            # We do not really know the size of the type, so return
1473            # a 32-bit literal and rely on casting to final type. It will
1474            # be negative for signed ints, which is good.
1475            return "0xbad0bad0"
1476
1477    def overflow_check_binop(self, binop, env, const_rhs=False):
1478        env.use_utility_code(UtilityCode.load("Common", "Overflow.c"))
1479        type = self.declaration_code("")
1480        name = self.specialization_name()
1481        if binop == "lshift":
1482            env.use_utility_code(TempitaUtilityCode.load(
1483                "LeftShift", "Overflow.c",
1484                context={'TYPE': type, 'NAME': name, 'SIGNED': self.signed}))
1485        else:
1486            if const_rhs:
1487                binop += "_const"
1488            if type in ('int', 'long', 'long long'):
1489                env.use_utility_code(TempitaUtilityCode.load(
1490                    "BaseCaseSigned", "Overflow.c",
1491                    context={'INT': type, 'NAME': name}))
1492            elif type in ('unsigned int', 'unsigned long', 'unsigned long long'):
1493                env.use_utility_code(TempitaUtilityCode.load(
1494                    "BaseCaseUnsigned", "Overflow.c",
1495                    context={'UINT': type, 'NAME': name}))
1496            elif self.rank <= 1:
1497                # sizeof(short) < sizeof(int)
1498                return "__Pyx_%s_%s_no_overflow" % (binop, name)
1499            else:
1500                _load_overflow_base(env)
1501                env.use_utility_code(TempitaUtilityCode.load(
1502                    "SizeCheck", "Overflow.c",
1503                    context={'TYPE': type, 'NAME': name}))
1504                env.use_utility_code(TempitaUtilityCode.load(
1505                    "Binop", "Overflow.c",
1506                    context={'TYPE': type, 'NAME': name, 'BINOP': binop}))
1507        return "__Pyx_%s_%s_checking_overflow" % (binop, name)
1508
1509def _load_overflow_base(env):
1510    env.use_utility_code(UtilityCode.load("Common", "Overflow.c"))
1511    for type in ('int', 'long', 'long long'):
1512        env.use_utility_code(TempitaUtilityCode.load(
1513            "BaseCaseSigned", "Overflow.c",
1514            context={'INT': type, 'NAME': type.replace(' ', '_')}))
1515    for type in ('unsigned int', 'unsigned long', 'unsigned long long'):
1516        env.use_utility_code(TempitaUtilityCode.load(
1517            "BaseCaseUnsigned", "Overflow.c",
1518            context={'UINT': type, 'NAME': type.replace(' ', '_')}))
1519
1520
1521class CAnonEnumType(CIntType):
1522
1523    is_enum = 1
1524
1525    def sign_and_name(self):
1526        return 'int'
1527
1528
1529class CReturnCodeType(CIntType):
1530
1531    to_py_function = "__Pyx_Owned_Py_None"
1532
1533    is_returncode = True
1534    exception_check = False
1535
1536
1537class CBIntType(CIntType):
1538
1539    to_py_function = "__Pyx_PyBool_FromLong"
1540    from_py_function = "__Pyx_PyObject_IsTrue"
1541    exception_check = 1 # for C++ bool
1542
1543    def declaration_code(self, entity_code,
1544            for_display = 0, dll_linkage = None, pyrex = 0):
1545        if pyrex or for_display:
1546            base_code = 'bool'
1547        else:
1548            base_code = public_decl('int', dll_linkage)
1549        return self.base_declaration_code(base_code, entity_code)
1550
1551    def __repr__(self):
1552        return "<CNumericType bint>"
1553
1554    def __str__(self):
1555        return 'bint'
1556
1557    def py_type_name(self):
1558        return "bool"
1559
1560
1561class CPyUCS4IntType(CIntType):
1562    # Py_UCS4
1563
1564    is_unicode_char = True
1565
1566    # Py_UCS4 coerces from and to single character unicode strings (or
1567    # at most two characters on 16bit Unicode builds), but we also
1568    # allow Python integers as input.  The value range for Py_UCS4
1569    # is 0..1114111, which is checked when converting from an integer
1570    # value.
1571
1572    to_py_function = "PyUnicode_FromOrdinal"
1573    from_py_function = "__Pyx_PyObject_AsPy_UCS4"
1574
1575    def create_from_py_utility_code(self, env):
1576        env.use_utility_code(UtilityCode.load_cached("ObjectAsUCS4", "TypeConversion.c"))
1577        return True
1578
1579    def sign_and_name(self):
1580        return "Py_UCS4"
1581
1582
1583class CPyUnicodeIntType(CIntType):
1584    # Py_UNICODE
1585
1586    is_unicode_char = True
1587
1588    # Py_UNICODE coerces from and to single character unicode strings,
1589    # but we also allow Python integers as input.  The value range for
1590    # Py_UNICODE is 0..1114111, which is checked when converting from
1591    # an integer value.
1592
1593    to_py_function = "PyUnicode_FromOrdinal"
1594    from_py_function = "__Pyx_PyObject_AsPy_UNICODE"
1595
1596    def create_from_py_utility_code(self, env):
1597        env.use_utility_code(UtilityCode.load_cached("ObjectAsPyUnicode", "TypeConversion.c"))
1598        return True
1599
1600    def sign_and_name(self):
1601        return "Py_UNICODE"
1602
1603
1604class CPyHashTType(CIntType):
1605
1606    to_py_function = "__Pyx_PyInt_FromHash_t"
1607    from_py_function = "__Pyx_PyInt_AsHash_t"
1608
1609    def sign_and_name(self):
1610        return "Py_hash_t"
1611
1612class CPySSizeTType(CIntType):
1613
1614    to_py_function = "PyInt_FromSsize_t"
1615    from_py_function = "__Pyx_PyIndex_AsSsize_t"
1616
1617    def sign_and_name(self):
1618        return "Py_ssize_t"
1619
1620class CSSizeTType(CIntType):
1621
1622    to_py_function = "PyInt_FromSsize_t"
1623    from_py_function = "PyInt_AsSsize_t"
1624
1625    def sign_and_name(self):
1626        return "Py_ssize_t"
1627
1628class CSizeTType(CIntType):
1629
1630    to_py_function = "__Pyx_PyInt_FromSize_t"
1631
1632    def sign_and_name(self):
1633        return "size_t"
1634
1635class CPtrdiffTType(CIntType):
1636
1637    def sign_and_name(self):
1638        return "ptrdiff_t"
1639
1640
1641class CFloatType(CNumericType):
1642
1643    is_float = 1
1644    to_py_function = "PyFloat_FromDouble"
1645    from_py_function = "__pyx_PyFloat_AsDouble"
1646
1647    exception_value = -1
1648
1649    def __init__(self, rank, math_h_modifier = ''):
1650        CNumericType.__init__(self, rank, 1)
1651        self.math_h_modifier = math_h_modifier
1652        if rank == RANK_FLOAT:
1653            self.from_py_function = "__pyx_PyFloat_AsFloat"
1654
1655    def assignable_from_resolved_type(self, src_type):
1656        return (src_type.is_numeric and not src_type.is_complex) or src_type is error_type
1657
1658    def invalid_value(self):
1659        return Naming.PYX_NAN
1660
1661class CComplexType(CNumericType):
1662
1663    is_complex = 1
1664    to_py_function = "__pyx_PyComplex_FromComplex"
1665    has_attributes = 1
1666    scope = None
1667
1668    def __init__(self, real_type):
1669        while real_type.is_typedef and not real_type.typedef_is_external:
1670            real_type = real_type.typedef_base_type
1671        if real_type.is_typedef and real_type.typedef_is_external:
1672            # The below is not actually used: Coercions are currently disabled
1673            # so that complex types of external types can not be created
1674            self.funcsuffix = "_%s" % real_type.specialization_name()
1675        elif hasattr(real_type, 'math_h_modifier'):
1676            self.funcsuffix = real_type.math_h_modifier
1677        else:
1678            self.funcsuffix = "_%s" % real_type.specialization_name()
1679
1680        self.real_type = real_type
1681        CNumericType.__init__(self, real_type.rank + 0.5, real_type.signed)
1682        self.binops = {}
1683        self.from_parts = "%s_from_parts" % self.specialization_name()
1684        self.default_value = "%s(0, 0)" % self.from_parts
1685
1686    def __eq__(self, other):
1687        if isinstance(self, CComplexType) and isinstance(other, CComplexType):
1688            return self.real_type == other.real_type
1689        else:
1690            return False
1691
1692    def __ne__(self, other):
1693        if isinstance(self, CComplexType) and isinstance(other, CComplexType):
1694            return self.real_type != other.real_type
1695        else:
1696            return True
1697
1698    def __lt__(self, other):
1699        if isinstance(self, CComplexType) and isinstance(other, CComplexType):
1700            return self.real_type < other.real_type
1701        else:
1702            # this is arbitrary, but it makes sure we always have
1703            # *some* kind of order
1704            return False
1705
1706    def __hash__(self):
1707        return ~hash(self.real_type)
1708
1709    def declaration_code(self, entity_code,
1710            for_display = 0, dll_linkage = None, pyrex = 0):
1711        if pyrex or for_display:
1712            real_code = self.real_type.declaration_code("", for_display, dll_linkage, pyrex)
1713            base_code = "%s complex" % real_code
1714        else:
1715            base_code = public_decl(self.sign_and_name(), dll_linkage)
1716        return self.base_declaration_code(base_code, entity_code)
1717
1718    def sign_and_name(self):
1719        real_type_name = self.real_type.specialization_name()
1720        real_type_name = real_type_name.replace('long__double','long_double')
1721        real_type_name = real_type_name.replace('PY_LONG_LONG','long_long')
1722        return Naming.type_prefix + real_type_name + "_complex"
1723
1724    def assignable_from(self, src_type):
1725        # Temporary hack/feature disabling, see #441
1726        if (not src_type.is_complex and src_type.is_numeric and src_type.is_typedef
1727            and src_type.typedef_is_external):
1728             return False
1729        else:
1730            return super(CComplexType, self).assignable_from(src_type)
1731
1732    def assignable_from_resolved_type(self, src_type):
1733        return (src_type.is_complex and self.real_type.assignable_from_resolved_type(src_type.real_type)
1734                    or src_type.is_numeric and self.real_type.assignable_from_resolved_type(src_type)
1735                    or src_type is error_type)
1736
1737    def attributes_known(self):
1738        if self.scope is None:
1739            import Symtab
1740            self.scope = scope = Symtab.CClassScope(
1741                    '',
1742                    None,
1743                    visibility="extern")
1744            scope.parent_type = self
1745            scope.directives = {}
1746            scope.declare_var("real", self.real_type, None, cname="real", is_cdef=True)
1747            scope.declare_var("imag", self.real_type, None, cname="imag", is_cdef=True)
1748            scope.declare_cfunction(
1749                    "conjugate",
1750                    CFuncType(self, [CFuncTypeArg("self", self, None)], nogil=True),
1751                    pos=None,
1752                    defining=1,
1753                    cname="__Pyx_c_conj%s" % self.funcsuffix)
1754
1755        return True
1756
1757    def create_declaration_utility_code(self, env):
1758        # This must always be run, because a single CComplexType instance can be shared
1759        # across multiple compilations (the one created in the module scope)
1760        env.use_utility_code(complex_header_utility_code)
1761        env.use_utility_code(complex_real_imag_utility_code)
1762        for utility_code in (complex_type_utility_code,
1763                             complex_from_parts_utility_code,
1764                             complex_arithmetic_utility_code):
1765            env.use_utility_code(
1766                utility_code.specialize(
1767                    self,
1768                    real_type = self.real_type.declaration_code(''),
1769                    m = self.funcsuffix,
1770                    is_float = self.real_type.is_float))
1771        return True
1772
1773    def create_to_py_utility_code(self, env):
1774        env.use_utility_code(complex_real_imag_utility_code)
1775        env.use_utility_code(complex_to_py_utility_code)
1776        return True
1777
1778    def create_from_py_utility_code(self, env):
1779        self.real_type.create_from_py_utility_code(env)
1780
1781        for utility_code in (complex_from_parts_utility_code,
1782                             complex_from_py_utility_code):
1783            env.use_utility_code(
1784                utility_code.specialize(
1785                    self,
1786                    real_type = self.real_type.declaration_code(''),
1787                    m = self.funcsuffix,
1788                    is_float = self.real_type.is_float))
1789        self.from_py_function = "__Pyx_PyComplex_As_" + self.specialization_name()
1790        return True
1791
1792    def lookup_op(self, nargs, op):
1793        try:
1794            return self.binops[nargs, op]
1795        except KeyError:
1796            pass
1797        try:
1798            op_name = complex_ops[nargs, op]
1799            self.binops[nargs, op] = func_name = "__Pyx_c_%s%s" % (op_name, self.funcsuffix)
1800            return func_name
1801        except KeyError:
1802            return None
1803
1804    def unary_op(self, op):
1805        return self.lookup_op(1, op)
1806
1807    def binary_op(self, op):
1808        return self.lookup_op(2, op)
1809
1810    def py_type_name(self):
1811        return "complex"
1812
1813    def cast_code(self, expr_code):
1814        return expr_code
1815
1816complex_ops = {
1817    (1, '-'): 'neg',
1818    (1, 'zero'): 'is_zero',
1819    (2, '+'): 'sum',
1820    (2, '-'): 'diff',
1821    (2, '*'): 'prod',
1822    (2, '/'): 'quot',
1823    (2, '=='): 'eq',
1824}
1825
1826complex_header_utility_code = UtilityCode(
1827proto_block='h_code',
1828proto="""
1829#if !defined(CYTHON_CCOMPLEX)
1830  #if defined(__cplusplus)
1831    #define CYTHON_CCOMPLEX 1
1832  #elif defined(_Complex_I)
1833    #define CYTHON_CCOMPLEX 1
1834  #else
1835    #define CYTHON_CCOMPLEX 0
1836  #endif
1837#endif
1838
1839#if CYTHON_CCOMPLEX
1840  #ifdef __cplusplus
1841    #include <complex>
1842  #else
1843    #include <complex.h>
1844  #endif
1845#endif
1846
1847#if CYTHON_CCOMPLEX && !defined(__cplusplus) && defined(__sun__) && defined(__GNUC__)
1848  #undef _Complex_I
1849  #define _Complex_I 1.0fj
1850#endif
1851""")
1852
1853complex_real_imag_utility_code = UtilityCode(
1854proto="""
1855#if CYTHON_CCOMPLEX
1856  #ifdef __cplusplus
1857    #define __Pyx_CREAL(z) ((z).real())
1858    #define __Pyx_CIMAG(z) ((z).imag())
1859  #else
1860    #define __Pyx_CREAL(z) (__real__(z))
1861    #define __Pyx_CIMAG(z) (__imag__(z))
1862  #endif
1863#else
1864    #define __Pyx_CREAL(z) ((z).real)
1865    #define __Pyx_CIMAG(z) ((z).imag)
1866#endif
1867
1868#if (defined(_WIN32) || defined(__clang__)) && defined(__cplusplus) && CYTHON_CCOMPLEX
1869    #define __Pyx_SET_CREAL(z,x) ((z).real(x))
1870    #define __Pyx_SET_CIMAG(z,y) ((z).imag(y))
1871#else
1872    #define __Pyx_SET_CREAL(z,x) __Pyx_CREAL(z) = (x)
1873    #define __Pyx_SET_CIMAG(z,y) __Pyx_CIMAG(z) = (y)
1874#endif
1875""")
1876
1877complex_type_utility_code = UtilityCode(
1878proto_block='complex_type_declarations',
1879proto="""
1880#if CYTHON_CCOMPLEX
1881  #ifdef __cplusplus
1882    typedef ::std::complex< %(real_type)s > %(type_name)s;
1883  #else
1884    typedef %(real_type)s _Complex %(type_name)s;
1885  #endif
1886#else
1887    typedef struct { %(real_type)s real, imag; } %(type_name)s;
1888#endif
1889""")
1890
1891complex_from_parts_utility_code = UtilityCode(
1892proto_block='utility_code_proto',
1893proto="""
1894static CYTHON_INLINE %(type)s %(type_name)s_from_parts(%(real_type)s, %(real_type)s);
1895""",
1896impl="""
1897#if CYTHON_CCOMPLEX
1898  #ifdef __cplusplus
1899    static CYTHON_INLINE %(type)s %(type_name)s_from_parts(%(real_type)s x, %(real_type)s y) {
1900      return ::std::complex< %(real_type)s >(x, y);
1901    }
1902  #else
1903    static CYTHON_INLINE %(type)s %(type_name)s_from_parts(%(real_type)s x, %(real_type)s y) {
1904      return x + y*(%(type)s)_Complex_I;
1905    }
1906  #endif
1907#else
1908    static CYTHON_INLINE %(type)s %(type_name)s_from_parts(%(real_type)s x, %(real_type)s y) {
1909      %(type)s z;
1910      z.real = x;
1911      z.imag = y;
1912      return z;
1913    }
1914#endif
1915""")
1916
1917complex_to_py_utility_code = UtilityCode(
1918proto="""
1919#define __pyx_PyComplex_FromComplex(z) \\
1920        PyComplex_FromDoubles((double)__Pyx_CREAL(z), \\
1921                              (double)__Pyx_CIMAG(z))
1922""")
1923
1924complex_from_py_utility_code = UtilityCode(
1925proto="""
1926static %(type)s __Pyx_PyComplex_As_%(type_name)s(PyObject*);
1927""",
1928impl="""
1929static %(type)s __Pyx_PyComplex_As_%(type_name)s(PyObject* o) {
1930    Py_complex cval;
1931#if CYTHON_COMPILING_IN_CPYTHON
1932    if (PyComplex_CheckExact(o))
1933        cval = ((PyComplexObject *)o)->cval;
1934    else
1935#endif
1936        cval = PyComplex_AsCComplex(o);
1937    return %(type_name)s_from_parts(
1938               (%(real_type)s)cval.real,
1939               (%(real_type)s)cval.imag);
1940}
1941""")
1942
1943complex_arithmetic_utility_code = UtilityCode(
1944proto="""
1945#if CYTHON_CCOMPLEX
1946    #define __Pyx_c_eq%(m)s(a, b)   ((a)==(b))
1947    #define __Pyx_c_sum%(m)s(a, b)  ((a)+(b))
1948    #define __Pyx_c_diff%(m)s(a, b) ((a)-(b))
1949    #define __Pyx_c_prod%(m)s(a, b) ((a)*(b))
1950    #define __Pyx_c_quot%(m)s(a, b) ((a)/(b))
1951    #define __Pyx_c_neg%(m)s(a)     (-(a))
1952  #ifdef __cplusplus
1953    #define __Pyx_c_is_zero%(m)s(z) ((z)==(%(real_type)s)0)
1954    #define __Pyx_c_conj%(m)s(z)    (::std::conj(z))
1955    #if %(is_float)s
1956        #define __Pyx_c_abs%(m)s(z)     (::std::abs(z))
1957        #define __Pyx_c_pow%(m)s(a, b)  (::std::pow(a, b))
1958    #endif
1959  #else
1960    #define __Pyx_c_is_zero%(m)s(z) ((z)==0)
1961    #define __Pyx_c_conj%(m)s(z)    (conj%(m)s(z))
1962    #if %(is_float)s
1963        #define __Pyx_c_abs%(m)s(z)     (cabs%(m)s(z))
1964        #define __Pyx_c_pow%(m)s(a, b)  (cpow%(m)s(a, b))
1965    #endif
1966 #endif
1967#else
1968    static CYTHON_INLINE int __Pyx_c_eq%(m)s(%(type)s, %(type)s);
1969    static CYTHON_INLINE %(type)s __Pyx_c_sum%(m)s(%(type)s, %(type)s);
1970    static CYTHON_INLINE %(type)s __Pyx_c_diff%(m)s(%(type)s, %(type)s);
1971    static CYTHON_INLINE %(type)s __Pyx_c_prod%(m)s(%(type)s, %(type)s);
1972    static CYTHON_INLINE %(type)s __Pyx_c_quot%(m)s(%(type)s, %(type)s);
1973    static CYTHON_INLINE %(type)s __Pyx_c_neg%(m)s(%(type)s);
1974    static CYTHON_INLINE int __Pyx_c_is_zero%(m)s(%(type)s);
1975    static CYTHON_INLINE %(type)s __Pyx_c_conj%(m)s(%(type)s);
1976    #if %(is_float)s
1977        static CYTHON_INLINE %(real_type)s __Pyx_c_abs%(m)s(%(type)s);
1978        static CYTHON_INLINE %(type)s __Pyx_c_pow%(m)s(%(type)s, %(type)s);
1979    #endif
1980#endif
1981""",
1982impl="""
1983#if CYTHON_CCOMPLEX
1984#else
1985    static CYTHON_INLINE int __Pyx_c_eq%(m)s(%(type)s a, %(type)s b) {
1986       return (a.real == b.real) && (a.imag == b.imag);
1987    }
1988    static CYTHON_INLINE %(type)s __Pyx_c_sum%(m)s(%(type)s a, %(type)s b) {
1989        %(type)s z;
1990        z.real = a.real + b.real;
1991        z.imag = a.imag + b.imag;
1992        return z;
1993    }
1994    static CYTHON_INLINE %(type)s __Pyx_c_diff%(m)s(%(type)s a, %(type)s b) {
1995        %(type)s z;
1996        z.real = a.real - b.real;
1997        z.imag = a.imag - b.imag;
1998        return z;
1999    }
2000    static CYTHON_INLINE %(type)s __Pyx_c_prod%(m)s(%(type)s a, %(type)s b) {
2001        %(type)s z;
2002        z.real = a.real * b.real - a.imag * b.imag;
2003        z.imag = a.real * b.imag + a.imag * b.real;
2004        return z;
2005    }
2006    static CYTHON_INLINE %(type)s __Pyx_c_quot%(m)s(%(type)s a, %(type)s b) {
2007        %(type)s z;
2008        %(real_type)s denom = b.real * b.real + b.imag * b.imag;
2009        z.real = (a.real * b.real + a.imag * b.imag) / denom;
2010        z.imag = (a.imag * b.real - a.real * b.imag) / denom;
2011        return z;
2012    }
2013    static CYTHON_INLINE %(type)s __Pyx_c_neg%(m)s(%(type)s a) {
2014        %(type)s z;
2015        z.real = -a.real;
2016        z.imag = -a.imag;
2017        return z;
2018    }
2019    static CYTHON_INLINE int __Pyx_c_is_zero%(m)s(%(type)s a) {
2020       return (a.real == 0) && (a.imag == 0);
2021    }
2022    static CYTHON_INLINE %(type)s __Pyx_c_conj%(m)s(%(type)s a) {
2023        %(type)s z;
2024        z.real =  a.real;
2025        z.imag = -a.imag;
2026        return z;
2027    }
2028    #if %(is_float)s
2029        static CYTHON_INLINE %(real_type)s __Pyx_c_abs%(m)s(%(type)s z) {
2030          #if !defined(HAVE_HYPOT) || defined(_MSC_VER)
2031            return sqrt%(m)s(z.real*z.real + z.imag*z.imag);
2032          #else
2033            return hypot%(m)s(z.real, z.imag);
2034          #endif
2035        }
2036        static CYTHON_INLINE %(type)s __Pyx_c_pow%(m)s(%(type)s a, %(type)s b) {
2037            %(type)s z;
2038            %(real_type)s r, lnr, theta, z_r, z_theta;
2039            if (b.imag == 0 && b.real == (int)b.real) {
2040                if (b.real < 0) {
2041                    %(real_type)s denom = a.real * a.real + a.imag * a.imag;
2042                    a.real = a.real / denom;
2043                    a.imag = -a.imag / denom;
2044                    b.real = -b.real;
2045                }
2046                switch ((int)b.real) {
2047                    case 0:
2048                        z.real = 1;
2049                        z.imag = 0;
2050                        return z;
2051                    case 1:
2052                        return a;
2053                    case 2:
2054                        z = __Pyx_c_prod%(m)s(a, a);
2055                        return __Pyx_c_prod%(m)s(a, a);
2056                    case 3:
2057                        z = __Pyx_c_prod%(m)s(a, a);
2058                        return __Pyx_c_prod%(m)s(z, a);
2059                    case 4:
2060                        z = __Pyx_c_prod%(m)s(a, a);
2061                        return __Pyx_c_prod%(m)s(z, z);
2062                }
2063            }
2064            if (a.imag == 0) {
2065                if (a.real == 0) {
2066                    return a;
2067                }
2068                r = a.real;
2069                theta = 0;
2070            } else {
2071                r = __Pyx_c_abs%(m)s(a);
2072                theta = atan2%(m)s(a.imag, a.real);
2073            }
2074            lnr = log%(m)s(r);
2075            z_r = exp%(m)s(lnr * b.real - theta * b.imag);
2076            z_theta = theta * b.real + lnr * b.imag;
2077            z.real = z_r * cos%(m)s(z_theta);
2078            z.imag = z_r * sin%(m)s(z_theta);
2079            return z;
2080        }
2081    #endif
2082#endif
2083""")
2084
2085class CPointerBaseType(CType):
2086    # common base type for pointer/array types
2087    #
2088    #  base_type     CType              Reference type
2089
2090    subtypes = ['base_type']
2091
2092    def __init__(self, base_type):
2093        self.base_type = base_type
2094        for char_type in (c_char_type, c_uchar_type, c_schar_type):
2095            if base_type.same_as(char_type):
2096                self.is_string = 1
2097                break
2098        else:
2099            if base_type.same_as(c_py_unicode_type):
2100                self.is_pyunicode_ptr = 1
2101
2102        if self.is_string and not base_type.is_error:
2103            if base_type.signed:
2104                self.to_py_function = "__Pyx_PyObject_FromString"
2105                if self.is_ptr:
2106                    if base_type.signed == 2:
2107                        self.from_py_function = "__Pyx_PyObject_AsSString"
2108                    else:
2109                        self.from_py_function = "__Pyx_PyObject_AsString"
2110            else:
2111                self.to_py_function = "__Pyx_PyObject_FromUString"
2112                if self.is_ptr:
2113                    self.from_py_function = "__Pyx_PyObject_AsUString"
2114            self.exception_value = "NULL"
2115        elif self.is_pyunicode_ptr and not base_type.is_error:
2116            self.to_py_function = "__Pyx_PyUnicode_FromUnicode"
2117            if self.is_ptr:
2118                self.from_py_function = "__Pyx_PyUnicode_AsUnicode"
2119            self.exception_value = "NULL"
2120
2121    def py_type_name(self):
2122        if self.is_string:
2123            return "bytes"
2124        elif self.is_pyunicode_ptr:
2125            return "unicode"
2126        else:
2127            return super(CPointerBaseType, self).py_type_name()
2128
2129    def literal_code(self, value):
2130        if self.is_string:
2131            assert isinstance(value, str)
2132            return '"%s"' % StringEncoding.escape_byte_string(value)
2133
2134
2135class CArrayType(CPointerBaseType):
2136    #  base_type     CType              Element type
2137    #  size          integer or None    Number of elements
2138
2139    is_array = 1
2140
2141    def __init__(self, base_type, size):
2142        super(CArrayType, self).__init__(base_type)
2143        self.size = size
2144
2145    def __eq__(self, other):
2146        if isinstance(other, CType) and other.is_array and self.size == other.size:
2147            return self.base_type.same_as(other.base_type)
2148        return False
2149
2150    def __hash__(self):
2151        return hash(self.base_type) + 28 # arbitrarily chosen offset
2152
2153    def __repr__(self):
2154        return "<CArrayType %s %s>" % (self.size, repr(self.base_type))
2155
2156    def same_as_resolved_type(self, other_type):
2157        return ((other_type.is_array and
2158            self.base_type.same_as(other_type.base_type))
2159                or other_type is error_type)
2160
2161    def assignable_from_resolved_type(self, src_type):
2162        # Can't assign to a variable of an array type
2163        return 0
2164
2165    def element_ptr_type(self):
2166        return c_ptr_type(self.base_type)
2167
2168    def declaration_code(self, entity_code,
2169            for_display = 0, dll_linkage = None, pyrex = 0):
2170        if self.size is not None:
2171            dimension_code = self.size
2172        else:
2173            dimension_code = ""
2174        if entity_code.startswith("*"):
2175            entity_code = "(%s)" % entity_code
2176        return self.base_type.declaration_code(
2177            "%s[%s]" % (entity_code, dimension_code),
2178            for_display, dll_linkage, pyrex)
2179
2180    def as_argument_type(self):
2181        return c_ptr_type(self.base_type)
2182
2183    def is_complete(self):
2184        return self.size is not None
2185
2186    def specialize(self, values):
2187        base_type = self.base_type.specialize(values)
2188        if base_type == self.base_type:
2189            return self
2190        else:
2191            return CArrayType(base_type)
2192
2193    def deduce_template_params(self, actual):
2194        if isinstance(actual, CArrayType):
2195            return self.base_type.deduce_template_params(actual.base_type)
2196        else:
2197            return None
2198
2199
2200class CPtrType(CPointerBaseType):
2201    #  base_type     CType              Reference type
2202
2203    is_ptr = 1
2204    default_value = "0"
2205
2206    def __hash__(self):
2207        return hash(self.base_type) + 27 # arbitrarily chosen offset
2208
2209    def __eq__(self, other):
2210        if isinstance(other, CType) and other.is_ptr:
2211            return self.base_type.same_as(other.base_type)
2212        return False
2213
2214    def __ne__(self, other):
2215        return not (self == other)
2216
2217    def __repr__(self):
2218        return "<CPtrType %s>" % repr(self.base_type)
2219
2220    def same_as_resolved_type(self, other_type):
2221        return ((other_type.is_ptr and
2222            self.base_type.same_as(other_type.base_type))
2223                or other_type is error_type)
2224
2225    def declaration_code(self, entity_code,
2226            for_display = 0, dll_linkage = None, pyrex = 0):
2227        #print "CPtrType.declaration_code: pointer to", self.base_type ###
2228        return self.base_type.declaration_code(
2229            "*%s" % entity_code,
2230            for_display, dll_linkage, pyrex)
2231
2232    def assignable_from_resolved_type(self, other_type):
2233        if other_type is error_type:
2234            return 1
2235        if other_type.is_null_ptr:
2236            return 1
2237        if self.base_type.is_const:
2238            self = CPtrType(self.base_type.const_base_type)
2239        if self.base_type.is_cfunction:
2240            if other_type.is_ptr:
2241                other_type = other_type.base_type.resolve()
2242            if other_type.is_cfunction:
2243                return self.base_type.pointer_assignable_from_resolved_type(other_type)
2244            else:
2245                return 0
2246        if (self.base_type.is_cpp_class and other_type.is_ptr
2247                and other_type.base_type.is_cpp_class and other_type.base_type.is_subclass(self.base_type)):
2248            return 1
2249        if other_type.is_array or other_type.is_ptr:
2250            return self.base_type.is_void or self.base_type.same_as(other_type.base_type)
2251        return 0
2252
2253    def specialize(self, values):
2254        base_type = self.base_type.specialize(values)
2255        if base_type == self.base_type:
2256            return self
2257        else:
2258            return CPtrType(base_type)
2259
2260    def deduce_template_params(self, actual):
2261        if isinstance(actual, CPtrType):
2262            return self.base_type.deduce_template_params(actual.base_type)
2263        else:
2264            return None
2265
2266    def invalid_value(self):
2267        return "1"
2268
2269    def find_cpp_operation_type(self, operator, operand_type=None):
2270        if self.base_type.is_cpp_class:
2271            return self.base_type.find_cpp_operation_type(operator, operand_type)
2272        return None
2273
2274class CNullPtrType(CPtrType):
2275
2276    is_null_ptr = 1
2277
2278
2279class CReferenceType(BaseType):
2280
2281    is_reference = 1
2282
2283    def __init__(self, base_type):
2284        self.ref_base_type = base_type
2285
2286    def __repr__(self):
2287        return "<CReferenceType %s>" % repr(self.ref_base_type)
2288
2289    def __str__(self):
2290        return "%s &" % self.ref_base_type
2291
2292    def declaration_code(self, entity_code,
2293            for_display = 0, dll_linkage = None, pyrex = 0):
2294        #print "CReferenceType.declaration_code: pointer to", self.base_type ###
2295        return self.ref_base_type.declaration_code(
2296            "&%s" % entity_code,
2297            for_display, dll_linkage, pyrex)
2298
2299    def specialize(self, values):
2300        base_type = self.ref_base_type.specialize(values)
2301        if base_type == self.ref_base_type:
2302            return self
2303        else:
2304            return CReferenceType(base_type)
2305
2306    def deduce_template_params(self, actual):
2307        return self.ref_base_type.deduce_template_params(actual)
2308
2309    def __getattr__(self, name):
2310        return getattr(self.ref_base_type, name)
2311
2312
2313class CFuncType(CType):
2314    #  return_type      CType
2315    #  args             [CFuncTypeArg]
2316    #  has_varargs      boolean
2317    #  exception_value  string
2318    #  exception_check  boolean    True if PyErr_Occurred check needed
2319    #  calling_convention  string  Function calling convention
2320    #  nogil            boolean    Can be called without gil
2321    #  with_gil         boolean    Acquire gil around function body
2322    #  templates        [string] or None
2323    #  cached_specialized_types [CFuncType]   cached specialized versions of the CFuncType if defined in a pxd
2324    #  from_fused       boolean    Indicates whether this is a specialized
2325    #                              C function
2326    #  is_strict_signature boolean  function refuses to accept coerced arguments
2327    #                               (used for optimisation overrides)
2328    #  is_const_method  boolean
2329
2330    is_cfunction = 1
2331    original_sig = None
2332    cached_specialized_types = None
2333    from_fused = False
2334    is_const_method = False
2335
2336    subtypes = ['return_type', 'args']
2337
2338    def __init__(self, return_type, args, has_varargs = 0,
2339            exception_value = None, exception_check = 0, calling_convention = "",
2340            nogil = 0, with_gil = 0, is_overridable = 0, optional_arg_count = 0,
2341            is_const_method = False, templates = None, is_strict_signature = False):
2342        self.return_type = return_type
2343        self.args = args
2344        self.has_varargs = has_varargs
2345        self.optional_arg_count = optional_arg_count
2346        self.exception_value = exception_value
2347        self.exception_check = exception_check
2348        self.calling_convention = calling_convention
2349        self.nogil = nogil
2350        self.with_gil = with_gil
2351        self.is_overridable = is_overridable
2352        self.is_const_method = is_const_method
2353        self.templates = templates
2354        self.is_strict_signature = is_strict_signature
2355
2356    def __repr__(self):
2357        arg_reprs = map(repr, self.args)
2358        if self.has_varargs:
2359            arg_reprs.append("...")
2360        if self.exception_value:
2361            except_clause = " %r" % self.exception_value
2362        else:
2363            except_clause = ""
2364        if self.exception_check:
2365            except_clause += "?"
2366        return "<CFuncType %s %s[%s]%s>" % (
2367            repr(self.return_type),
2368            self.calling_convention_prefix(),
2369            ",".join(arg_reprs),
2370            except_clause)
2371
2372    def calling_convention_prefix(self):
2373        cc = self.calling_convention
2374        if cc:
2375            return cc + " "
2376        else:
2377            return ""
2378
2379    def as_argument_type(self):
2380        return c_ptr_type(self)
2381
2382    def same_c_signature_as(self, other_type, as_cmethod = 0):
2383        return self.same_c_signature_as_resolved_type(
2384            other_type.resolve(), as_cmethod)
2385
2386    def same_c_signature_as_resolved_type(self, other_type, as_cmethod = 0):
2387        #print "CFuncType.same_c_signature_as_resolved_type:", \
2388        #    self, other_type, "as_cmethod =", as_cmethod ###
2389        if other_type is error_type:
2390            return 1
2391        if not other_type.is_cfunction:
2392            return 0
2393        if self.is_overridable != other_type.is_overridable:
2394            return 0
2395        nargs = len(self.args)
2396        if nargs != len(other_type.args):
2397            return 0
2398        # When comparing C method signatures, the first argument
2399        # is exempt from compatibility checking (the proper check
2400        # is performed elsewhere).
2401        for i in range(as_cmethod, nargs):
2402            if not self.args[i].type.same_as(
2403                other_type.args[i].type):
2404                    return 0
2405        if self.has_varargs != other_type.has_varargs:
2406            return 0
2407        if self.optional_arg_count != other_type.optional_arg_count:
2408            return 0
2409        if not self.return_type.same_as(other_type.return_type):
2410            return 0
2411        if not self.same_calling_convention_as(other_type):
2412            return 0
2413        return 1
2414
2415    def compatible_signature_with(self, other_type, as_cmethod = 0):
2416        return self.compatible_signature_with_resolved_type(other_type.resolve(), as_cmethod)
2417
2418    def compatible_signature_with_resolved_type(self, other_type, as_cmethod):
2419        #print "CFuncType.same_c_signature_as_resolved_type:", \
2420        #    self, other_type, "as_cmethod =", as_cmethod ###
2421        if other_type is error_type:
2422            return 1
2423        if not other_type.is_cfunction:
2424            return 0
2425        if not self.is_overridable and other_type.is_overridable:
2426            return 0
2427        nargs = len(self.args)
2428        if nargs - self.optional_arg_count != len(other_type.args) - other_type.optional_arg_count:
2429            return 0
2430        if self.optional_arg_count < other_type.optional_arg_count:
2431            return 0
2432        # When comparing C method signatures, the first argument
2433        # is exempt from compatibility checking (the proper check
2434        # is performed elsewhere).
2435        for i in range(as_cmethod, len(other_type.args)):
2436            if not self.args[i].type.same_as(
2437                other_type.args[i].type):
2438                    return 0
2439        if self.has_varargs != other_type.has_varargs:
2440            return 0
2441        if not self.return_type.subtype_of_resolved_type(other_type.return_type):
2442            return 0
2443        if not self.same_calling_convention_as(other_type):
2444            return 0
2445        if self.nogil != other_type.nogil:
2446            return 0
2447        self.original_sig = other_type.original_sig or other_type
2448        return 1
2449
2450
2451    def narrower_c_signature_than(self, other_type, as_cmethod = 0):
2452        return self.narrower_c_signature_than_resolved_type(other_type.resolve(), as_cmethod)
2453
2454    def narrower_c_signature_than_resolved_type(self, other_type, as_cmethod):
2455        if other_type is error_type:
2456            return 1
2457        if not other_type.is_cfunction:
2458            return 0
2459        nargs = len(self.args)
2460        if nargs != len(other_type.args):
2461            return 0
2462        for i in range(as_cmethod, nargs):
2463            if not self.args[i].type.subtype_of_resolved_type(other_type.args[i].type):
2464                return 0
2465            else:
2466                self.args[i].needs_type_test = other_type.args[i].needs_type_test \
2467                        or not self.args[i].type.same_as(other_type.args[i].type)
2468        if self.has_varargs != other_type.has_varargs:
2469            return 0
2470        if self.optional_arg_count != other_type.optional_arg_count:
2471            return 0
2472        if not self.return_type.subtype_of_resolved_type(other_type.return_type):
2473            return 0
2474        return 1
2475
2476    def same_calling_convention_as(self, other):
2477        ## XXX Under discussion ...
2478        ## callspec_words = ("__stdcall", "__cdecl", "__fastcall")
2479        ## cs1 = self.calling_convention
2480        ## cs2 = other.calling_convention
2481        ## if (cs1 in callspec_words or
2482        ##     cs2 in callspec_words):
2483        ##     return cs1 == cs2
2484        ## else:
2485        ##     return True
2486        sc1 = self.calling_convention == '__stdcall'
2487        sc2 = other.calling_convention == '__stdcall'
2488        return sc1 == sc2
2489
2490    def same_exception_signature_as(self, other_type):
2491        return self.same_exception_signature_as_resolved_type(
2492            other_type.resolve())
2493
2494    def same_exception_signature_as_resolved_type(self, other_type):
2495        return self.exception_value == other_type.exception_value \
2496            and self.exception_check == other_type.exception_check
2497
2498    def same_as_resolved_type(self, other_type, as_cmethod = 0):
2499        return self.same_c_signature_as_resolved_type(other_type, as_cmethod) \
2500            and self.same_exception_signature_as_resolved_type(other_type) \
2501            and self.nogil == other_type.nogil
2502
2503    def pointer_assignable_from_resolved_type(self, other_type):
2504        return self.same_c_signature_as_resolved_type(other_type) \
2505            and self.same_exception_signature_as_resolved_type(other_type) \
2506            and not (self.nogil and not other_type.nogil)
2507
2508    def declaration_code(self, entity_code,
2509                         for_display = 0, dll_linkage = None, pyrex = 0,
2510                         with_calling_convention = 1):
2511        arg_decl_list = []
2512        for arg in self.args[:len(self.args)-self.optional_arg_count]:
2513            arg_decl_list.append(
2514                arg.type.declaration_code("", for_display, pyrex = pyrex))
2515        if self.is_overridable:
2516            arg_decl_list.append("int %s" % Naming.skip_dispatch_cname)
2517        if self.optional_arg_count:
2518            arg_decl_list.append(self.op_arg_struct.declaration_code(Naming.optional_args_cname))
2519        if self.has_varargs:
2520            arg_decl_list.append("...")
2521        arg_decl_code = ", ".join(arg_decl_list)
2522        if not arg_decl_code and not pyrex:
2523            arg_decl_code = "void"
2524        trailer = ""
2525        if (pyrex or for_display) and not self.return_type.is_pyobject:
2526            if self.exception_value and self.exception_check:
2527                trailer = " except? %s" % self.exception_value
2528            elif self.exception_value:
2529                trailer = " except %s" % self.exception_value
2530            elif self.exception_check == '+':
2531                trailer = " except +"
2532            else:
2533                " except *" # ignored
2534            if self.nogil:
2535                trailer += " nogil"
2536        if not with_calling_convention:
2537            cc = ''
2538        else:
2539            cc = self.calling_convention_prefix()
2540            if (not entity_code and cc) or entity_code.startswith("*"):
2541                entity_code = "(%s%s)" % (cc, entity_code)
2542                cc = ""
2543        if self.is_const_method:
2544            trailer += " const"
2545        return self.return_type.declaration_code(
2546            "%s%s(%s)%s" % (cc, entity_code, arg_decl_code, trailer),
2547            for_display, dll_linkage, pyrex)
2548
2549    def function_header_code(self, func_name, arg_code):
2550        if self.is_const_method:
2551            trailer = " const"
2552        else:
2553            trailer = ""
2554        return "%s%s(%s)%s" % (self.calling_convention_prefix(),
2555            func_name, arg_code, trailer)
2556
2557    def signature_string(self):
2558        s = self.declaration_code("")
2559        return s
2560
2561    def signature_cast_string(self):
2562        s = self.declaration_code("(*)", with_calling_convention=False)
2563        return '(%s)' % s
2564
2565    def specialize(self, values):
2566        result = CFuncType(self.return_type.specialize(values),
2567                           [arg.specialize(values) for arg in self.args],
2568                           has_varargs = self.has_varargs,
2569                           exception_value = self.exception_value,
2570                           exception_check = self.exception_check,
2571                           calling_convention = self.calling_convention,
2572                           nogil = self.nogil,
2573                           with_gil = self.with_gil,
2574                           is_overridable = self.is_overridable,
2575                           optional_arg_count = self.optional_arg_count,
2576                           is_const_method = self.is_const_method,
2577                           templates = self.templates)
2578
2579        result.from_fused = self.is_fused
2580        return result
2581
2582    def opt_arg_cname(self, arg_name):
2583        return self.op_arg_struct.base_type.scope.lookup(arg_name).cname
2584
2585    # Methods that deal with Fused Types
2586    # All but map_with_specific_entries should be called only on functions
2587    # with fused types (and not on their corresponding specific versions).
2588
2589    def get_all_specialized_permutations(self, fused_types=None):
2590        """
2591        Permute all the types. For every specific instance of a fused type, we
2592        want all other specific instances of all other fused types.
2593
2594        It returns an iterable of two-tuples of the cname that should prefix
2595        the cname of the function, and a dict mapping any fused types to their
2596        respective specific types.
2597        """
2598        assert self.is_fused
2599
2600        if fused_types is None:
2601            fused_types = self.get_fused_types()
2602
2603        return get_all_specialized_permutations(fused_types)
2604
2605    def get_all_specialized_function_types(self):
2606        """
2607        Get all the specific function types of this one.
2608        """
2609        assert self.is_fused
2610
2611        if self.entry.fused_cfunction:
2612            return [n.type for n in self.entry.fused_cfunction.nodes]
2613        elif self.cached_specialized_types is not None:
2614            return self.cached_specialized_types
2615
2616        cfunc_entries = self.entry.scope.cfunc_entries
2617        cfunc_entries.remove(self.entry)
2618
2619        result = []
2620        permutations = self.get_all_specialized_permutations()
2621
2622        for cname, fused_to_specific in permutations:
2623            new_func_type = self.entry.type.specialize(fused_to_specific)
2624
2625            if self.optional_arg_count:
2626                # Remember, this method is set by CFuncDeclaratorNode
2627                self.declare_opt_arg_struct(new_func_type, cname)
2628
2629            new_entry = copy.deepcopy(self.entry)
2630            new_func_type.specialize_entry(new_entry, cname)
2631
2632            new_entry.type = new_func_type
2633            new_func_type.entry = new_entry
2634            result.append(new_func_type)
2635
2636            cfunc_entries.append(new_entry)
2637
2638        self.cached_specialized_types = result
2639
2640        return result
2641
2642    def get_fused_types(self, result=None, seen=None, subtypes=None):
2643        """Return fused types in the order they appear as parameter types"""
2644        return super(CFuncType, self).get_fused_types(result, seen,
2645                                                      subtypes=['args'])
2646
2647    def specialize_entry(self, entry, cname):
2648        assert not self.is_fused
2649        specialize_entry(entry, cname)
2650
2651
2652def specialize_entry(entry, cname):
2653    """
2654    Specialize an entry of a copied fused function or method
2655    """
2656    entry.is_fused_specialized = True
2657    entry.name = get_fused_cname(cname, entry.name)
2658
2659    if entry.is_cmethod:
2660        entry.cname = entry.name
2661        if entry.is_inherited:
2662            entry.cname = StringEncoding.EncodedString(
2663                    "%s.%s" % (Naming.obj_base_cname, entry.cname))
2664    else:
2665        entry.cname = get_fused_cname(cname, entry.cname)
2666
2667    if entry.func_cname:
2668        entry.func_cname = get_fused_cname(cname, entry.func_cname)
2669
2670def get_fused_cname(fused_cname, orig_cname):
2671    """
2672    Given the fused cname id and an original cname, return a specialized cname
2673    """
2674    assert fused_cname and orig_cname
2675    return StringEncoding.EncodedString('%s%s%s' % (Naming.fused_func_prefix,
2676                                                    fused_cname, orig_cname))
2677
2678def unique(somelist):
2679    seen = set()
2680    result = []
2681    for obj in somelist:
2682        if obj not in seen:
2683            result.append(obj)
2684            seen.add(obj)
2685
2686    return result
2687
2688def get_all_specialized_permutations(fused_types):
2689    return _get_all_specialized_permutations(unique(fused_types))
2690
2691def _get_all_specialized_permutations(fused_types, id="", f2s=()):
2692    fused_type, = fused_types[0].get_fused_types()
2693    result = []
2694
2695    for newid, specific_type in enumerate(fused_type.types):
2696        # f2s = dict(f2s, **{ fused_type: specific_type })
2697        f2s = dict(f2s)
2698        f2s.update({ fused_type: specific_type })
2699
2700        if id:
2701            cname = '%s_%s' % (id, newid)
2702        else:
2703            cname = str(newid)
2704
2705        if len(fused_types) > 1:
2706            result.extend(_get_all_specialized_permutations(
2707                                            fused_types[1:], cname, f2s))
2708        else:
2709            result.append((cname, f2s))
2710
2711    return result
2712
2713def specialization_signature_string(fused_compound_type, fused_to_specific):
2714    """
2715    Return the signature for a specialization of a fused type. e.g.
2716
2717        floating[:] ->
2718            'float' or 'double'
2719
2720        cdef fused ft:
2721            float[:]
2722            double[:]
2723
2724        ft ->
2725            'float[:]' or 'double[:]'
2726
2727        integral func(floating) ->
2728            'int (*func)(float)' or ...
2729    """
2730    fused_types = fused_compound_type.get_fused_types()
2731    if len(fused_types) == 1:
2732        fused_type = fused_types[0]
2733    else:
2734        fused_type = fused_compound_type
2735
2736    return fused_type.specialize(fused_to_specific).typeof_name()
2737
2738def get_specialized_types(type):
2739    """
2740    Return a list of specialized types sorted in reverse order in accordance
2741    with their preference in runtime fused-type dispatch
2742    """
2743    assert type.is_fused
2744
2745    if isinstance(type, FusedType):
2746        result = type.types
2747        for specialized_type in result:
2748            specialized_type.specialization_string = specialized_type.typeof_name()
2749    else:
2750        result = []
2751        for cname, f2s in get_all_specialized_permutations(type.get_fused_types()):
2752            specialized_type = type.specialize(f2s)
2753            specialized_type.specialization_string = (
2754                            specialization_signature_string(type, f2s))
2755            result.append(specialized_type)
2756
2757    return sorted(result)
2758
2759
2760class CFuncTypeArg(BaseType):
2761    #  name       string
2762    #  cname      string
2763    #  type       PyrexType
2764    #  pos        source file position
2765
2766    # FIXME: is this the right setup? should None be allowed here?
2767    not_none = False
2768    or_none = False
2769    accept_none = True
2770    accept_builtin_subtypes = False
2771
2772    subtypes = ['type']
2773
2774    def __init__(self, name, type, pos, cname=None):
2775        self.name = name
2776        if cname is not None:
2777            self.cname = cname
2778        else:
2779            self.cname = Naming.var_prefix + name
2780        self.type = type
2781        self.pos = pos
2782        self.needs_type_test = False # TODO: should these defaults be set in analyse_types()?
2783
2784    def __repr__(self):
2785        return "%s:%s" % (self.name, repr(self.type))
2786
2787    def declaration_code(self, for_display = 0):
2788        return self.type.declaration_code(self.cname, for_display)
2789
2790    def specialize(self, values):
2791        return CFuncTypeArg(self.name, self.type.specialize(values), self.pos, self.cname)
2792
2793class ToPyStructUtilityCode(object):
2794
2795    requires = None
2796
2797    def __init__(self, type, forward_decl):
2798        self.type = type
2799        self.header = "static PyObject* %s(%s)" % (type.to_py_function,
2800                                                   type.declaration_code('s'))
2801        self.forward_decl = forward_decl
2802
2803    def __eq__(self, other):
2804        return isinstance(other, ToPyStructUtilityCode) and self.header == other.header
2805
2806    def __hash__(self):
2807        return hash(self.header)
2808
2809    def get_tree(self):
2810        pass
2811
2812    def put_code(self, output):
2813        code = output['utility_code_def']
2814        proto = output['utility_code_proto']
2815
2816        code.putln("%s {" % self.header)
2817        code.putln("PyObject* res;")
2818        code.putln("PyObject* member;")
2819        code.putln("res = PyDict_New(); if (res == NULL) return NULL;")
2820        for member in self.type.scope.var_entries:
2821            nameconst_cname = code.get_py_string_const(member.name, identifier=True)
2822            code.putln("member = %s(s.%s); if (member == NULL) goto bad;" % (
2823                member.type.to_py_function, member.cname))
2824            code.putln("if (PyDict_SetItem(res, %s, member) < 0) goto bad;" % nameconst_cname)
2825            code.putln("Py_DECREF(member);")
2826        code.putln("return res;")
2827        code.putln("bad:")
2828        code.putln("Py_XDECREF(member);")
2829        code.putln("Py_DECREF(res);")
2830        code.putln("return NULL;")
2831        code.putln("}")
2832
2833        # This is a bit of a hack, we need a forward declaration
2834        # due to the way things are ordered in the module...
2835        if self.forward_decl:
2836            proto.putln(self.type.declaration_code('') + ';')
2837        proto.putln(self.header + ";")
2838
2839    def inject_tree_and_scope_into(self, module_node):
2840        pass
2841
2842
2843class CStructOrUnionType(CType):
2844    #  name          string
2845    #  cname         string
2846    #  kind          string              "struct" or "union"
2847    #  scope         StructOrUnionScope, or None if incomplete
2848    #  typedef_flag  boolean
2849    #  packed        boolean
2850
2851    # entry          Entry
2852
2853    is_struct_or_union = 1
2854    has_attributes = 1
2855    exception_check = True
2856
2857    def __init__(self, name, kind, scope, typedef_flag, cname, packed=False):
2858        self.name = name
2859        self.cname = cname
2860        self.kind = kind
2861        self.scope = scope
2862        self.typedef_flag = typedef_flag
2863        self.is_struct = kind == 'struct'
2864        if self.is_struct:
2865            self.to_py_function = "%s_to_py_%s" % (Naming.convert_func_prefix, self.cname)
2866            self.from_py_function = "%s_from_py_%s" % (Naming.convert_func_prefix, self.cname)
2867        self.exception_check = True
2868        self._convert_to_py_code = None
2869        self._convert_from_py_code = None
2870        self.packed = packed
2871
2872    def create_to_py_utility_code(self, env):
2873        if env.outer_scope is None:
2874            return False
2875
2876        if self._convert_to_py_code is False:
2877            return None  # tri-state-ish
2878
2879        if self._convert_to_py_code is None:
2880            for member in self.scope.var_entries:
2881                if not member.type.create_to_py_utility_code(env):
2882                    self.to_py_function = None
2883                    self._convert_to_py_code = False
2884                    return False
2885            forward_decl = (self.entry.visibility != 'extern')
2886            self._convert_to_py_code = ToPyStructUtilityCode(self, forward_decl)
2887
2888        env.use_utility_code(self._convert_to_py_code)
2889        return True
2890
2891    def create_from_py_utility_code(self, env):
2892        if env.outer_scope is None:
2893            return False
2894
2895        if self._convert_from_py_code is False:
2896            return None  # tri-state-ish
2897
2898        if self._convert_from_py_code is None:
2899            for member in self.scope.var_entries:
2900                if not member.type.create_from_py_utility_code(env):
2901                    self.from_py_function = None
2902                    self._convert_from_py_code = False
2903                    return False
2904
2905            context = dict(
2906                struct_type_decl=self.declaration_code(""),
2907                var_entries=self.scope.var_entries,
2908                funcname=self.from_py_function,
2909            )
2910            self._convert_from_py_code = TempitaUtilityCode.load(
2911                "FromPyStructUtility", "TypeConversion.c", context=context)
2912
2913        env.use_utility_code(self._convert_from_py_code)
2914        return True
2915
2916    def __repr__(self):
2917        return "<CStructOrUnionType %s %s%s>" % (
2918            self.name, self.cname,
2919            ("", " typedef")[self.typedef_flag])
2920
2921    def declaration_code(self, entity_code,
2922                         for_display=0, dll_linkage=None, pyrex=0):
2923        if pyrex or for_display:
2924            base_code = self.name
2925        else:
2926            if self.typedef_flag:
2927                base_code = self.cname
2928            else:
2929                base_code = "%s %s" % (self.kind, self.cname)
2930            base_code = public_decl(base_code, dll_linkage)
2931        return self.base_declaration_code(base_code, entity_code)
2932
2933    def __eq__(self, other):
2934        try:
2935            return (isinstance(other, CStructOrUnionType) and
2936                    self.name == other.name)
2937        except AttributeError:
2938            return False
2939
2940    def __lt__(self, other):
2941        try:
2942            return self.name < other.name
2943        except AttributeError:
2944            # this is arbitrary, but it makes sure we always have
2945            # *some* kind of order
2946            return False
2947
2948    def __hash__(self):
2949        return hash(self.cname) ^ hash(self.kind)
2950
2951    def is_complete(self):
2952        return self.scope is not None
2953
2954    def attributes_known(self):
2955        return self.is_complete()
2956
2957    def can_be_complex(self):
2958        # Does the struct consist of exactly two identical floats?
2959        fields = self.scope.var_entries
2960        if len(fields) != 2: return False
2961        a, b = fields
2962        return (a.type.is_float and b.type.is_float and
2963                a.type.declaration_code("") ==
2964                b.type.declaration_code(""))
2965
2966    def struct_nesting_depth(self):
2967        child_depths = [x.type.struct_nesting_depth()
2968                        for x in self.scope.var_entries]
2969        return max(child_depths) + 1
2970
2971    def cast_code(self, expr_code):
2972        if self.is_struct:
2973            return expr_code
2974        return super(CStructOrUnionType, self).cast_code(expr_code)
2975
2976
2977builtin_cpp_conversions = ("std::string",
2978                           "std::pair",
2979                           "std::vector", "std::list",
2980                           "std::set", "std::unordered_set",
2981                           "std::map", "std::unordered_map")
2982
2983class CppClassType(CType):
2984    #  name          string
2985    #  cname         string
2986    #  scope         CppClassScope
2987    #  templates     [string] or None
2988
2989    is_cpp_class = 1
2990    has_attributes = 1
2991    exception_check = True
2992    namespace = None
2993
2994    # For struct-like declaration.
2995    kind = "struct"
2996    packed = False
2997    typedef_flag = False
2998
2999    subtypes = ['templates']
3000
3001    def __init__(self, name, scope, cname, base_classes, templates = None, template_type = None):
3002        self.name = name
3003        self.cname = cname
3004        self.scope = scope
3005        self.base_classes = base_classes
3006        self.operators = []
3007        self.templates = templates
3008        self.template_type = template_type
3009        self.specializations = {}
3010        self.is_cpp_string = cname == 'std::string'
3011
3012    def use_conversion_utility(self, from_or_to):
3013        pass
3014
3015    def maybe_unordered(self):
3016        if 'unordered' in self.cname:
3017            return 'unordered_'
3018        else:
3019            return ''
3020
3021    def create_from_py_utility_code(self, env):
3022        if self.from_py_function is not None:
3023            return True
3024        if self.cname in builtin_cpp_conversions:
3025            X = "XYZABC"
3026            tags = []
3027            declarations = ["cdef extern from *:"]
3028            for ix, T in enumerate(self.templates or []):
3029                if T.is_pyobject or not T.create_from_py_utility_code(env):
3030                    return False
3031                tags.append(T.specialization_name())
3032                if T.exception_value is not None:
3033                    except_clause = T.exception_value
3034                    if T.exception_check:
3035                        except_clause = "? %s" % except_clause
3036                    declarations.append(
3037                        "    ctypedef %s %s '%s'" % (
3038                             T.declaration_code("", for_display=True), X[ix], T.declaration_code("")))
3039                else:
3040                    except_clause = "*"
3041                    declarations.append(
3042                        "    ctypedef struct %s '%s':\n        pass" % (
3043                             X[ix], T.declaration_code("")))
3044                declarations.append(
3045                    "    cdef %s %s_from_py '%s' (object) except %s" % (
3046                         X[ix], X[ix], T.from_py_function, except_clause))
3047            cls = self.cname[5:]
3048            cname = '__pyx_convert_%s_from_py_%s' % (cls, '____'.join(tags))
3049            context = {
3050                'template_type_declarations': '\n'.join(declarations),
3051                'cname': cname,
3052                'maybe_unordered': self.maybe_unordered(),
3053            }
3054            from UtilityCode import CythonUtilityCode
3055            env.use_utility_code(CythonUtilityCode.load(cls.replace('unordered_', '') + ".from_py", "CppConvert.pyx", context=context))
3056            self.from_py_function = cname
3057            return True
3058
3059    def create_to_py_utility_code(self, env):
3060        if self.to_py_function is not None:
3061            return True
3062        if self.cname in builtin_cpp_conversions:
3063            X = "XYZABC"
3064            tags = []
3065            declarations = ["cdef extern from *:"]
3066            for ix, T in enumerate(self.templates or []):
3067                if not T.create_to_py_utility_code(env):
3068                    return False
3069                tags.append(T.specialization_name())
3070                declarations.append(
3071                    "    ctypedef struct %s '%s':\n        pass" % (
3072                         X[ix], T.declaration_code("")))
3073                declarations.append(
3074                    "    cdef object %s_to_py '%s' (%s)" % (
3075                         X[ix], T.to_py_function, X[ix]))
3076            cls = self.cname[5:]
3077            cname = "__pyx_convert_%s_to_py_%s" % (cls, "____".join(tags))
3078            context = {
3079                'template_type_declarations': '\n'.join(declarations),
3080                'cname': cname,
3081                'maybe_unordered': self.maybe_unordered(),
3082            }
3083            from UtilityCode import CythonUtilityCode
3084            env.use_utility_code(CythonUtilityCode.load(cls.replace('unordered_', '') + ".to_py", "CppConvert.pyx", context=context))
3085            self.to_py_function = cname
3086            return True
3087
3088    def specialize_here(self, pos, template_values = None):
3089        if self.templates is None:
3090            error(pos, "'%s' type is not a template" % self)
3091            return error_type
3092        if len(self.templates) != len(template_values):
3093            error(pos, "%s templated type receives %d arguments, got %d" %
3094                  (self.name, len(self.templates), len(template_values)))
3095            return error_type
3096        has_object_template_param = False
3097        for value in template_values:
3098            if value.is_pyobject:
3099                has_object_template_param = True
3100                error(pos,
3101                      "Python object type '%s' cannot be used as a template argument" % value)
3102        if has_object_template_param:
3103            return error_type
3104        return self.specialize(dict(zip(self.templates, template_values)))
3105
3106    def specialize(self, values):
3107        if not self.templates and not self.namespace:
3108            return self
3109        if self.templates is None:
3110            self.templates = []
3111        key = tuple(values.items())
3112        if key in self.specializations:
3113            return self.specializations[key]
3114        template_values = [t.specialize(values) for t in self.templates]
3115        specialized = self.specializations[key] = \
3116            CppClassType(self.name, None, self.cname, [], template_values, template_type=self)
3117        # Need to do these *after* self.specializations[key] is set
3118        # to avoid infinite recursion on circular references.
3119        specialized.base_classes = [b.specialize(values) for b in self.base_classes]
3120        specialized.scope = self.scope.specialize(values)
3121        if self.namespace is not None:
3122            specialized.namespace = self.namespace.specialize(values)
3123        return specialized
3124
3125    def deduce_template_params(self, actual):
3126        if self == actual:
3127            return {}
3128        # TODO(robertwb): Actual type equality.
3129        elif self.declaration_code("") == actual.template_type.declaration_code(""):
3130            return reduce(
3131                merge_template_deductions,
3132                [formal_param.deduce_template_params(actual_param) for (formal_param, actual_param) in zip(self.templates, actual.templates)],
3133                {})
3134        else:
3135            return None
3136
3137    def declaration_code(self, entity_code,
3138            for_display = 0, dll_linkage = None, pyrex = 0):
3139        if self.templates:
3140            template_strings = [param.declaration_code('', for_display, None, pyrex)
3141                                for param in self.templates]
3142            if for_display:
3143                brackets = "[%s]"
3144            else:
3145                brackets = "<%s>"
3146            templates = brackets % ",".join(template_strings)
3147            if templates[-2:] == ">>":
3148                templates = templates[:-2] + "> >"
3149        else:
3150            templates = ""
3151        if pyrex or for_display:
3152            base_code = "%s%s" % (self.name, templates)
3153        else:
3154            base_code = "%s%s" % (self.cname, templates)
3155            if self.namespace is not None:
3156                base_code = "%s::%s" % (self.namespace.declaration_code(''), base_code)
3157            base_code = public_decl(base_code, dll_linkage)
3158        return self.base_declaration_code(base_code, entity_code)
3159
3160    def is_subclass(self, other_type):
3161        if self.same_as_resolved_type(other_type):
3162            return 1
3163        for base_class in self.base_classes:
3164            if base_class.is_subclass(other_type):
3165                return 1
3166        return 0
3167
3168    def same_as_resolved_type(self, other_type):
3169        if other_type.is_cpp_class:
3170            if self == other_type:
3171                return 1
3172            elif (self.cname == other_type.cname and
3173                  self.template_type and other_type.template_type):
3174                if self.templates == other_type.templates:
3175                    return 1
3176                for t1, t2 in zip(self.templates, other_type.templates):
3177                    if not t1.same_as_resolved_type(t2):
3178                        return 0
3179                return 1
3180        return 0
3181
3182    def assignable_from_resolved_type(self, other_type):
3183        # TODO: handle operator=(...) here?
3184        if other_type is error_type:
3185            return True
3186        return other_type.is_cpp_class and other_type.is_subclass(self)
3187
3188    def attributes_known(self):
3189        return self.scope is not None
3190
3191    def find_cpp_operation_type(self, operator, operand_type=None):
3192        operands = [self]
3193        if operand_type is not None:
3194            operands.append(operand_type)
3195        # pos == None => no errors
3196        operator_entry = self.scope.lookup_operator_for_types(None, operator, operands)
3197        if not operator_entry:
3198            return None
3199        func_type = operator_entry.type
3200        if func_type.is_ptr:
3201            func_type = func_type.base_type
3202        return func_type.return_type
3203
3204    def check_nullary_constructor(self, pos, msg="stack allocated"):
3205        constructor = self.scope.lookup(u'<init>')
3206        if constructor is not None and best_match([], constructor.all_alternatives()) is None:
3207            error(pos, "C++ class must have a nullary constructor to be %s" % msg)
3208
3209
3210class TemplatePlaceholderType(CType):
3211
3212    def __init__(self, name):
3213        self.name = name
3214
3215    def declaration_code(self, entity_code,
3216            for_display = 0, dll_linkage = None, pyrex = 0):
3217        if entity_code:
3218            return self.name + " " + entity_code
3219        else:
3220            return self.name
3221
3222    def specialize(self, values):
3223        if self in values:
3224            return values[self]
3225        else:
3226            return self
3227
3228    def deduce_template_params(self, actual):
3229        return {self: actual}
3230
3231    def same_as_resolved_type(self, other_type):
3232        if isinstance(other_type, TemplatePlaceholderType):
3233            return self.name == other_type.name
3234        else:
3235            return 0
3236
3237    def __hash__(self):
3238        return hash(self.name)
3239
3240    def __cmp__(self, other):
3241        if isinstance(other, TemplatePlaceholderType):
3242            return cmp(self.name, other.name)
3243        else:
3244            return cmp(type(self), type(other))
3245
3246    def __eq__(self, other):
3247        if isinstance(other, TemplatePlaceholderType):
3248            return self.name == other.name
3249        else:
3250            return False
3251
3252class CEnumType(CType):
3253    #  name           string
3254    #  cname          string or None
3255    #  typedef_flag   boolean
3256
3257    is_enum = 1
3258    signed = 1
3259    rank = -1 # Ranks below any integer type
3260    to_py_function = "PyInt_FromLong"
3261    from_py_function = "PyInt_AsLong"
3262
3263    def __init__(self, name, cname, typedef_flag):
3264        self.name = name
3265        self.cname = cname
3266        self.values = []
3267        self.typedef_flag = typedef_flag
3268
3269    def __str__(self):
3270        return self.name
3271
3272    def __repr__(self):
3273        return "<CEnumType %s %s%s>" % (self.name, self.cname,
3274            ("", " typedef")[self.typedef_flag])
3275
3276    def declaration_code(self, entity_code,
3277            for_display = 0, dll_linkage = None, pyrex = 0):
3278        if pyrex or for_display:
3279            base_code = self.name
3280        else:
3281            if self.typedef_flag:
3282                base_code = self.cname
3283            else:
3284                base_code = "enum %s" % self.cname
3285            base_code = public_decl(base_code, dll_linkage)
3286        return self.base_declaration_code(base_code, entity_code)
3287
3288class UnspecifiedType(PyrexType):
3289    # Used as a placeholder until the type can be determined.
3290
3291    is_unspecified = 1
3292
3293    def declaration_code(self, entity_code,
3294            for_display = 0, dll_linkage = None, pyrex = 0):
3295        return "<unspecified>"
3296
3297    def same_as_resolved_type(self, other_type):
3298        return False
3299
3300
3301class ErrorType(PyrexType):
3302    # Used to prevent propagation of error messages.
3303
3304    is_error = 1
3305    exception_value = "0"
3306    exception_check    = 0
3307    to_py_function = "dummy"
3308    from_py_function = "dummy"
3309
3310    def create_to_py_utility_code(self, env):
3311        return True
3312
3313    def create_from_py_utility_code(self, env):
3314        return True
3315
3316    def declaration_code(self, entity_code,
3317            for_display = 0, dll_linkage = None, pyrex = 0):
3318        return "<error>"
3319
3320    def same_as_resolved_type(self, other_type):
3321        return 1
3322
3323    def error_condition(self, result_code):
3324        return "dummy"
3325
3326
3327rank_to_type_name = (
3328    "char",         # 0
3329    "short",        # 1
3330    "int",          # 2
3331    "long",         # 3
3332    "PY_LONG_LONG", # 4
3333    "float",        # 5
3334    "double",       # 6
3335    "long double",  # 7
3336)
3337
3338_rank_to_type_name = list(rank_to_type_name)
3339RANK_INT  = _rank_to_type_name.index('int')
3340RANK_LONG = _rank_to_type_name.index('long')
3341RANK_FLOAT = _rank_to_type_name.index('float')
3342UNSIGNED = 0
3343SIGNED = 2
3344
3345error_type =    ErrorType()
3346unspecified_type = UnspecifiedType()
3347
3348py_object_type = PyObjectType()
3349
3350c_void_type =        CVoidType()
3351
3352c_uchar_type =       CIntType(0, UNSIGNED)
3353c_ushort_type =      CIntType(1, UNSIGNED)
3354c_uint_type =        CIntType(2, UNSIGNED)
3355c_ulong_type =       CIntType(3, UNSIGNED)
3356c_ulonglong_type =   CIntType(4, UNSIGNED)
3357
3358c_char_type =        CIntType(0)
3359c_short_type =       CIntType(1)
3360c_int_type =         CIntType(2)
3361c_long_type =        CIntType(3)
3362c_longlong_type =    CIntType(4)
3363
3364c_schar_type =       CIntType(0, SIGNED)
3365c_sshort_type =      CIntType(1, SIGNED)
3366c_sint_type =        CIntType(2, SIGNED)
3367c_slong_type =       CIntType(3, SIGNED)
3368c_slonglong_type =   CIntType(4, SIGNED)
3369
3370c_float_type =       CFloatType(5, math_h_modifier='f')
3371c_double_type =      CFloatType(6)
3372c_longdouble_type =  CFloatType(7, math_h_modifier='l')
3373
3374c_float_complex_type =      CComplexType(c_float_type)
3375c_double_complex_type =     CComplexType(c_double_type)
3376c_longdouble_complex_type = CComplexType(c_longdouble_type)
3377
3378c_anon_enum_type =   CAnonEnumType(-1)
3379c_returncode_type =  CReturnCodeType(RANK_INT)
3380c_bint_type =        CBIntType(RANK_INT)
3381c_py_unicode_type =  CPyUnicodeIntType(RANK_INT-0.5, UNSIGNED)
3382c_py_ucs4_type =     CPyUCS4IntType(RANK_LONG-0.5, UNSIGNED)
3383c_py_hash_t_type =   CPyHashTType(RANK_LONG+0.5, SIGNED)
3384c_py_ssize_t_type =  CPySSizeTType(RANK_LONG+0.5, SIGNED)
3385c_ssize_t_type =     CSSizeTType(RANK_LONG+0.5, SIGNED)
3386c_size_t_type =      CSizeTType(RANK_LONG+0.5, UNSIGNED)
3387c_ptrdiff_t_type =   CPtrdiffTType(RANK_LONG+0.75, SIGNED)
3388
3389c_null_ptr_type =     CNullPtrType(c_void_type)
3390c_void_ptr_type =     CPtrType(c_void_type)
3391c_void_ptr_ptr_type = CPtrType(c_void_ptr_type)
3392c_char_ptr_type =     CPtrType(c_char_type)
3393c_uchar_ptr_type =    CPtrType(c_uchar_type)
3394c_char_ptr_ptr_type = CPtrType(c_char_ptr_type)
3395c_int_ptr_type =      CPtrType(c_int_type)
3396c_py_unicode_ptr_type = CPtrType(c_py_unicode_type)
3397c_py_ssize_t_ptr_type =  CPtrType(c_py_ssize_t_type)
3398c_ssize_t_ptr_type =  CPtrType(c_ssize_t_type)
3399c_size_t_ptr_type =  CPtrType(c_size_t_type)
3400
3401# GIL state
3402c_gilstate_type = CEnumType("PyGILState_STATE", "PyGILState_STATE", True)
3403c_threadstate_type = CStructOrUnionType("PyThreadState", "struct", None, 1, "PyThreadState")
3404c_threadstate_ptr_type = CPtrType(c_threadstate_type)
3405
3406# the Py_buffer type is defined in Builtin.py
3407c_py_buffer_type = CStructOrUnionType("Py_buffer", "struct", None, 1, "Py_buffer")
3408c_py_buffer_ptr_type = CPtrType(c_py_buffer_type)
3409
3410# Not sure whether the unsigned versions and 'long long' should be in there
3411# long long requires C99 and might be slow, and would always get preferred
3412# when specialization happens through calling and not indexing
3413cy_integral_type = FusedType([c_short_type, c_int_type, c_long_type],
3414                             name="integral")
3415# Omitting long double as it might be slow
3416cy_floating_type = FusedType([c_float_type, c_double_type], name="floating")
3417cy_numeric_type = FusedType([c_short_type,
3418                             c_int_type,
3419                             c_long_type,
3420                             c_float_type,
3421                             c_double_type,
3422                             c_float_complex_type,
3423                             c_double_complex_type], name="numeric")
3424
3425# buffer-related structs
3426c_buf_diminfo_type =  CStructOrUnionType("__Pyx_Buf_DimInfo", "struct",
3427                                      None, 1, "__Pyx_Buf_DimInfo")
3428c_pyx_buffer_type = CStructOrUnionType("__Pyx_Buffer", "struct", None, 1, "__Pyx_Buffer")
3429c_pyx_buffer_ptr_type = CPtrType(c_pyx_buffer_type)
3430c_pyx_buffer_nd_type = CStructOrUnionType("__Pyx_LocalBuf_ND", "struct",
3431                                      None, 1, "__Pyx_LocalBuf_ND")
3432
3433cython_memoryview_type = CStructOrUnionType("__pyx_memoryview_obj", "struct",
3434                                      None, 0, "__pyx_memoryview_obj")
3435
3436memoryviewslice_type = CStructOrUnionType("memoryviewslice", "struct",
3437                                          None, 1, "__Pyx_memviewslice")
3438
3439modifiers_and_name_to_type = {
3440    #(signed, longness, name) : type
3441    (0,  0, "char"): c_uchar_type,
3442    (1,  0, "char"): c_char_type,
3443    (2,  0, "char"): c_schar_type,
3444
3445    (0, -1, "int"): c_ushort_type,
3446    (0,  0, "int"): c_uint_type,
3447    (0,  1, "int"): c_ulong_type,
3448    (0,  2, "int"): c_ulonglong_type,
3449
3450    (1, -1, "int"): c_short_type,
3451    (1,  0, "int"): c_int_type,
3452    (1,  1, "int"): c_long_type,
3453    (1,  2, "int"): c_longlong_type,
3454
3455    (2, -1, "int"): c_sshort_type,
3456    (2,  0, "int"): c_sint_type,
3457    (2,  1, "int"): c_slong_type,
3458    (2,  2, "int"): c_slonglong_type,
3459
3460    (1,  0, "float"):  c_float_type,
3461    (1,  0, "double"): c_double_type,
3462    (1,  1, "double"): c_longdouble_type,
3463
3464    (1,  0, "complex"):  c_double_complex_type,  # C: float, Python: double => Python wins
3465    (1,  0, "floatcomplex"):  c_float_complex_type,
3466    (1,  0, "doublecomplex"): c_double_complex_type,
3467    (1,  1, "doublecomplex"): c_longdouble_complex_type,
3468
3469    #
3470    (1,  0, "void"): c_void_type,
3471
3472    (1,  0, "bint"):       c_bint_type,
3473    (0,  0, "Py_UNICODE"): c_py_unicode_type,
3474    (0,  0, "Py_UCS4"):    c_py_ucs4_type,
3475    (2,  0, "Py_hash_t"):  c_py_hash_t_type,
3476    (2,  0, "Py_ssize_t"): c_py_ssize_t_type,
3477    (2,  0, "ssize_t") :   c_ssize_t_type,
3478    (0,  0, "size_t") :    c_size_t_type,
3479    (2,  0, "ptrdiff_t") : c_ptrdiff_t_type,
3480
3481    (1,  0, "object"): py_object_type,
3482}
3483
3484def is_promotion(src_type, dst_type):
3485    # It's hard to find a hard definition of promotion, but empirical
3486    # evidence suggests that the below is all that's allowed.
3487    if src_type.is_numeric:
3488        if dst_type.same_as(c_int_type):
3489            unsigned = (not src_type.signed)
3490            return (src_type.is_enum or
3491                    (src_type.is_int and
3492                     unsigned + src_type.rank < dst_type.rank))
3493        elif dst_type.same_as(c_double_type):
3494            return src_type.is_float and src_type.rank <= dst_type.rank
3495    return False
3496
3497def best_match(args, functions, pos=None, env=None):
3498    """
3499    Given a list args of arguments and a list of functions, choose one
3500    to call which seems to be the "best" fit for this list of arguments.
3501    This function is used, e.g., when deciding which overloaded method
3502    to dispatch for C++ classes.
3503
3504    We first eliminate functions based on arity, and if only one
3505    function has the correct arity, we return it. Otherwise, we weight
3506    functions based on how much work must be done to convert the
3507    arguments, with the following priorities:
3508      * identical types or pointers to identical types
3509      * promotions
3510      * non-Python types
3511    That is, we prefer functions where no arguments need converted,
3512    and failing that, functions where only promotions are required, and
3513    so on.
3514
3515    If no function is deemed a good fit, or if two or more functions have
3516    the same weight, we return None (as there is no best match). If pos
3517    is not None, we also generate an error.
3518    """
3519    # TODO: args should be a list of types, not a list of Nodes.
3520    actual_nargs = len(args)
3521
3522    candidates = []
3523    errors = []
3524    for func in functions:
3525        error_mesg = ""
3526        func_type = func.type
3527        if func_type.is_ptr:
3528            func_type = func_type.base_type
3529        # Check function type
3530        if not func_type.is_cfunction:
3531            if not func_type.is_error and pos is not None:
3532                error_mesg = "Calling non-function type '%s'" % func_type
3533            errors.append((func, error_mesg))
3534            continue
3535        # Check no. of args
3536        max_nargs = len(func_type.args)
3537        min_nargs = max_nargs - func_type.optional_arg_count
3538        if actual_nargs < min_nargs or \
3539            (not func_type.has_varargs and actual_nargs > max_nargs):
3540            if max_nargs == min_nargs and not func_type.has_varargs:
3541                expectation = max_nargs
3542            elif actual_nargs < min_nargs:
3543                expectation = "at least %s" % min_nargs
3544            else:
3545                expectation = "at most %s" % max_nargs
3546            error_mesg = "Call with wrong number of arguments (expected %s, got %s)" \
3547                         % (expectation, actual_nargs)
3548            errors.append((func, error_mesg))
3549            continue
3550        if func_type.templates:
3551            arg_types = [arg.type for arg in args]
3552            deductions = reduce(
3553                merge_template_deductions,
3554                [pattern.type.deduce_template_params(actual) for (pattern, actual) in zip(func_type.args, arg_types)],
3555                {})
3556            if deductions is None:
3557                errors.append((func, "Unable to deduce type parameters"))
3558            elif len(deductions) < len(func_type.templates):
3559                errors.append((func, "Unable to deduce type parameter %s" % (
3560                    ", ".join([param.name for param in set(func_type.templates) - set(deductions.keys())]))))
3561            else:
3562                type_list = [deductions[param] for param in func_type.templates]
3563                from Symtab import Entry
3564                specialization = Entry(
3565                    name = func.name + "[%s]" % ",".join([str(t) for t in type_list]),
3566                    cname = func.cname + "<%s>" % ",".join([t.declaration_code("") for t in type_list]),
3567                    type = func_type.specialize(deductions),
3568                    pos = func.pos)
3569                candidates.append((specialization, specialization.type))
3570        else:
3571            candidates.append((func, func_type))
3572
3573    # Optimize the most common case of no overloading...
3574    if len(candidates) == 1:
3575        return candidates[0][0]
3576    elif len(candidates) == 0:
3577        if pos is not None:
3578            func, errmsg = errors[0]
3579            if len(errors) == 1 or [1 for func, e in errors if e == errmsg]:
3580                error(pos, errmsg)
3581            else:
3582                error(pos, "no suitable method found")
3583        return None
3584
3585    possibilities = []
3586    bad_types = []
3587    needed_coercions = {}
3588
3589    for index, (func, func_type) in enumerate(candidates):
3590        score = [0,0,0,0]
3591        for i in range(min(len(args), len(func_type.args))):
3592            src_type = args[i].type
3593            dst_type = func_type.args[i].type
3594
3595            assignable = dst_type.assignable_from(src_type)
3596
3597            # Now take care of normal string literals. So when you call a cdef
3598            # function that takes a char *, the coercion will mean that the
3599            # type will simply become bytes. We need to do this coercion
3600            # manually for overloaded and fused functions
3601            if not assignable and src_type.is_pyobject:
3602                if (src_type.is_builtin_type and src_type.name == 'str' and
3603                        dst_type.resolve() is c_char_ptr_type):
3604                    c_src_type = c_char_ptr_type
3605                else:
3606                    c_src_type = src_type.default_coerced_ctype()
3607
3608                if c_src_type:
3609                    assignable = dst_type.assignable_from(c_src_type)
3610                    if assignable:
3611                        src_type = c_src_type
3612                        needed_coercions[func] = i, dst_type
3613
3614            if assignable:
3615                if src_type == dst_type or dst_type.same_as(src_type):
3616                    pass # score 0
3617                elif func_type.is_strict_signature:
3618                    break # exact match requested but not found
3619                elif is_promotion(src_type, dst_type):
3620                    score[2] += 1
3621                elif ((src_type.is_int and dst_type.is_int) or
3622                      (src_type.is_float and dst_type.is_float)):
3623                    score[2] += abs(dst_type.rank + (not dst_type.signed) -
3624                                    (src_type.rank + (not src_type.signed))) + 1
3625                elif not src_type.is_pyobject:
3626                    score[1] += 1
3627                else:
3628                    score[0] += 1
3629            else:
3630                error_mesg = "Invalid conversion from '%s' to '%s'"%(src_type,
3631                                                                     dst_type)
3632                bad_types.append((func, error_mesg))
3633                break
3634        else:
3635            possibilities.append((score, index, func)) # so we can sort it
3636
3637    if possibilities:
3638        possibilities.sort()
3639        if len(possibilities) > 1:
3640            score1 = possibilities[0][0]
3641            score2 = possibilities[1][0]
3642            if score1 == score2:
3643                if pos is not None:
3644                    error(pos, "ambiguous overloaded method")
3645                return None
3646
3647        function = possibilities[0][-1]
3648
3649        if function in needed_coercions and env:
3650            arg_i, coerce_to_type = needed_coercions[function]
3651            args[arg_i] = args[arg_i].coerce_to(coerce_to_type, env)
3652
3653        return function
3654
3655    if pos is not None:
3656        if len(bad_types) == 1:
3657            error(pos, bad_types[0][1])
3658        else:
3659            error(pos, "no suitable method found")
3660
3661    return None
3662
3663def merge_template_deductions(a, b):
3664    if a is None or b is None:
3665        return None
3666    all = a
3667    for param, value in b.iteritems():
3668        if param in all:
3669            if a[param] != b[param]:
3670                return None
3671        else:
3672            all[param] = value
3673    return all
3674
3675def widest_numeric_type(type1, type2):
3676    # Given two numeric types, return the narrowest type
3677    # encompassing both of them.
3678    if type1 == type2:
3679        widest_type = type1
3680    elif type1.is_complex or type2.is_complex:
3681        def real_type(ntype):
3682            if ntype.is_complex:
3683                return ntype.real_type
3684            return ntype
3685        widest_type = CComplexType(
3686            widest_numeric_type(
3687                real_type(type1),
3688                real_type(type2)))
3689    elif type1.is_enum and type2.is_enum:
3690        widest_type = c_int_type
3691    elif type1.rank < type2.rank:
3692        widest_type = type2
3693    elif type1.rank > type2.rank:
3694        widest_type = type1
3695    elif type1.signed < type2.signed:
3696        widest_type = type1
3697    else:
3698        widest_type = type2
3699    return widest_type
3700
3701def independent_spanning_type(type1, type2):
3702    # Return a type assignable independently from both type1 and
3703    # type2, but do not require any interoperability between the two.
3704    # For example, in "True * 2", it is safe to assume an integer
3705    # result type (so spanning_type() will do the right thing),
3706    # whereas "x = True or 2" must evaluate to a type that can hold
3707    # both a boolean value and an integer, so this function works
3708    # better.
3709    if type1 == type2:
3710        return type1
3711    elif (type1 is c_bint_type or type2 is c_bint_type) and (type1.is_numeric and type2.is_numeric):
3712        # special case: if one of the results is a bint and the other
3713        # is another C integer, we must prevent returning a numeric
3714        # type so that we do not lose the ability to coerce to a
3715        # Python bool if we have to.
3716        return py_object_type
3717    span_type = _spanning_type(type1, type2)
3718    if span_type is None:
3719        return error_type
3720    return span_type
3721
3722def spanning_type(type1, type2):
3723    # Return a type assignable from both type1 and type2, or
3724    # py_object_type if no better type is found.  Assumes that the
3725    # code that calls this will try a coercion afterwards, which will
3726    # fail if the types cannot actually coerce to a py_object_type.
3727    if type1 == type2:
3728        return type1
3729    elif type1 is py_object_type or type2 is py_object_type:
3730        return py_object_type
3731    elif type1 is c_py_unicode_type or type2 is c_py_unicode_type:
3732        # Py_UNICODE behaves more like a string than an int
3733        return py_object_type
3734    span_type = _spanning_type(type1, type2)
3735    if span_type is None:
3736        return py_object_type
3737    return span_type
3738
3739def _spanning_type(type1, type2):
3740    if type1.is_numeric and type2.is_numeric:
3741        return widest_numeric_type(type1, type2)
3742    elif type1.is_builtin_type and type1.name == 'float' and type2.is_numeric:
3743        return widest_numeric_type(c_double_type, type2)
3744    elif type2.is_builtin_type and type2.name == 'float' and type1.is_numeric:
3745        return widest_numeric_type(type1, c_double_type)
3746    elif type1.is_extension_type and type2.is_extension_type:
3747        return widest_extension_type(type1, type2)
3748    elif type1.is_pyobject or type2.is_pyobject:
3749        return py_object_type
3750    elif type1.assignable_from(type2):
3751        if type1.is_extension_type and type1.typeobj_is_imported():
3752            # external types are unsafe, so we use PyObject instead
3753            return py_object_type
3754        return type1
3755    elif type2.assignable_from(type1):
3756        if type2.is_extension_type and type2.typeobj_is_imported():
3757            # external types are unsafe, so we use PyObject instead
3758            return py_object_type
3759        return type2
3760    else:
3761        return None
3762
3763def widest_extension_type(type1, type2):
3764    if type1.typeobj_is_imported() or type2.typeobj_is_imported():
3765        return py_object_type
3766    while True:
3767        if type1.subtype_of(type2):
3768            return type2
3769        elif type2.subtype_of(type1):
3770            return type1
3771        type1, type2 = type1.base_type, type2.base_type
3772        if type1 is None or type2 is None:
3773            return py_object_type
3774
3775def simple_c_type(signed, longness, name):
3776    # Find type descriptor for simple type given name and modifiers.
3777    # Returns None if arguments don't make sense.
3778    return modifiers_and_name_to_type.get((signed, longness, name))
3779
3780def parse_basic_type(name):
3781    base = None
3782    if name.startswith('p_'):
3783        base = parse_basic_type(name[2:])
3784    elif name.startswith('p'):
3785        base = parse_basic_type(name[1:])
3786    elif name.endswith('*'):
3787        base = parse_basic_type(name[:-1])
3788    if base:
3789        return CPtrType(base)
3790    #
3791    basic_type = simple_c_type(1, 0, name)
3792    if basic_type:
3793        return basic_type
3794    #
3795    signed = 1
3796    longness = 0
3797    if name == 'Py_UNICODE':
3798        signed = 0
3799    elif name == 'Py_UCS4':
3800        signed = 0
3801    elif name == 'Py_hash_t':
3802        signed = 2
3803    elif name == 'Py_ssize_t':
3804        signed = 2
3805    elif name == 'ssize_t':
3806        signed = 2
3807    elif name == 'size_t':
3808        signed = 0
3809    else:
3810        if name.startswith('u'):
3811            name = name[1:]
3812            signed = 0
3813        elif (name.startswith('s') and
3814              not name.startswith('short')):
3815            name = name[1:]
3816            signed = 2
3817        longness = 0
3818        while name.startswith('short'):
3819            name = name.replace('short', '', 1).strip()
3820            longness -= 1
3821        while name.startswith('long'):
3822            name = name.replace('long', '', 1).strip()
3823            longness += 1
3824        if longness != 0 and not name:
3825            name = 'int'
3826    return simple_c_type(signed, longness, name)
3827
3828def c_array_type(base_type, size):
3829    # Construct a C array type.
3830    if base_type is error_type:
3831        return error_type
3832    else:
3833        return CArrayType(base_type, size)
3834
3835def c_ptr_type(base_type):
3836    # Construct a C pointer type.
3837    if base_type is error_type:
3838        return error_type
3839    else:
3840        return CPtrType(base_type)
3841
3842def c_ref_type(base_type):
3843    # Construct a C reference type
3844    if base_type is error_type:
3845        return error_type
3846    else:
3847        return CReferenceType(base_type)
3848
3849def c_const_type(base_type):
3850    # Construct a C const type.
3851    if base_type is error_type:
3852        return error_type
3853    else:
3854        return CConstType(base_type)
3855
3856def same_type(type1, type2):
3857    return type1.same_as(type2)
3858
3859def assignable_from(type1, type2):
3860    return type1.assignable_from(type2)
3861
3862def typecast(to_type, from_type, expr_code):
3863    #  Return expr_code cast to a C type which can be
3864    #  assigned to to_type, assuming its existing C type
3865    #  is from_type.
3866    if (to_type is from_type or
3867            (not to_type.is_pyobject and assignable_from(to_type, from_type))):
3868        return expr_code
3869    elif (to_type is py_object_type and from_type and
3870            from_type.is_builtin_type and from_type.name != 'type'):
3871        # no cast needed, builtins are PyObject* already
3872        return expr_code
3873    else:
3874        #print "typecast: to", to_type, "from", from_type ###
3875        return to_type.cast_code(expr_code)
3876