Commit e4a8d986 authored by Lisandro Dalcin's avatar Lisandro Dalcin

cleanup and minor fixes in PyrexTypes.py

parent e18c8e7a
...@@ -162,6 +162,12 @@ class PyrexType(BaseType): ...@@ -162,6 +162,12 @@ class PyrexType(BaseType):
return 1 return 1
def public_decl(base_code, dll_linkage):
if dll_linkage:
return "%s(%s)" % (dll_linkage, base_code)
else:
return base_code
def create_typedef_type(name, base_type, cname, is_external=0): def create_typedef_type(name, base_type, cname, is_external=0):
if base_type.is_complex: if base_type.is_complex:
if is_external: if is_external:
...@@ -170,6 +176,7 @@ def create_typedef_type(name, base_type, cname, is_external=0): ...@@ -170,6 +176,7 @@ def create_typedef_type(name, base_type, cname, is_external=0):
else: else:
return CTypedefType(name, base_type, cname, is_external) return CTypedefType(name, base_type, cname, is_external)
class CTypedefType(BaseType): class CTypedefType(BaseType):
# #
# Pseudo-type defined with a ctypedef statement in a # Pseudo-type defined with a ctypedef statement in a
...@@ -286,6 +293,7 @@ class CTypedefType(BaseType): ...@@ -286,6 +293,7 @@ class CTypedefType(BaseType):
def __getattr__(self, name): def __getattr__(self, name):
return getattr(self.typedef_base_type, name) return getattr(self.typedef_base_type, name)
class BufferType(BaseType): class BufferType(BaseType):
# #
# Delegates most attribute # Delegates most attribute
...@@ -320,12 +328,7 @@ class BufferType(BaseType): ...@@ -320,12 +328,7 @@ class BufferType(BaseType):
def __repr__(self): def __repr__(self):
return "<BufferType %r>" % self.base return "<BufferType %r>" % self.base
def public_decl(base, dll_linkage):
if dll_linkage:
return "%s(%s)" % (dll_linkage, base)
else:
return base
class PyObjectType(PyrexType): class PyObjectType(PyrexType):
# #
# Base class for all Python object types (reference-counted). # Base class for all Python object types (reference-counted).
...@@ -355,9 +358,11 @@ class PyObjectType(PyrexType): ...@@ -355,9 +358,11 @@ class PyObjectType(PyrexType):
def declaration_code(self, entity_code, def declaration_code(self, entity_code,
for_display = 0, dll_linkage = None, pyrex = 0): for_display = 0, dll_linkage = None, pyrex = 0):
if pyrex or for_display: if pyrex or for_display:
return self.base_declaration_code("object", entity_code) base_code = "object"
else: else:
return "%s *%s" % (public_decl("PyObject", dll_linkage), entity_code) base_code = public_decl("PyObject", dll_linkage)
entity_code = "*%s" % entity_code
return self.base_declaration_code(base_code, entity_code)
def as_pyobject(self, cname): def as_pyobject(self, cname):
if (not self.is_complete()) or self.is_extension_type: if (not self.is_complete()) or self.is_extension_type:
...@@ -436,9 +441,11 @@ class BuiltinObjectType(PyObjectType): ...@@ -436,9 +441,11 @@ class BuiltinObjectType(PyObjectType):
def declaration_code(self, entity_code, def declaration_code(self, entity_code,
for_display = 0, dll_linkage = None, pyrex = 0): for_display = 0, dll_linkage = None, pyrex = 0):
if pyrex or for_display: if pyrex or for_display:
return self.base_declaration_code(self.name, entity_code) base_code = self.name
else: else:
return "%s *%s" % (public_decl("PyObject", dll_linkage), entity_code) base_code = public_decl("PyObject", dll_linkage)
entity_code = "*%s" % entity_code
return self.base_declaration_code(base_code, entity_code)
class PyExtensionType(PyObjectType): class PyExtensionType(PyObjectType):
...@@ -514,17 +521,18 @@ class PyExtensionType(PyObjectType): ...@@ -514,17 +521,18 @@ class PyExtensionType(PyObjectType):
def declaration_code(self, entity_code, def declaration_code(self, entity_code,
for_display = 0, dll_linkage = None, pyrex = 0, deref = 0): for_display = 0, dll_linkage = None, pyrex = 0, deref = 0):
if pyrex or for_display: if pyrex or for_display:
return self.base_declaration_code(self.name, entity_code) base_code = self.name
else: else:
if self.typedef_flag: if self.typedef_flag:
objstruct = self.objstruct_cname objstruct = self.objstruct_cname
else: else:
objstruct = "struct %s" % self.objstruct_cname objstruct = "struct %s" % self.objstruct_cname
base = public_decl(objstruct, dll_linkage) base_code = public_decl(objstruct, dll_linkage)
if deref: if deref:
return "%s %s" % (base, entity_code) assert not entity_code
else: else:
return "%s *%s" % (base, entity_code) entity_code = "*%s" % entity_code
return self.base_declaration_code(base_code, entity_code)
def type_test_code(self, py_arg, notnone=False): def type_test_code(self, py_arg, notnone=False):
...@@ -584,6 +592,10 @@ class CType(PyrexType): ...@@ -584,6 +592,10 @@ class CType(PyrexType):
class CVoidType(CType): class CVoidType(CType):
#
# C "void" type
#
is_void = 1 is_void = 1
def __repr__(self): def __repr__(self):
...@@ -591,8 +603,11 @@ class CVoidType(CType): ...@@ -591,8 +603,11 @@ class CVoidType(CType):
def declaration_code(self, entity_code, def declaration_code(self, entity_code,
for_display = 0, dll_linkage = None, pyrex = 0): for_display = 0, dll_linkage = None, pyrex = 0):
base = public_decl("void", dll_linkage) if pyrex or for_display:
return self.base_declaration_code(base, entity_code) base_code = "void"
else:
base_code = public_decl("void", dll_linkage)
return self.base_declaration_code(base_code, entity_code)
def is_complete(self): def is_complete(self):
return 0 return 0
...@@ -625,10 +640,12 @@ class CNumericType(CType): ...@@ -625,10 +640,12 @@ class CNumericType(CType):
def declaration_code(self, entity_code, def declaration_code(self, entity_code,
for_display = 0, dll_linkage = None, pyrex = 0): for_display = 0, dll_linkage = None, pyrex = 0):
base = public_decl(self.sign_and_name(), dll_linkage) type_name = self.sign_and_name()
if for_display: if pyrex or for_display:
base = base.replace('PY_LONG_LONG', 'long long') base_code = type_name.replace('PY_LONG_LONG', 'long long')
return self.base_declaration_code(base, entity_code) else:
base_code = public_decl(type_name, dll_linkage)
return self.base_declaration_code(base_code, entity_code)
type_conversion_predeclarations = "" type_conversion_predeclarations = ""
...@@ -775,17 +792,36 @@ class CIntType(CNumericType): ...@@ -775,17 +792,36 @@ class CIntType(CNumericType):
is_int = 1 is_int = 1
typedef_flag = 0 typedef_flag = 0
to_py_function = "PyInt_FromLong" to_py_function = None
from_py_function = "__Pyx_PyInt_AsInt" from_py_function = None
exception_value = -1 exception_value = -1
def __init__(self, rank, signed, is_returncode = 0): def __init__(self, rank, signed, is_returncode = 0):
CNumericType.__init__(self, rank, signed) CNumericType.__init__(self, rank, signed)
self.is_returncode = is_returncode self.is_returncode = is_returncode
if self.from_py_function == "__Pyx_PyInt_AsInt": if self.to_py_function is None:
self.from_py_function = self.get_type_conversion() self.to_py_function = self.get_to_py_type_conversion()
if self.from_py_function is None:
def get_type_conversion(self): self.from_py_function = self.get_from_py_type_conversion()
def get_to_py_type_conversion(self):
if self.rank < rank_to_type_name.index('int'):
# This assumes sizeof(short) < sizeof(int)
return "PyInt_FromLong"
else:
# Py{Int|Long}_From[Unsigned]Long[Long]
Prefix = "Int"
SignWord = ""
TypeName = "Long"
if not self.signed:
Prefix = "Long"
SignWord = "Unsigned"
if self.rank == rank_to_type_name.index('PY_LONG_LONG'):
Prefix = "Long"
TypeName = "LongLong"
return "Py%s_From%s%s" % (Prefix, SignWord, TypeName)
def get_from_py_type_conversion(self):
ctype = self.declaration_code('') ctype = self.declaration_code('')
bits = ctype.split(" ", 1) bits = ctype.split(" ", 1)
if len(bits) == 1: if len(bits) == 1:
...@@ -827,48 +863,22 @@ class CAnonEnumType(CIntType): ...@@ -827,48 +863,22 @@ class CAnonEnumType(CIntType):
return 'int' return 'int'
class CUIntType(CIntType):
to_py_function = "PyLong_FromUnsignedLong"
exception_value = -1
class CLongType(CIntType):
to_py_function = "PyInt_FromLong"
class CULongType(CUIntType):
to_py_function = "PyLong_FromUnsignedLong"
class CLongLongType(CIntType):
to_py_function = "PyLong_FromLongLong"
class CULongLongType(CUIntType):
to_py_function = "PyLong_FromUnsignedLongLong"
class CPySSizeTType(CIntType): class CPySSizeTType(CIntType):
to_py_function = "PyInt_FromSsize_t" to_py_function = "PyInt_FromSsize_t"
from_py_function = "__Pyx_PyIndex_AsSsize_t" from_py_function = "__Pyx_PyIndex_AsSsize_t"
def sign_and_name(self): def sign_and_name(self):
return rank_to_type_name[self.rank] return "Py_ssize_t"
class CSizeTType(CUIntType): class CSizeTType(CIntType):
to_py_function = "__Pyx_PyInt_FromSize_t" to_py_function = "__Pyx_PyInt_FromSize_t"
from_py_function = "__Pyx_PyInt_AsSize_t" from_py_function = "__Pyx_PyInt_AsSize_t"
def sign_and_name(self): def sign_and_name(self):
return rank_to_type_name[self.rank] return "size_t"
class CFloatType(CNumericType): class CFloatType(CNumericType):
...@@ -937,15 +947,17 @@ class CComplexType(CNumericType): ...@@ -937,15 +947,17 @@ class CComplexType(CNumericType):
def declaration_code(self, entity_code, def declaration_code(self, entity_code,
for_display = 0, dll_linkage = None, pyrex = 0): for_display = 0, dll_linkage = None, pyrex = 0):
if for_display: if pyrex or for_display:
base = public_decl(self.real_type.sign_and_name() + " complex", dll_linkage) real_code = self.real_type.declaration_code("", for_display, dll_linkage, pyrex)
base_code = "%s complex" % real_code
else: else:
base = public_decl(self.sign_and_name(), dll_linkage) base_code = public_decl(self.sign_and_name(), dll_linkage)
return self.base_declaration_code(base, entity_code) return self.base_declaration_code(base_code, entity_code)
def sign_and_name(self): def sign_and_name(self):
real_type_name = self.real_type.specialization_name() real_type_name = self.real_type.specialization_name()
real_type_name = real_type_name.replace('long__double','long_double') real_type_name = real_type_name.replace('long__double','long_double')
real_type_name = real_type_name.replace('PY_LONG_LONG','long_long')
return Naming.type_prefix + real_type_name + "_complex" return Naming.type_prefix + real_type_name + "_complex"
def assignable_from(self, src_type): def assignable_from(self, src_type):
...@@ -1752,16 +1764,15 @@ class CStructOrUnionType(CType): ...@@ -1752,16 +1764,15 @@ class CStructOrUnionType(CType):
def declaration_code(self, entity_code, def declaration_code(self, entity_code,
for_display = 0, dll_linkage = None, pyrex = 0): for_display = 0, dll_linkage = None, pyrex = 0):
if pyrex: if pyrex or for_display:
return self.base_declaration_code(self.name, entity_code) base_code = self.name
else: else:
if for_display: if self.typedef_flag:
base = self.name base_code = self.cname
elif self.typedef_flag:
base = self.cname
else: else:
base = "%s %s" % (self.kind, self.cname) base_code = "%s %s" % (self.kind, self.cname)
return self.base_declaration_code(public_decl(base, dll_linkage), entity_code) base_code = public_decl(base_code, dll_linkage)
return self.base_declaration_code(base_code, entity_code)
def __eq__(self, other): def __eq__(self, other):
try: try:
...@@ -1851,20 +1862,24 @@ class CppClassType(CType): ...@@ -1851,20 +1862,24 @@ class CppClassType(CType):
specialized.namespace = self.namespace.specialize(values) specialized.namespace = self.namespace.specialize(values)
return specialized return specialized
def declaration_code(self, entity_code, for_display = 0, dll_linkage = None, pyrex = 0): def declaration_code(self, entity_code,
for_display = 0, dll_linkage = None, pyrex = 0):
if self.templates: if self.templates:
template_strings = [param.declaration_code('', for_display, pyrex) for param in self.templates] template_strings = [param.declaration_code('', for_display, None, pyrex)
for param in self.templates]
templates = "<%s>" % ",".join(template_strings) templates = "<%s>" % ",".join(template_strings)
if templates[-2:] == ">>":
templates = templates[:-2] + "> >"
else: else:
templates = "" templates = ""
if for_display or pyrex: if pyrex or for_display:
name = self.name base_code = "%s%s" % (self.name, templates)
else: else:
base_code = "%s%s" % (self.cname, templates)
if self.namespace is not None: if self.namespace is not None:
name = "%s::%s" % (self.namespace.declaration_code(''), self.cname) base_code = "%s::%s" % (self.namespace.declaration_code(''), base_code)
else: base_code = public_decl(base_code, dll_linkage)
name = self.cname return self.base_declaration_code(base_code, entity_code)
return "%s%s %s" % (name, templates, entity_code)
def is_subclass(self, other_type): def is_subclass(self, other_type):
# TODO(danilo): Handle templates. # TODO(danilo): Handle templates.
...@@ -1903,7 +1918,8 @@ class TemplatePlaceholderType(CType): ...@@ -1903,7 +1918,8 @@ class TemplatePlaceholderType(CType):
def __init__(self, name): def __init__(self, name):
self.name = name self.name = name
def declaration_code(self, entity_code, for_display = 0, dll_linkage = None, pyrex = 0): def declaration_code(self, entity_code,
for_display = 0, dll_linkage = None, pyrex = 0):
if entity_code: if entity_code:
return self.name + " " + entity_code return self.name + " " + entity_code
else: else:
...@@ -1956,14 +1972,15 @@ class CEnumType(CType): ...@@ -1956,14 +1972,15 @@ class CEnumType(CType):
def declaration_code(self, entity_code, def declaration_code(self, entity_code,
for_display = 0, dll_linkage = None, pyrex = 0): for_display = 0, dll_linkage = None, pyrex = 0):
if pyrex: if pyrex or for_display:
return self.base_declaration_code(self.cname, entity_code) base_code = self.name
else: else:
if self.typedef_flag: if self.typedef_flag:
base = self.cname base_code = self.cname
else: else:
base = "enum %s" % self.cname base_code = "enum %s" % self.cname
return self.base_declaration_code(public_decl(base, dll_linkage), entity_code) base_code = public_decl(base_code, dll_linkage)
return self.base_declaration_code(base_code, entity_code)
class CStringType(object): class CStringType(object):
...@@ -2076,23 +2093,23 @@ c_void_ptr_ptr_type = CPtrType(c_void_ptr_type) ...@@ -2076,23 +2093,23 @@ c_void_ptr_ptr_type = CPtrType(c_void_ptr_type)
c_uchar_type = CIntType(0, 0) c_uchar_type = CIntType(0, 0)
c_ushort_type = CIntType(1, 0) c_ushort_type = CIntType(1, 0)
c_uint_type = CUIntType(2, 0) c_uint_type = CIntType(2, 0)
c_ulong_type = CULongType(3, 0) c_ulong_type = CIntType(3, 0)
c_ulonglong_type = CULongLongType(6, 0) c_ulonglong_type = CIntType(6, 0)
c_char_type = CIntType(0, 1) c_char_type = CIntType(0, 1)
c_short_type = CIntType(1, 1) c_short_type = CIntType(1, 1)
c_int_type = CIntType(2, 1) c_int_type = CIntType(2, 1)
c_long_type = CLongType(3, 1) c_long_type = CIntType(3, 1)
c_longlong_type = CLongLongType(6, 1) c_longlong_type = CIntType(6, 1)
c_bint_type = CBIntType(2, 1)
c_schar_type = CIntType(0, 2) c_schar_type = CIntType(0, 2)
c_sshort_type = CIntType(1, 2) c_sshort_type = CIntType(1, 2)
c_sint_type = CIntType(2, 2) c_sint_type = CIntType(2, 2)
c_slong_type = CLongType(3, 2) c_slong_type = CIntType(3, 2)
c_slonglong_type = CLongLongType(6, 2) c_slonglong_type = CIntType(6, 2)
c_bint_type = CBIntType(2, 1)
c_py_ssize_t_type = CPySSizeTType(4, 2) c_py_ssize_t_type = CPySSizeTType(4, 2)
c_size_t_type = CSizeTType(5, 0) c_size_t_type = CSizeTType(5, 0)
...@@ -2100,7 +2117,9 @@ c_float_type = CFloatType(7, math_h_modifier='f') ...@@ -2100,7 +2117,9 @@ c_float_type = CFloatType(7, math_h_modifier='f')
c_double_type = CFloatType(8) c_double_type = CFloatType(8)
c_longdouble_type = CFloatType(9, math_h_modifier='l') c_longdouble_type = CFloatType(9, math_h_modifier='l')
c_double_complex_type = CComplexType(c_double_type) c_float_complex_type = CComplexType(c_float_type)
c_double_complex_type = CComplexType(c_double_type)
c_longdouble_complex_type = CComplexType(c_longdouble_type)
c_null_ptr_type = CNullPtrType(c_void_type) c_null_ptr_type = CNullPtrType(c_void_type)
c_char_array_type = CCharArrayType(None) c_char_array_type = CCharArrayType(None)
...@@ -2113,7 +2132,6 @@ c_py_ssize_t_ptr_type = CPtrType(c_py_ssize_t_type) ...@@ -2113,7 +2132,6 @@ c_py_ssize_t_ptr_type = CPtrType(c_py_ssize_t_type)
c_size_t_ptr_type = CPtrType(c_size_t_type) c_size_t_ptr_type = CPtrType(c_size_t_type)
c_returncode_type = CIntType(2, 1, is_returncode = 1) c_returncode_type = CIntType(2, 1, is_returncode = 1)
c_anon_enum_type = CAnonEnumType(-1, 1) c_anon_enum_type = CAnonEnumType(-1, 1)
# the Py_buffer type is defined in Builtin.py # the Py_buffer type is defined in Builtin.py
...@@ -2192,24 +2210,6 @@ modifiers_and_name_to_type = { ...@@ -2192,24 +2210,6 @@ modifiers_and_name_to_type = {
(1, 0, "bint"): c_bint_type, (1, 0, "bint"): c_bint_type,
} }
def is_promotion0(src_type, dst_type):
if src_type.is_numeric and dst_type.is_numeric:
if src_type.is_int and dst_type.is_int:
if src_type.is_enum:
return True
elif src_type.signed:
return dst_type.signed and src_type.rank <= dst_type.rank
elif dst_type.signed: # and not src_type.signed
src_type.rank < dst_type.rank
else:
return src_type.rank <= dst_type.rank
elif src_type.is_float and dst_type.is_float:
return src_type.rank <= dst_type.rank
else:
return False
else:
return False
def is_promotion(src_type, dst_type): def is_promotion(src_type, dst_type):
# It's hard to find a hard definition of promotion, but empirical # It's hard to find a hard definition of promotion, but empirical
# evidence suggests that the below is all that's allowed. # evidence suggests that the below is all that's allowed.
...@@ -2323,7 +2323,6 @@ def best_match(args, functions, pos=None): ...@@ -2323,7 +2323,6 @@ def best_match(args, functions, pos=None):
error(pos, "no suitable method found") error(pos, "no suitable method found")
return None return None
def widest_numeric_type(type1, type2): def widest_numeric_type(type1, type2):
# Given two numeric types, return the narrowest type # Given two numeric types, return the narrowest type
# encompassing both of them. # encompassing both of them.
...@@ -2432,19 +2431,6 @@ def c_ref_type(base_type): ...@@ -2432,19 +2431,6 @@ def c_ref_type(base_type):
return error_type return error_type
else: else:
return CReferenceType(base_type) return CReferenceType(base_type)
def Node_to_type(node, env):
from ExprNodes import NameNode, AttributeNode, StringNode, error
if isinstance(node, StringNode):
node = NameNode(node.pos, name=node.value)
if isinstance(node, NameNode) and node.name in rank_to_type_name:
return simple_c_type(1, 0, node.name)
elif isinstance(node, (AttributeNode, NameNode)):
node.analyze_types(env)
if not node.entry.is_type:
pass
else:
error(node.pos, "Bad type")
def same_type(type1, type2): def same_type(type1, type2):
return type1.same_as(type2) return type1.same_as(type2)
...@@ -2587,4 +2573,3 @@ static CYTHON_INLINE size_t __Pyx_PyInt_AsSize_t(PyObject* x) { ...@@ -2587,4 +2573,3 @@ static CYTHON_INLINE size_t __Pyx_PyInt_AsSize_t(PyObject* x) {
""" + type_conversion_functions """ + type_conversion_functions
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment