Commit 136f8912 authored by DaniloFreitas's avatar DaniloFreitas

Cpp class scope and type

parent daf0017c
...@@ -703,6 +703,35 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -703,6 +703,35 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.putln("#pragma pack(pop)") code.putln("#pragma pack(pop)")
code.putln("#endif") code.putln("#endif")
def generate_cpp_class_definition(self, entry, code):
code.mark_pos(entry.pos)
type = entry.type
scope = type.scope
if scope:
kind = type.kind
packed = type.is_cpp_class and type.packed
if packed:
kind = "%s %s" % (type.kind, "__Pyx_PACKED")
code.globalstate.use_utility_code(packed_struct_utility_code)
header, footer = \
self.sue_header_footer(type, kind, type.cname)
code.putln("")
if packed:
code.putln("#if !defined(__GNUC__)")
code.putln("#pragma pack(push, 1)")
code.putln("#endif")
code.putln(header)
var_entries = scope.var_entries
for attr in var_entries:
code.putln(
"%s;" %
attr.type.declaration_code(attr.cname))
code.putln(footer)
if packed:
code.putln("#if !defined(__GNUC__)")
code.putln("#pragma pack(pop)")
code.putln("#endif")
def generate_enum_definition(self, entry, code): def generate_enum_definition(self, entry, code):
code.mark_pos(entry.pos) code.mark_pos(entry.pos)
type = entry.type type = entry.type
......
...@@ -914,18 +914,20 @@ class CppClassNode(CStructOrUnionDefNode): ...@@ -914,18 +914,20 @@ class CppClassNode(CStructOrUnionDefNode):
# name string # name string
# cname string or None # cname string or None
# visibility "public" or "private" # visibility "extern"
# in_pxd boolean # in_pxd boolean
# attributes [CVarDefNode] or None # attributes [CVarDefNode] or None
# entry Entry # entry Entry
# base_classes [string]
# namespace string or None
def analyse_declarations(self, env): def analyse_declarations(self, env):
scope = None scope = None
if self.attributes is not None: if self.attributes is not None:
scope = StructOrUnionScope(self.name) # for now scope = CppClassScope(self.name)
self.entry = env.declare_struct_or_union( self.entry = env.declare_cpp_class(
self.name, "struct", scope, 0, self.pos, self.name, "cppclass", scope, 0, self.pos,
self.cname, visibility = self.visibility) self.cname, self.base_classes, self.namespace, visibility = self.visibility)
if self.attributes is not None: if self.attributes is not None:
if self.in_pxd and not env.in_cinclude: if self.in_pxd and not env.in_cinclude:
self.entry.defined_in_pxd = 1 self.entry.defined_in_pxd = 1
......
...@@ -31,6 +31,7 @@ class Ctx(object): ...@@ -31,6 +31,7 @@ class Ctx(object):
api = 0 api = 0
overridable = 0 overridable = 0
nogil = 0 nogil = 0
namespace = None
def __init__(self, **kwds): def __init__(self, **kwds):
self.__dict__.update(kwds) self.__dict__.update(kwds)
...@@ -2123,7 +2124,7 @@ def p_cdef_extern_block(s, pos, ctx): ...@@ -2123,7 +2124,7 @@ def p_cdef_extern_block(s, pos, ctx):
_, include_file = p_string_literal(s) _, include_file = p_string_literal(s)
if s.systring == "namespace": if s.systring == "namespace":
s.next() s.next()
namespace = p_ident(s) ctx.namespace = p_ident(s)
ctx = ctx(cdef_flag = 1, visibility = 'extern') ctx = ctx(cdef_flag = 1, visibility = 'extern')
if p_nogil(s): if p_nogil(s):
ctx.nogil = 1 ctx.nogil = 1
...@@ -2533,9 +2534,6 @@ def p_module(s, pxd, full_module_name): ...@@ -2533,9 +2534,6 @@ def p_module(s, pxd, full_module_name):
full_module_name = full_module_name, full_module_name = full_module_name,
option_comments = option_comments) option_comments = option_comments)
#Implementing...
def p_cpp_class_definition(s, pos, ctx): def p_cpp_class_definition(s, pos, ctx):
# s.sy == 'cppclass' # s.sy == 'cppclass'
s.next() s.next()
...@@ -2584,15 +2582,12 @@ def p_cpp_class_definition(s, pos, ctx): ...@@ -2584,15 +2582,12 @@ def p_cpp_class_definition(s, pos, ctx):
s.expect_newline("Syntax error in C++ class definition") s.expect_newline("Syntax error in C++ class definition")
return Nodes.CppClassNode(pos, return Nodes.CppClassNode(pos,
name = class_name, name = class_name,
namespace = None,
cname = None, cname = None,
base_classes = base_classes, base_classes = base_classes,
namespace = ctx.namespace,
visibility = ctx.visibility, visibility = ctx.visibility,
in_pxd = ctx.level == 'module_pxd', in_pxd = ctx.level == 'module_pxd',
attributes = None) attributes = attributes)
def p_cpp_class(s):
pass
......
...@@ -91,6 +91,7 @@ class PyrexType(BaseType): ...@@ -91,6 +91,7 @@ class PyrexType(BaseType):
is_null_ptr = 0 is_null_ptr = 0
is_cfunction = 0 is_cfunction = 0
is_struct_or_union = 0 is_struct_or_union = 0
is_cpp_class = 0
is_struct = 0 is_struct = 0
is_enum = 0 is_enum = 0
is_typedef = 0 is_typedef = 0
...@@ -1342,6 +1343,57 @@ class CStructOrUnionType(CType): ...@@ -1342,6 +1343,57 @@ class CStructOrUnionType(CType):
for x in self.scope.var_entries] for x in self.scope.var_entries]
return max(child_depths) + 1 return max(child_depths) + 1
class CppClassType(CType):
# name string
# cname string
# kind string "cppclass"
# scope CppClassScope
# typedef_flag boolean
# packed boolean
is_cpp_class = 1
has_attributes = 1
base_classes = []
namespace = None
def __init__(self, name, kind, scope, typedef_flag, cname, base_classes,
namespace = None, packed=False):
self.name = name
self.cname = cname
self.kind = kind
self.scope = scope
self.typedef_flag = typedef_flag
self.exception_check = True
self._convert_code = None
self.packed = packed
self.base_classes = base_classes
self.namespace = namespace
def declaration_code(self, entity_code, for_display = 0, dll_linkage = None, pyrex = 0):
inherited = ""
for base_class in self.base_classes:
if inherited != "":
inherited += " : public "
inherited += base_class
if base_class != baseclasses[-1]:
inherited += " , "
return "%s%s" % (self.name, inherited)
def is_subclass(self, other_type):
if not base_classes.empty():
for base_class in self.base_classes:
if base_class.is_subclass(other_type):
return 1
return 0
def assignable_from_resolved_type(self, other_type):
if self.same_as_resolved_type(other_type):
return 1
if self.is_subclass(other) or self.same_as(other_type):
return 1
return 0
class CEnumType(CType): class CEnumType(CType):
# name string # name string
# cname string or None # cname string or None
......
...@@ -384,6 +384,32 @@ class Scope(object): ...@@ -384,6 +384,32 @@ class Scope(object):
self.check_for_illegal_incomplete_ctypedef(typedef_flag, pos) self.check_for_illegal_incomplete_ctypedef(typedef_flag, pos)
return entry return entry
def declare_cpp_class(self, name, kind, scope,
typedef_flag, pos, cname = None, base_classes = [], namespace = None,
visibility = 'extern', packed = False):
if visibility != 'extern':
error(pos, "C++ classes may only be extern")
if not entry:
type = PyrexTypes.CppClassType(
name, kind, scope, typedef_flag, cname, base_classes, namespace, packed)
entry = self.declare_type(name, type, pos, cname,
visibility = visibility, defining = scope is not None)
self.sue_entries.append(entry)
else:
if not (entry.is_type and entry.type.is_cpp_class
and entry.type.kind == kind):
warning(pos, "'%s' redeclared " % name, 0)
elif scope and entry.type.scope:
warning(pos, "'%s' already defined (ignoring second definition)" % name, 0)
else:
self.check_previous_typedef_flag(entry, typedef_flag, pos)
if scope:
entry.type.scope = scope
self.type_entries.append(entry)
if not scope and not entry.type.scope:
self.check_for_illegal_incomplete_ctypedef(typedef_flag, pos)
return entry
def check_previous_typedef_flag(self, entry, typedef_flag, pos): def check_previous_typedef_flag(self, entry, typedef_flag, pos):
if typedef_flag != entry.type.typedef_flag: if typedef_flag != entry.type.typedef_flag:
error(pos, "'%s' previously declared using '%s'" % ( error(pos, "'%s' previously declared using '%s'" % (
......
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