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:
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
#
# 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
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:
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':
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:
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
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()
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)
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 = []
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,
# 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 = ""
# 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:
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
#
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")