Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Labels
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Commits
Open sidebar
nexedi
cython
Commits
dd1c4c74
Commit
dd1c4c74
authored
Apr 29, 2019
by
gsamain
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Cypclass constructor wrapper
parent
a845670d
Changes
3
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
300 additions
and
11 deletions
+300
-11
Cython/Compiler/ExprNodes.py
Cython/Compiler/ExprNodes.py
+29
-4
Cython/Compiler/ModuleNode.py
Cython/Compiler/ModuleNode.py
+165
-3
Cython/Compiler/Symtab.py
Cython/Compiler/Symtab.py
+106
-4
No files found.
Cython/Compiler/ExprNodes.py
View file @
dd1c4c74
...
...
@@ -5503,14 +5503,39 @@ class CallNode(ExprNode):
elif
type
and
type
.
is_cpp_class
:
self
.
args
=
[
arg
.
analyse_types
(
env
)
for
arg
in
self
.
args
]
constructor
=
type
.
scope
.
lookup
(
"<init>"
)
if
not
constructor
:
constructor_type
=
None
constructor_cname
=
None
if
type
.
is_cyp_class
:
constructor
=
wrapper
=
type
.
scope
.
lookup_here
(
"<constructor>"
)
if
not
wrapper
:
error
(
self
.
function
.
pos
,
"no constructor wrapper found for Cypclass type '%s'"
%
self
.
function
.
name
)
namespace_list
=
wrapper
.
func_cname
.
split
(
'::'
)
templates
=
''
if
type
.
templates
:
templates
=
'<'
+
','
.
join
([
param
.
declaration_code
(
''
)
for
param
in
type
.
templates
if
not
PyrexTypes
.
is_optional_template_param
(
param
)
and
not
param
.
is_fused
])
+
'>'
if
len
(
namespace_list
)
>
2
:
# We do this because cypclass wrappers are outside of the class namespace
# in the C++ code, but they are declared within the class scope
constructor_cname
=
'::'
.
join
(
namespace_list
[:
-
2
]
+
[
namespace_list
[
-
1
]])
+
templates
else
:
constructor_cname
=
namespace_list
[
-
1
]
+
templates
constructor_type
=
wrapper
.
type
elif
not
constructor
:
error
(
self
.
function
.
pos
,
"no constructor found for C++ type '%s'"
%
self
.
function
.
name
)
self
.
type
=
error_type
return
self
self
.
function
=
RawCNameExprNode
(
self
.
function
.
pos
,
constructor
.
type
)
else
:
constructor_type
=
constructor
.
type
constructor_cname
=
type
.
empty_declaration_code
()
self
.
function
=
RawCNameExprNode
(
self
.
function
.
pos
,
constructor_type
)
self
.
function
.
entry
=
constructor
self
.
function
.
set_cname
(
type
.
empty_declaration_code
()
)
self
.
function
.
set_cname
(
constructor_cname
)
self
.
analyse_c_function_call
(
env
)
if
type
.
is_cyp_class
:
self
.
type
=
constructor_type
.
return_type
else
:
self
.
type
=
type
return
True
...
...
Cython/Compiler/ModuleNode.py
View file @
dd1c4c74
This diff is collapsed.
Click to expand it.
Cython/Compiler/Symtab.py
View file @
dd1c4c74
...
...
@@ -653,7 +653,28 @@ class Scope(object):
if
scope
:
entry
.
type
.
set_scope
(
scope
)
declare_inherited_attributes
(
entry
,
base_classes
)
scope
.
declare_var
(
name
=
"this"
,
cname
=
"this"
,
type
=
PyrexTypes
.
CPtrType
(
entry
.
type
),
pos
=
entry
.
pos
)
this_type
=
PyrexTypes
.
CPtrType
(
entry
.
type
)
if
not
cypclass
else
entry
.
type
scope
.
declare_var
(
name
=
"this"
,
cname
=
"this"
,
type
=
this_type
,
pos
=
entry
.
pos
)
if
cypclass
:
# Declare a shadow default constructor
wrapper_type
=
PyrexTypes
.
CFuncType
(
entry
.
type
,
[],
nogil
=
1
)
wrapper_cname
=
"%s__constructor__%s"
%
(
Naming
.
func_prefix
,
name
)
wrapper_name
=
"<constructor>"
wrapper_entry
=
scope
.
declare
(
wrapper_name
,
wrapper_cname
,
wrapper_type
,
pos
,
visibility
)
wrapper_type
.
entry
=
wrapper_entry
wrapper_entry
.
is_inherited
=
1
wrapper_entry
.
is_cfunction
=
1
wrapper_entry
.
func_cname
=
"%s::%s"
%
(
entry
.
type
.
empty_declaration_code
(),
wrapper_cname
)
# Declare the default __alloc__ method
alloc_type
=
wrapper_type
alloc_cname
=
"%s__alloc__%s"
%
(
Naming
.
func_prefix
,
name
)
alloc_name
=
"<alloc>"
alloc_entry
=
scope
.
declare
(
alloc_name
,
alloc_cname
,
alloc_type
,
pos
,
visibility
)
alloc_type
.
entry
=
alloc_entry
alloc_entry
.
is_cfunction
=
1
alloc_entry
.
func_cname
=
"%s::%s"
%
(
entry
.
type
.
empty_declaration_code
(),
alloc_cname
)
if
self
.
is_cpp_class_scope
:
entry
.
type
.
namespace
=
self
.
outer_scope
.
lookup
(
self
.
name
).
type
return
entry
...
...
@@ -2445,6 +2466,26 @@ class CppClassScope(Scope):
self
.
var_entries
.
append
(
entry
)
return
entry
def
declare_constructor_wrapper
(
self
,
args
,
pos
,
defining
=
0
,
has_varargs
=
0
,
optional_arg_count
=
0
,
op_arg_struct
=
None
,
return_type
=
None
):
if
not
return_type
:
return_type
=
self
.
type
class_type
=
self
.
parent_type
class_name
=
self
.
name
.
split
(
'::'
)[
-
1
]
wrapper_cname
=
"%s__constructor__%s"
%
(
Naming
.
func_prefix
,
class_name
)
wrapper_name
=
"<constructor>"
wrapper_type
=
PyrexTypes
.
CFuncType
(
return_type
,
args
,
nogil
=
1
,
has_varargs
=
has_varargs
,
optional_arg_count
=
optional_arg_count
)
if
op_arg_struct
:
wrapper_type
.
op_arg_struct
=
op_arg_struct
wrapper_entry
=
self
.
declare
(
wrapper_name
,
wrapper_cname
,
wrapper_type
,
pos
,
'extern'
)
wrapper_type
.
entry
=
wrapper_entry
wrapper_entry
.
is_cfunction
=
1
if
defining
:
wrapper_entry
.
func_cname
=
"%s::%s"
%
(
class_type
.
empty_declaration_code
(),
wrapper_cname
)
return
wrapper_entry
def
declare_cfunction
(
self
,
name
,
type
,
pos
,
cname
=
None
,
visibility
=
'extern'
,
api
=
0
,
in_pxd
=
0
,
defining
=
0
,
modifiers
=
(),
utility_code
=
None
,
overridable
=
False
):
...
...
@@ -2457,16 +2498,40 @@ class CppClassScope(Scope):
# arguments that cannot by called by value.
type
.
original_args
=
type
.
args
def
maybe_ref
(
arg
):
if
arg
.
type
.
is_cpp_class
and
not
arg
.
type
.
is_reference
:
if
arg
.
type
.
is_cpp_class
and
not
arg
.
type
.
is_reference
and
not
arg
.
type
.
is_cyp_class
:
return
PyrexTypes
.
CFuncTypeArg
(
arg
.
name
,
PyrexTypes
.
c_ref_type
(
arg
.
type
),
arg
.
pos
)
else
:
return
arg
type
.
args
=
[
maybe_ref
(
arg
)
for
arg
in
type
.
args
]
if
self
.
type
.
is_cyp_class
and
not
self
.
lookup_here
(
"__new__"
):
self
.
declare_constructor_wrapper
(
type
.
args
,
pos
,
defining
,
type
.
has_varargs
,
type
.
optional_arg_count
,
getattr
(
type
,
'op_arg_struct'
,
None
))
elif
name
==
'__dealloc__'
and
cname
is
None
:
cname
=
"%s__dealloc__%s"
%
(
Naming
.
func_prefix
,
class_name
)
name
=
'<del>'
type
.
return_type
=
PyrexTypes
.
c_void_type
elif
name
==
'__alloc__'
and
self
.
type
.
is_cyp_class
:
cname
=
"%s__alloc__%s"
%
(
Naming
.
func_prefix
,
class_name
)
name
=
'<alloc>'
elif
name
==
'__new__'
and
self
.
type
.
is_cyp_class
:
if
name
in
self
.
entries
:
if
self
.
entries
[
name
].
is_inherited
:
del
self
.
entries
[
name
]
else
:
error
(
pos
,
"Couldn't have more than one __new__ function"
)
if
self
.
lookup_here
(
"<constructor>"
):
del
self
.
entries
[
"<constructor>"
]
self
.
declare_constructor_wrapper
(
type
.
args
[
1
:],
pos
,
defining
,
type
.
has_varargs
,
type
.
optional_arg_count
,
getattr
(
type
,
'op_arg_struct'
,
None
),
return_type
=
type
.
return_type
)
type
.
original_alloc_type
=
type
.
args
[
0
]
if
name
in
(
'<init>'
,
'<del>'
)
and
type
.
nogil
:
for
base
in
self
.
type
.
base_classes
:
if
base
is
cy_object_type
:
...
...
@@ -2501,9 +2566,44 @@ class CppClassScope(Scope):
for
base_entry
in
\
base_scope
.
inherited_var_entries
+
base_scope
.
var_entries
:
#constructor/destructor is not inherited
if
base_entry
.
name
in
(
"<init>"
,
"<del>"
):
if
base_entry
.
name
==
"<del>"
\
or
base_entry
.
name
==
"<init>"
and
not
self
.
parent_type
.
is_cyp_class
\
or
base_entry
.
name
in
(
"<constructor>"
,
"<alloc>"
)
and
self
.
parent_type
.
is_cyp_class
:
continue
elif
base_entry
.
name
==
"<init>"
and
not
self
.
lookup_here
(
"__new__"
):
wrapper_entry
=
self
.
declare_constructor_wrapper
(
base_entry_type
.
args
,
base_entry
.
pos
,
defining
=
1
,
has_varargs
=
base_entry_type
.
has_varargs
,
optional_arg_count
=
base_entry_type
.
optional_arg_count
,
op_arg_struct
=
getattr
(
base_entry_type
,
'op_arg_struct'
,
None
),
return_type
=
self
.
parent_type
)
wrapper_entry
.
is_inherited
=
1
#print base_entry.name, self.entries
elif
base_entry
.
name
==
"__new__"
and
self
.
parent_type
.
is_cyp_class
:
# Rewrite first argument for __new__
alloc_type
=
PyrexTypes
.
CPtrType
(
PyrexTypes
.
CFuncType
(
self
.
parent_type
,
[],
nogil
=
1
))
alloc_arg
=
PyrexTypes
.
CFuncTypeArg
(
base_entry
.
type
.
args
[
0
].
name
,
alloc_type
,
base_entry
.
type
.
args
[
0
].
pos
,
cname
=
base_entry
.
type
.
args
[
0
].
cname
)
base_entry_type
=
PyrexTypes
.
CFuncType
(
base_entry_type
.
return_type
,
[
alloc_arg
]
+
base_entry_type
.
args
[
1
:],
nogil
=
1
,
has_varargs
=
base_entry_type
.
has_varargs
,
optional_arg_count
=
base_entry_type
.
optional_arg_count
)
if
hasattr
(
base_entry
.
type
,
'op_arg_struct'
):
base_entry_type
.
op_arg_struct
=
base_entry
.
type
.
op_arg_struct
base_entry_type
.
original_alloc_type
=
base_entry
.
type
.
original_alloc_type
if
base_entry
.
name
in
self
.
entries
:
del
self
.
entries
[
base_entry
.
name
]
del
self
.
entries
[
"<constructor>"
]
elif
"<init>"
in
self
.
entries
:
del
self
.
entries
[
"<constructor>"
]
wrapper_entry
=
self
.
declare_constructor_wrapper
(
base_entry_type
.
args
[
1
:],
base_entry
.
pos
,
defining
=
1
,
has_varargs
=
base_entry_type
.
has_varargs
,
optional_arg_count
=
base_entry_type
.
optional_arg_count
,
op_arg_struct
=
getattr
(
base_entry_type
,
'op_arg_struct'
,
None
),
return_type
=
base_entry_type
.
return_type
)
wrapper_entry
.
is_inherited
=
1
if
base_entry
.
name
in
self
.
entries
:
base_entry
.
name
# FIXME: is there anything to do in this case?
entry
=
self
.
declare
(
base_entry
.
name
,
base_entry
.
cname
,
...
...
@@ -2560,7 +2660,9 @@ class CppClassScope(Scope):
name
=
"<init>"
elif
name
==
"__dealloc__"
:
name
=
"<del>"
return
super
(
CppClassScope
,
self
).
lookup_here
(
name
)
elif
name
==
"__alloc__"
:
name
=
"<alloc>"
return
super
(
CppClassScope
,
self
).
lookup_here
(
name
)
class
PropertyScope
(
Scope
):
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment