if debug_temp_alloc:
print self, "Allocated result", self.result_code
else:
- self.result_code = self.calculate_result_code_with_env(env)
-
- def calculate_result_code_with_env(self, env):
- return self.calculate_result_code()
+ self.result_code = self.calculate_result_code()
def target_code(self):
# Return code fragment for use as LHS of a C assignment.
error(self.pos, "Assignment to non-lvalue '%s'"
% self.name)
self.type = PyrexTypes.error_type
+ self.entry.used = 1
def analyse_rvalue_entry(self, env):
#print "NameNode.analyse_rvalue_entry:", self.name ###
# Name nodes are never ephemeral, even if the
# result is in a temporary.
return 0
-
- def calculate_result_code_with_env(self, env):
+
+ def allocate_temp(self, env, result = None):
+ AtomicExprNode.allocate_temp(self, env, result)
entry = self.entry
if entry:
entry.used = 1
if entry.utility_code:
env.use_utility_code(entry.utility_code)
- return self.calculate_result_code()
-
+
def calculate_result_code(self):
entry = self.entry
if not entry:
return "<error>" # There was an error earlier
- entry.used = 1
return entry.cname
def generate_result_code(self, code):
return 0
def generate_h_code(self, env, options, result):
- public_types = []
- public_vars = []
- public_funcs = []
- public_extension_types = []
- for entry in env.type_entries:
- if entry.visibility == 'public':
- public_types.append(entry)
- for entry in env.var_entries:
- if entry.visibility == 'public':
- public_vars.append(entry)
- for entry in env.cfunc_entries:
- if entry.visibility == 'public' and not entry.in_cinclude:
- public_funcs.append(entry)
- for entry in env.c_class_entries:
- if entry.visibility == 'public':
- public_extension_types.append(entry)
- if public_types or public_vars or public_funcs or public_extension_types:
+ def h_entries(entries, pxd = 0):
+ return [entry for entry in entries
+ if entry.visibility == 'public' or pxd and entry.defined_in_pxd]
+ h_types = h_entries(env.type_entries)
+ h_vars = h_entries(env.var_entries)
+ h_funcs = h_entries(env.cfunc_entries)
+ h_extension_types = h_entries(env.c_class_entries)
+ if h_types or h_vars or h_funcs or h_extension_types:
result.h_file = replace_suffix(result.c_file, ".h")
h_code = Code.CCodeWriter(open_new_file(result.h_file))
if options.generate_pxi:
guard = Naming.h_guard_prefix + env.qualified_name.replace(".", "__")
h_code.put_h_guard(guard)
self.generate_extern_c_macro_definition(h_code)
- self.generate_type_header_code(public_types, h_code)
+ self.generate_type_header_code(h_types, h_code)
h_code.putln("")
h_code.putln("#ifndef %s" % Naming.api_guard_prefix + self.api_name(env))
- if public_vars:
+ if h_vars:
h_code.putln("")
- for entry in public_vars:
+ for entry in h_vars:
self.generate_public_declaration(entry, h_code, i_code)
- if public_funcs:
+ if h_funcs:
h_code.putln("")
- for entry in public_funcs:
+ for entry in h_funcs:
self.generate_public_declaration(entry, h_code, i_code)
- if public_extension_types:
+ if h_extension_types:
h_code.putln("")
- for entry in public_extension_types:
+ for entry in h_extension_types:
self.generate_cclass_header_code(entry.type, h_code)
if i_code:
self.generate_cclass_include_code(entry.type, i_code)
def generate_api_code(self, env, result):
api_funcs = []
+ public_extension_types = []
+ has_api_extension_types = 0
for entry in env.cfunc_entries:
if entry.api:
api_funcs.append(entry)
- public_extension_types = []
for entry in env.c_class_entries:
if entry.visibility == 'public':
public_extension_types.append(entry)
- if api_funcs or public_extension_types:
+ if entry.api:
+ has_api_extension_types = 1
+ if api_funcs or has_api_extension_types:
result.api_file = replace_suffix(result.c_file, "_api.h")
h_code = Code.CCodeWriter(open_new_file(result.api_file))
name = self.api_name(env)
h_code.putln("#endif")
if api_funcs:
h_code.putln("")
- h_code.put_h_guard(Naming.api_func_guard + "import_function")
h_code.put(function_import_utility_code[1])
- h_code.putln("")
- h_code.putln("#endif")
if public_extension_types:
h_code.putln("")
- h_code.put_h_guard(Naming.api_func_guard + "import_type")
h_code.put(type_import_utility_code[1])
- h_code.putln("")
- h_code.putln("#endif")
h_code.putln("")
h_code.putln("static int import_%s(void) {" % name)
h_code.putln("PyObject *module = 0;")
else:
i_code.putln("pass")
i_code.dedent()
-
+
def generate_c_code(self, env, result):
-# modules = []
-# self.find_referenced_modules(env, modules, {})
modules = self.referenced_modules
code = Code.CCodeWriter(StringIO())
code.h = Code.CCodeWriter(StringIO())
if definition:
type_entries = env.type_entries
else:
- type_entries = [
- entry for entry in env.type_entries
- if entry.defined_in_pxd]
+ type_entries = []
+ for entry in env.type_entries:
+ if entry.defined_in_pxd:
+ type_entries.append(entry)
self.generate_type_header_code(type_entries, code)
for entry in env.c_class_entries:
if not entry.in_cinclude:
objstruct = type.objstruct_cname
else:
objstruct = "struct %s" % type.objstruct_cname
-# code.putln('%s = __Pyx_ImportType("%s", "%s", sizeof(%s)); %s' % (
-# type.typeptr_cname,
-# type.module_name,
-# type.name,
-# objstruct,
-# code.error_goto_if_null(type.typeptr_cname, pos)))
self.generate_type_import_call(type, code,
code.error_goto_if_null(type.typeptr_cname, pos))
self.use_type_import_utility_code(env)
code.put(utility_code[1])
#------------------------------------------------------------------------------------
-
-#type_import_utility_code = [
-#"""
-#static PyTypeObject *__Pyx_ImportType(char *module_name, char *class_name, long size); /*proto*/
-#""","""
-#static PyTypeObject *__Pyx_ImportType(char *module_name, char *class_name,
-# long size)
-#{
-# PyObject *py_module_name = 0;
-# PyObject *py_class_name = 0;
-# PyObject *py_name_list = 0;
-# PyObject *py_module = 0;
-# PyObject *result = 0;
-#
-# py_module_name = PyString_FromString(module_name);
-# if (!py_module_name)
-# goto bad;
-# py_class_name = PyString_FromString(class_name);
-# if (!py_class_name)
-# goto bad;
-# py_name_list = PyList_New(1);
-# if (!py_name_list)
-# goto bad;
-# Py_INCREF(py_class_name);
-# if (PyList_SetItem(py_name_list, 0, py_class_name) < 0)
-# goto bad;
-# py_module = __Pyx_Import(py_module_name, py_name_list);
-# if (!py_module)
-# goto bad;
-# result = PyObject_GetAttr(py_module, py_class_name);
-# if (!result)
-# goto bad;
-# if (!PyType_Check(result)) {
-# PyErr_Format(PyExc_TypeError,
-# "%s.%s is not a type object",
-# module_name, class_name);
-# goto bad;
-# }
-# if (((PyTypeObject *)result)->tp_basicsize != size) {
-# PyErr_Format(PyExc_ValueError,
-# "%s.%s does not appear to be the correct type object",
-# module_name, class_name);
-# goto bad;
-# }
-# goto done;
-#bad:
-# Py_XDECREF(result);
-# result = 0;
-#done:
-# Py_XDECREF(py_module_name);
-# Py_XDECREF(py_class_name);
-# Py_XDECREF(py_name_list);
-# return (PyTypeObject *)result;
-#}
-#"""]
-
+#
+# Runtime support code
+#
#------------------------------------------------------------------------------------
import_module_utility_code = [
"""
static PyTypeObject *__Pyx_ImportType(PyObject *py_module, char *module_name, char *class_name, long size); /*proto*/
""","""
+#ifndef __PYX_HAVE_RT_ImportType
+#define __PYX_HAVE_RT_ImportType
static PyTypeObject *__Pyx_ImportType(PyObject *py_module, char *module_name, char *class_name, long size) {
PyObject *result = 0;
Py_XDECREF(result);
return 0;
}
+#endif
"""]
#------------------------------------------------------------------------------------
"""
static int __Pyx_ImportFunction(PyObject *module, char *funcname, void **f, char *sig); /*proto*/
""","""
+#ifndef __PYX_HAVE_RT_ImportFunction
+#define __PYX_HAVE_RT_ImportFunction
static int __Pyx_ImportFunction(PyObject *module, char *funcname, void **f, char *sig) {
PyObject *d = 0;
PyObject *cobj = 0;
Py_XDECREF(d);
return -1;
}
+#endif
""" % dict(API = Naming.api_name)]
# base_type CBaseTypeNode
# declarators [CDeclaratorNode]
# in_pxd boolean
+ # api boolean
def analyse_declarations(self, env, dest_scope = None):
if not dest_scope:
return
if type.is_cfunction:
entry = dest_scope.declare_cfunction(name, type, declarator.pos,
- cname = cname, visibility = self.visibility, in_pxd = self.in_pxd)
- #if self.visibility <> 'extern':
- # if self.in_pxd:
- # entry.defined_in_pxd = 1
- # else:
- # error(declarator.pos,
- # "Non-extern C function declared but not defined")
+ cname = cname, visibility = self.visibility, in_pxd = self.in_pxd,
+ api = self.api)
else:
if self.in_pxd and self.visibility != 'extern':
error(self.pos,
# kind "struct" or "union"
# typedef_flag boolean
# visibility "public" or "private"
+ # in_pxd boolean
# attributes [CVarDefNode] or None
# entry Entry
self.name, self.kind, scope, self.typedef_flag, self.pos,
self.cname, visibility = self.visibility)
if self.attributes is not None:
+ if self.in_pxd and not env.in_cinclude:
+ self.entry.defined_in_pxd = 1
for attr in self.attributes:
attr.analyse_declarations(env, scope)
-
+
def analyse_expressions(self, env):
pass
# cname string or None
# items [CEnumDefItemNode]
# typedef_flag boolean
- # visibility "public" or "private"
+ # visibility "public" or "private"
+ # in_pxd boolean
# entry Entry
def analyse_declarations(self, env):
self.entry = env.declare_enum(self.name, self.pos,
cname = self.cname, typedef_flag = self.typedef_flag,
visibility = self.visibility)
- for item in self.items:
- item.analyse_declarations(env, self.entry)
+ if self.items is not None:
+ if self.in_pxd and not env.in_cinclude:
+ self.entry.defined_in_pxd = 1
+ for item in self.items:
+ item.analyse_declarations(env, self.entry)
def analyse_expressions(self, env):
pass
class CTypeDefNode(StatNode):
- # base_type CBaseTypeNode
- # declarator CDeclaratorNode
- # visibility "public" or "private"
+ # base_type CBaseTypeNode
+ # declarator CDeclaratorNode
+ # visibility "public" or "private"
+ # in_pxd boolean
def analyse_declarations(self, env):
base = self.base_type.analyse(env)
name_declarator, type = self.declarator.analyse(base, env)
name = name_declarator.name
cname = name_declarator.cname
- #if env.in_cinclude:
- # type = CTypedefType(cname, type)
- env.declare_typedef(name, type, self.pos,
+ entry = env.declare_typedef(name, type, self.pos,
cname = cname, visibility = self.visibility)
+ if self.in_pxd and not env.in_cinclude:
+ entry.defined_in_pxd = 1
def analyse_expressions(self, env):
pass
-
def generate_execution_code(self, code):
pass
#if api:
# error(pos, "'api' not allowed with '%s'" % s.systring)
if s.systring == "enum":
- return p_c_enum_definition(s, pos, visibility)
+ return p_c_enum_definition(s, pos, level, visibility)
else:
- return p_c_struct_or_union_definition(s, pos, visibility)
+ return p_c_struct_or_union_definition(s, pos, level, visibility)
elif s.sy == 'pass':
node = p_pass_statement(s)
s.expect_newline('Expected a newline')
"struct", "union", "enum"
)
-def p_c_enum_definition(s, pos, visibility, typedef_flag = 0):
+def p_c_enum_definition(s, pos, level, visibility, typedef_flag = 0):
# s.sy == ident 'enum'
s.next()
if s.sy == 'IDENT':
p_c_enum_line(s, items)
s.expect_dedent()
return Nodes.CEnumDefNode(pos, name = name, cname = cname,
- items = items, typedef_flag = typedef_flag, visibility = visibility)
+ items = items, typedef_flag = typedef_flag, visibility = visibility,
+ in_pxd = level == 'module_pxd')
def p_c_enum_line(s, items):
if s.sy <> 'pass':
items.append(Nodes.CEnumDefItemNode(pos,
name = name, cname = cname, value = value))
-def p_c_struct_or_union_definition(s, pos, visibility, typedef_flag = 0):
+def p_c_struct_or_union_definition(s, pos, level, visibility, typedef_flag = 0):
# s.sy == ident 'struct' or 'union'
kind = s.systring
s.next()
s.expect_newline("Syntax error in struct or union definition")
return Nodes.CStructOrUnionDefNode(pos,
name = name, cname = cname, kind = kind, attributes = attributes,
- typedef_flag = typedef_flag, visibility = visibility)
+ typedef_flag = typedef_flag, visibility = visibility,
+ in_pxd = level == 'module_pxd')
def p_visibility(s, prev_visibility):
pos = s.position()
visibility = visibility,
base_type = base_type,
declarators = declarators,
- in_pxd = level == 'module_pxd')
+ in_pxd = level == 'module_pxd',
+ api = api)
return result
def p_ctypedef_statement(s, level, visibility = 'private', api = 0):
visibility = visibility, typedef_flag = 1, api = api)
elif s.sy == 'IDENT' and s.systring in ('struct', 'union', 'enum'):
if s.systring == 'enum':
- return p_c_enum_definition(s, pos, visibility, typedef_flag = 1)
+ return p_c_enum_definition(s, pos, level, visibility, typedef_flag = 1)
else:
- return p_c_struct_or_union_definition(s, pos, visibility, typedef_flag = 1)
+ return p_c_struct_or_union_definition(s, pos, level, visibility,
+ typedef_flag = 1)
else:
base_type = p_c_base_type(s)
declarator = p_c_declarator(s, is_type = 1, nonempty = 1)
s.expect_newline("Syntax error in ctypedef statement")
return Nodes.CTypeDefNode(pos,
- base_type = base_type, declarator = declarator, visibility = visibility)
+ base_type = base_type, declarator = declarator, visibility = visibility,
+ in_pxd = level == 'module_pxd')
def p_def_statement(s):
# s.sy == 'def'
type = PyrexTypes.CTypedefType(cname, base_type)
entry = self.declare_type(name, type, pos, cname, visibility)
type.qualified_name = entry.qualified_name
+ return entry
def declare_struct_or_union(self, name, kind, scope,
typedef_flag, pos, cname = None, visibility = 'private'):