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)
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 9.2 +++ b/tests/run/inlinepxd_support.pxd Thu Nov 27 19:29:12 2008 +0100 9.3 @@ -0,0 +1,3 @@ 9.4 + 9.5 +cdef inline int my_add(int a, int b, int c): 9.6 + return a + b + c