def put_var_decref(self, entry):
if entry.type.is_pyobject:
- self.putln("Py_DECREF(%s);" % self.entry_as_pyobject(entry))
+ if entry.init_to_none is False:
+ self.putln("Py_XDECREF(%s);" % self.entry_as_pyobject(entry))
+ else:
+ self.putln("Py_DECREF(%s);" % self.entry_as_pyobject(entry))
def put_var_decref_clear(self, entry):
if entry.type.is_pyobject:
# CNameDeclaratorNode of the name being declared
# and type is the type it is being declared as.
#
- pass
+
+ def analyse_expressions(self, env):
+ pass
+
+ def generate_execution_code(self, env):
+ pass
class CNameDeclaratorNode(CDeclaratorNode):
# cname string or None C name, if specified
def analyse(self, base_type, env):
+ self.type = base_type
return self, base_type
+
+ def analyse_expressions(self, env):
+ self.entry = env.lookup(self.name)
+ if self.rhs is not None:
+ if self.type.is_pyobject:
+ self.entry.init_to_none = False
+ self.entry.init = 0
+ self.rhs.analyse_types(env)
+ self.rhs = self.rhs.coerce_to(self.type, env)
+ self.rhs.allocate_temps(env)
+ self.rhs.release_temp(env)
+ def generate_execution_code(self, code):
+ if self.rhs is not None:
+ self.rhs.generate_evaluation_code(code)
+ if self.type.is_pyobject:
+ self.rhs.make_owned_reference(code)
+ code.putln('%s = %s;' % (self.entry.cname, self.rhs.result_as(self.entry.type)))
+ self.rhs.generate_post_assignment_code(code)
+ code.putln()
class CPtrDeclaratorNode(CDeclaratorNode):
# base CDeclaratorNode
ptr_type = PyrexTypes.c_ptr_type(base_type)
return self.base.analyse(ptr_type, env)
+ def analyse_expressions(self, env):
+ self.base.analyse_expressions(env)
+
+ def generate_execution_code(self, env):
+ self.base.generate_execution_code(env)
class CArrayDeclaratorNode(CDeclaratorNode):
# base CDeclaratorNode
cname = cname, visibility = self.visibility, is_cdef = 1)
def analyse_expressions(self, env):
- pass
+ for declarator in self.declarators:
+ declarator.analyse_expressions(env)
def generate_execution_code(self, code):
- pass
+ for declarator in self.declarators:
+ declarator.generate_execution_code(code)
class CStructOrUnionDefNode(StatNode):
class CFuncDefNode(FuncDefNode):
# C function definition.
#
+ # modifiers 'inline ' or ''
# visibility 'private' or 'public' or 'extern'
# base_type CBaseTypeNode
# declarator CDeclaratorNode
storage_class = "%s " % Naming.extern_c_macro
else:
storage_class = "static "
- code.putln("%s%s {" % (
+ code.putln("%s%s%s {" % (
storage_class,
+ self.modifiers,
header))
def generate_argument_declarations(self, env, code):
cname = None
return cname
-def p_c_declarator(s, empty = 0, is_type = 0, cmethod_flag = 0):
+def p_c_declarator(s, empty = 0, is_type = 0, cmethod_flag = 0 , assignable = 0):
# If empty is true, the declarator must be
# empty, otherwise we don't care.
# If cmethod_flag is true, then if this declarator declares
pos = s.position()
if s.sy == '*':
s.next()
- base = p_c_declarator(s, empty, is_type, cmethod_flag)
+ base = p_c_declarator(s, empty, is_type, cmethod_flag, assignable)
result = Nodes.CPtrDeclaratorNode(pos,
base = base)
elif s.sy == '**': # scanner returns this as a single token
s.next()
- base = p_c_declarator(s, empty, is_type, cmethod_flag)
+ base = p_c_declarator(s, empty, is_type, cmethod_flag, assignable)
result = Nodes.CPtrDeclaratorNode(pos,
base = Nodes.CPtrDeclaratorNode(pos,
base = base))
else:
name = ""
cname = None
+ if s.sy == '=' and assignable:
+ s.next()
+ rhs = p_simple_expr(s)
+ else: rhs = None
result = Nodes.CNameDeclaratorNode(pos,
- name = name, cname = cname)
+ name = name, cname = cname, rhs = rhs)
while s.sy in ('[', '('):
if s.sy == '[':
s.next()
% (prev_visibility, visibility))
s.next()
return visibility
+
+def p_c_modifiers(s):
+ if s.systring in ('inline', ):
+ modifier = s.systring
+ s.next()
+ return modifier + ' ' + p_c_modifiers(s)
+ return ""
def p_c_func_or_var_declaration(s, level, pos, visibility = 'private'):
cmethod_flag = level in ('c_class', 'c_class_pxd')
+ modifiers = p_c_modifiers(s)
base_type = p_c_base_type(s)
- declarator = p_c_declarator(s, cmethod_flag = cmethod_flag)
+ declarator = p_c_declarator(s, cmethod_flag = cmethod_flag, assignable = 1)
if s.sy == ':':
if level not in ('module', 'c_class'):
s.error("C function definition not allowed here")
visibility = visibility,
base_type = base_type,
declarator = declarator,
- body = suite)
+ body = suite,
+ modifiers = modifiers)
else:
if level == 'module_pxd' and visibility <> 'extern':
error(pos,
s.next()
if s.sy == 'NEWLINE':
break
- declarator = p_c_declarator(s, cmethod_flag = cmethod_flag)
+ declarator = p_c_declarator(s, cmethod_flag = cmethod_flag, assignable = 1)
declarators.append(declarator)
s.expect_newline("Syntax error in C variable declaration")
result = Nodes.CVarDefNode(pos,