Commit 0f319c23 authored by Stefan Behnel's avatar Stefan Behnel

General cdef block

parent 105244d3
......@@ -807,6 +807,7 @@ class CFuncDefNode(FuncDefNode):
def generate_function_header(self, code, with_pymethdef):
arg_decls = []
type = self.type
visibility = self.entry.visibility
for arg in type.args:
arg_decls.append(arg.declaration_code())
if type.has_varargs:
......@@ -815,18 +816,16 @@ class CFuncDefNode(FuncDefNode):
arg_decls = ["void"]
entity = type.function_header_code(self.entry.func_cname,
string.join(arg_decls, ","))
if self.visibility == 'public':
if visibility == 'public':
dll_linkage = "DL_EXPORT"
else:
dll_linkage = None
header = self.return_type.declaration_code(entity,
dll_linkage = dll_linkage)
if self.visibility == 'private':
storage_class = "static "
elif self.visibility == 'extern':
if visibility <> 'private':
storage_class = "%s " % Naming.extern_c_macro
else:
storage_class = ""
storage_class = "static "
code.putln("%s%s %s {" % (
storage_class,
' '.join(self.modifiers).upper(), # macro forms
......@@ -1476,6 +1475,7 @@ class CClassDefNode(StatNode):
#
# visibility 'private' or 'public' or 'extern'
# typedef_flag boolean
# api boolean
# module_name string or None For import of extern type objects
# class_name string Unqualified name of class
# as_name string or None Name to declare as in this scope
......@@ -1524,7 +1524,8 @@ class CClassDefNode(StatNode):
objstruct_cname = self.objstruct_name,
typeobj_cname = self.typeobj_name,
visibility = self.visibility,
typedef_flag = self.typedef_flag)
typedef_flag = self.typedef_flag,
api = self.api)
scope = self.entry.type.scope
if self.doc:
......
......@@ -1301,7 +1301,7 @@ def p_statement(s, level, cdef_flag = 0, visibility = 'private', api = 0):
s.error("ctypedef statement not allowed here")
if api:
error(s.pos, "'api' not allowed with 'ctypedef'")
return p_ctypedef_statement(s, level, visibility)
return p_ctypedef_statement(s, level, visibility, api)
elif s.sy == 'DEF':
return p_DEF_statement(s)
elif s.sy == 'IF':
......@@ -1713,20 +1713,20 @@ def p_cdef_statement(s, level, visibility = 'private', api = 0,
if visibility == 'extern' and s.sy == 'from':
return p_cdef_extern_block(s, level, pos)
elif s.sy == ':':
p_cdef_block(s, level, visibility, api)
return p_cdef_block(s, level, visibility, api)
elif s.sy == 'class':
if level not in ('module', 'module_pxd'):
error(pos, "Extension type definition not allowed here")
if api:
error(pos, "'api' not allowed with extension class")
return p_c_class_definition(s, level, pos, visibility = visibility)
#if api:
# error(pos, "'api' not allowed with extension class")
return p_c_class_definition(s, level, pos, visibility = visibility, api = api)
elif s.sy == 'IDENT' and s.systring in struct_union_or_enum:
if level not in ('module', 'module_pxd'):
error(pos, "C struct/union/enum definition not allowed here")
#if visibility == 'public':
# error(pos, "Public struct/union/enum definition not implemented")
if api:
error(pos, "'api' not allowed with '%s'" % s.systring)
#if api:
# error(pos, "'api' not allowed with '%s'" % s.systring)
if s.systring == "enum":
return p_c_enum_definition(s, pos, visibility)
else:
......@@ -1740,8 +1740,7 @@ def p_cdef_statement(s, level, visibility = 'private', api = 0,
overridable)
def p_cdef_block(s, level, visibility, api):
body = p_suite(s, level, cdef_flag = 1, visibility = 'extern', api = api)
return Nodes.StatListNode(pos, stats = body)
return p_suite(s, level, cdef_flag = 1, visibility = visibility, api = api)
def p_cdef_extern_block(s, level, pos):
include_file = None
......@@ -1871,8 +1870,8 @@ def p_c_func_or_var_declaration(s, level, pos, visibility = 'private', api = 0,
api = api,
overridable = overridable)
else:
if api:
error(s.pos, "'api' not allowed with variable declaration")
#if api:
# error(s.pos, "'api' not allowed with variable declaration")
declarators = [declarator]
while s.sy == ',':
s.next()
......@@ -1888,15 +1887,14 @@ def p_c_func_or_var_declaration(s, level, pos, visibility = 'private', api = 0,
in_pxd = level == 'module_pxd')
return result
def p_ctypedef_statement(s, level, visibility = 'private'):
def p_ctypedef_statement(s, level, visibility = 'private', api = 0):
# s.sy == 'ctypedef'
pos = s.position()
s.next()
visibility = p_visibility(s, visibility)
if s.sy == 'class':
return p_c_class_definition(s, level, pos,
visibility = visibility,
typedef_flag = 1)
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)
......@@ -1963,7 +1961,7 @@ def p_class_statement(s):
doc = doc, body = body)
def p_c_class_definition(s, level, pos,
visibility = 'private', typedef_flag = 0):
visibility = 'private', typedef_flag = 0, api = 0):
# s.sy == 'class'
s.next()
module_path = []
......@@ -2019,9 +2017,13 @@ def p_c_class_definition(s, level, pos,
error(pos, "Object struct name specification required for 'public' C class")
if not typeobj_name:
error(pos, "Type object name specification required for 'public' C class")
else:
if api:
error(pos, "Only 'public' C class can be declared 'api'")
return Nodes.CClassDefNode(pos,
visibility = visibility,
typedef_flag = typedef_flag,
api = api,
module_name = ".".join(module_path),
class_name = class_name,
as_name = as_name,
......
......@@ -68,7 +68,7 @@ class Entry:
# is_special boolean Is a special method or property accessor
# of an extension type
# defined_in_pxd boolean Is defined in a .pxd file (not just declared)
# api boolean Generate C API for C function
# api boolean Generate C API for C class or function
borrowed = 0
init = ""
......@@ -353,6 +353,9 @@ class Scope:
# Add an entry for a C function.
entry = self.lookup_here(name)
if entry:
if visibility <> 'private' and visibility <> entry.visibility:
error(pos, "Function '%s' previously declared as '%s'" % (
name, entry.visibility))
if not entry.type.same_as(type):
error(pos, "Function signature does not match previous declaration")
else:
......@@ -823,7 +826,7 @@ class ModuleScope(Scope):
def declare_c_class(self, name, pos, defining, implementing,
module_name, base_type, objstruct_cname, typeobj_cname,
visibility, typedef_flag):
visibility, typedef_flag, api):
#
# Look for previous declaration as a type
#
......@@ -882,9 +885,11 @@ class ModuleScope(Scope):
entry.defined_in_pxd = 1
if implementing: # So that filenames in runtime exceptions refer to
entry.pos = pos # the .pyx file and not the .pxd file
if entry.visibility <> visibility:
error(pos, "Declaration of '%s' as '%s' conflicts with previous "
"declaration as '%s'" % (name, visibility, entry.visibility))
if visibility <> 'private' and entry.visibility <> visibility:
error(pos, "Class '%s' previously declared as '%s'"
% (name, entry.visibility))
if api:
entry.api = 1
if objstruct_cname:
if type.objstruct_cname and type.objstruct_cname <> objstruct_cname:
error(pos, "Object struct name differs from previous declaration")
......
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