cython-devel
changeset 1409:151d8366f329
Inline function definitions in pxd files
| author | Dag Sverre Seljebotn <dagss@student.matnat.uio.no> |
|---|---|
| date | Thu Nov 27 19:29:12 2008 +0100 (4 years ago) |
| parents | bfd2c54fbe62 |
| children | 18b01615d799 |
| files | Cython/Compiler/ModuleNode.py Cython/Compiler/Nodes.py Cython/Compiler/ParseTreeTransforms.py Cython/Compiler/Symtab.py tests/errors/e_func_in_pxd.pyx tests/errors/e_func_in_pxd_support.pxd tests/run/inlinepxd.pxd tests/run/inlinepxd.pyx tests/run/inlinepxd_support.pxd |
line diff
1.1 --- a/Cython/Compiler/ModuleNode.py Thu Nov 27 17:54:26 2008 +0100
1.2 +++ b/Cython/Compiler/ModuleNode.py Thu Nov 27 19:29:12 2008 +0100
1.3 @@ -757,8 +757,8 @@
1.4
1.5 def generate_cfunction_predeclarations(self, env, code, definition):
1.6 for entry in env.cfunc_entries:
1.7 - if not entry.in_cinclude and (definition
1.8 - or entry.defined_in_pxd or entry.visibility == 'extern'):
1.9 + if entry.inline_func_in_pxd or (not entry.in_cinclude and (definition
1.10 + or entry.defined_in_pxd or entry.visibility == 'extern')):
1.11 if entry.visibility in ('public', 'extern'):
1.12 dll_linkage = "DL_EXPORT"
1.13 else:
2.1 --- a/Cython/Compiler/Nodes.py Thu Nov 27 17:54:26 2008 +0100
2.2 +++ b/Cython/Compiler/Nodes.py Thu Nov 27 19:29:12 2008 +0100
2.3 @@ -1212,9 +1212,12 @@
2.4 # type CFuncType
2.5 # py_func wrapper for calling from Python
2.6 # overridable whether or not this is a cpdef function
2.7 + # inline_in_pxd whether this is an inline function in a pxd file
2.8
2.9 child_attrs = ["base_type", "declarator", "body", "py_func"]
2.10 -
2.11 +
2.12 + inline_in_pxd = False
2.13 +
2.14 def unqualified_name(self):
2.15 return self.entry.name
2.16
2.17 @@ -1251,6 +1254,7 @@
2.18 cname = cname, visibility = self.visibility,
2.19 defining = self.body is not None,
2.20 api = self.api, modifiers = self.modifiers)
2.21 + self.entry.inline_func_in_pxd = self.inline_in_pxd
2.22 self.return_type = type.return_type
2.23
2.24 if self.overridable:
3.1 --- a/Cython/Compiler/ParseTreeTransforms.py Thu Nov 27 17:54:26 2008 +0100
3.2 +++ b/Cython/Compiler/ParseTreeTransforms.py Thu Nov 27 19:29:12 2008 +0100
3.3 @@ -212,8 +212,12 @@
3.4
3.5 - "def" functions are let through only if they fill the
3.6 getbuffer/releasebuffer slots
3.7 +
3.8 + - cdef functions are let through only if they are on the
3.9 + top level and are declared "inline"
3.10 """
3.11 - ERR_FUNCDEF_NOT_ALLOWED = 'function definition not allowed here'
3.12 + ERR_INLINE_ONLY = "function definition in pxd file must be declared 'cdef inline'"
3.13 + ERR_NOGO_WITH_INLINE = "inline function definition in pxd file cannot be '%s'"
3.14
3.15 def __call__(self, node):
3.16 self.scope_type = 'pxd'
3.17 @@ -229,30 +233,37 @@
3.18 def visit_FuncDefNode(self, node):
3.19 # FuncDefNode always come with an implementation (without
3.20 # an imp they are CVarDefNodes..)
3.21 - ok = False
3.22 + err = self.ERR_INLINE_ONLY
3.23
3.24 if (isinstance(node, DefNode) and self.scope_type == 'cclass'
3.25 and node.name in ('__getbuffer__', '__releasebuffer__')):
3.26 - ok = True
3.27 + err = None # allow these slots
3.28
3.29 if isinstance(node, CFuncDefNode):
3.30 - ok = True
3.31 - for stat in node.body.stats:
3.32 - if not isinstance(stat, CVarDefNode):
3.33 - ok = False
3.34 - break
3.35 - node = CVarDefNode(node.pos,
3.36 - visibility = node.visibility,
3.37 - base_type = node.base_type,
3.38 - declarators = [node.declarator],
3.39 - in_pxd = True,
3.40 - api = node.api,
3.41 - overridable = node.overridable,
3.42 - pxd_locals = node.body.stats)
3.43 -
3.44 - if not ok:
3.45 - self.context.nonfatal_error(PostParseError(node.pos,
3.46 - self.ERR_FUNCDEF_NOT_ALLOWED))
3.47 + if u'inline' in node.modifiers and self.scope_type == 'pxd':
3.48 + node.inline_in_pxd = True
3.49 + if node.visibility != 'private':
3.50 + err = self.ERR_NOGO_WITH_INLINE % node.visibility
3.51 + elif node.api:
3.52 + err = self.ERR_NOGO_WITH_INLINE % 'api'
3.53 + else:
3.54 + err = None # allow inline function
3.55 + else:
3.56 + err = None
3.57 + for stat in node.body.stats:
3.58 + if not isinstance(stat, CVarDefNode):
3.59 + err = self.ERR_INLINE_ONLY
3.60 + break
3.61 + node = CVarDefNode(node.pos,
3.62 + visibility = node.visibility,
3.63 + base_type = node.base_type,
3.64 + declarators = [node.declarator],
3.65 + in_pxd = True,
3.66 + api = node.api,
3.67 + overridable = node.overridable,
3.68 + pxd_locals = node.body.stats)
3.69 + if err:
3.70 + self.context.nonfatal_error(PostParseError(node.pos, err))
3.71 return None
3.72 else:
3.73 return node
4.1 --- a/Cython/Compiler/Symtab.py Thu Nov 27 17:54:26 2008 +0100
4.2 +++ b/Cython/Compiler/Symtab.py Thu Nov 27 19:29:12 2008 +0100
4.3 @@ -97,7 +97,10 @@
4.4 # utility_code string Utility code needed when this entry is used
4.5 #
4.6 # buffer_aux BufferAux or None Extra information needed for buffer variables
4.7 + # inline_func_in_pxd boolean Hacky special case for inline function in pxd file.
4.8 + # Ideally this should not be necesarry.
4.9
4.10 + inline_func_in_pxd = False
4.11 borrowed = 0
4.12 init = ""
4.13 visibility = 'private'
5.1 --- a/tests/errors/e_func_in_pxd.pyx Thu Nov 27 17:54:26 2008 +0100
5.2 +++ b/tests/errors/e_func_in_pxd.pyx Thu Nov 27 19:29:12 2008 +0100
5.3 @@ -1,5 +1,7 @@
5.4 cimport e_func_in_pxd_support
5.5
5.6 _ERRORS = u"""
5.7 -1:5: function definition not allowed here
5.8 +1:5: function definition in pxd file must be declared 'cdef inline'
5.9 +4:5: inline function definition in pxd file cannot be 'public'
5.10 +7:5: inline function definition in pxd file cannot be 'api'
5.11 """
6.1 --- a/tests/errors/e_func_in_pxd_support.pxd Thu Nov 27 17:54:26 2008 +0100
6.2 +++ b/tests/errors/e_func_in_pxd_support.pxd Thu Nov 27 19:29:12 2008 +0100
6.3 @@ -1,2 +1,8 @@
6.4 cdef foo():
6.5 return 1
6.6 +
6.7 +cdef public inline foo2():
6.8 + return 1
6.9 +
6.10 +cdef api inline foo3():
6.11 + return 1
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
7.2 +++ b/tests/run/inlinepxd.pxd Thu Nov 27 19:29:12 2008 +0100
7.3 @@ -0,0 +1,3 @@
7.4 +
7.5 +cdef inline int my_add(int a, int b):
7.6 + return a + b
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
8.2 +++ b/tests/run/inlinepxd.pyx Thu Nov 27 19:29:12 2008 +0100
8.3 @@ -0,0 +1,20 @@
8.4 +"""
8.5 +>>> f()
8.6 +3
8.7 +>>> g()
8.8 +6
8.9 +>>> h()
8.10 +6
8.11 +"""
8.12 +
8.13 +cimport inlinepxd_support
8.14 +from inlinepxd_support cimport my_add as my_add3
8.15 +
8.16 +def f():
8.17 + return my_add(1, 2)
8.18 +
8.19 +def g():
8.20 + return inlinepxd_support.my_add(1, 2, 3)
8.21 +
8.22 +def h():
8.23 + return my_add3(1, 2, 3)
