Commit 57f327c1 authored by Lisandro Dalcin's avatar Lisandro Dalcin

add compiler directive for user-defined function calling conventions

parent 054826b1
......@@ -530,6 +530,9 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.putln(" #ifndef __cdecl")
code.putln(" #define __cdecl")
code.putln(" #endif")
code.putln(" #ifndef __fastcall")
code.putln(" #define __fastcall")
code.putln(" #endif")
code.putln("#else")
code.putln(" #define _USE_MATH_DEFINES")
code.putln("#endif")
......
......@@ -603,6 +603,13 @@ class CFuncDeclaratorNode(CDeclaratorNode):
nogil = self.nogil, with_gil = self.with_gil, is_overridable = self.overridable)
if self.optional_arg_count:
func_type.op_arg_struct = PyrexTypes.c_ptr_type(self.op_args_struct.type)
callspec = env.directives['callspec']
if callspec:
current = func_type.calling_convention
if current and current != callspec:
error(self.pos, "cannot have both '%s' and '%s' "
"calling conventions" % (current, callspec))
func_type.calling_convention = callspec
return self.base.analyse(func_type, env)
......
......@@ -66,6 +66,7 @@ option_defaults = {
'always_allow_keywords': False,
'wraparound' : True,
'c99_complex' : False, # Don't use macro wrappers for complex arith, not sure what to name this...
'callspec' : "",
}
# Override types possibilities above, if needed
......
......@@ -435,6 +435,11 @@ class InterpretCompilerDirectives(CythonTransform, SkipDeclarations):
raise PostParseError(dec.function.pos,
'The %s option takes one compile-time boolean argument' % optname)
return (optname, args[0].value)
elif optiontype is str:
if kwds is not None or len(args) != 1 or not isinstance(args[0], StringNode):
raise PostParseError(dec.function.pos,
'The %s option takes one compile-time string argument' % optname)
return (optname, args[0].value)
elif optiontype is dict:
if len(args) != 0:
raise PostParseError(dec.function.pos,
......
......@@ -1675,7 +1675,7 @@ def p_calling_convention(s):
else:
return ""
calling_convention_words = ("__stdcall", "__cdecl")
calling_convention_words = ("__stdcall", "__cdecl", "__fastcall")
def p_c_complex_base_type(s):
# s.sy == '('
......
......@@ -1125,6 +1125,15 @@ class CFuncType(CType):
return 1
def same_calling_convention_as(self, other):
## XXX Under discussion ...
## callspec_words = ("__stdcall", "__cdecl", "__fastcall")
## cs1 = self.calling_convention
## cs2 = other.calling_convention
## if (cs1 in callspec_words or
## cs2 in callspec_words):
## return cs1 == cs2
## else:
## return True
sc1 = self.calling_convention == '__stdcall'
sc2 = other.calling_convention == '__stdcall'
return sc1 == sc2
......
cdef extern int f()
cdef extern int f1()
cdef extern int __stdcall g()
cdef extern int __cdecl f2()
cdef extern int __cdecl h()
cdef extern int __stdcall f3()
cdef extern int (__stdcall *p)()
cdef extern int __fastcall f4()
cdef extern int (*p1)()
cdef extern int (__cdecl *p2)()
cdef extern int (__stdcall *p3)()
cdef extern int (__fastcall *p4)()
p1 = f1
p2 = f2
p3 = f3
p4 = f4
cimport cython
@cython.callspec("")
cdef void h1(): pass
@cython.callspec("__cdecl")
cdef void __cdecl h2(): pass
@cython.callspec("__stdcall")
cdef void __stdcall h3(): pass
@cython.callspec("__fastcall")
cdef void __fastcall h4(): pass
@cython.callspec("__cdecl")
cdef void __stdcall h5(): pass # fail
@cython.callspec("__cdecl")
cdef void __fastcall h6(): pass # fail
cdef void (*p1)()
cdef void (__cdecl *p2)()
cdef void (__stdcall *p3)()
cdef void (__fastcall *p4)()
p1 = h1
p2 = h2
p3 = h3
p4 = h4
#p1 = h2 # fail
#p1 = h3 # fail
#p1 = h4 # fail
#p2 = h1 # fail
#p2 = h3 # fail
#p2 = h4 # fail
_ERRORS = u"""
16:22: cannot have both '__stdcall' and '__cdecl' calling conventions
19:23: cannot have both '__fastcall' and '__cdecl' calling conventions
"""
#31:14: Cannot assign type 'void (__cdecl )(void)' to 'void (*)(void)'
#32:14: Cannot assign type 'void (__stdcall )(void)' to 'void (*)(void)'
#33:14: Cannot assign type 'void (__fastcall )(void)' to 'void (*)(void)'
#35:14: Cannot assign type 'void (void)' to 'void (__cdecl *)(void)'
#36:14: Cannot assign type 'void (__stdcall )(void)' to 'void (__cdecl *)(void)'
#37:14: Cannot assign type 'void (__fastcall )(void)' to 'void (__cdecl *)(void)'
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