From 7505ac6d439e92c809fccae007782f68b3618f24 Mon Sep 17 00:00:00 2001 From: Nikita Nemkin Date: Thu, 4 Apr 2013 10:21:01 +0600 Subject: [PATCH] Allow function pointer typedefs with calling convention specified. --- Cython/Compiler/Parsing.py | 3 ++- tests/errors/e_callspec.pyx | 61 +++++++++++++++++++++++++++++++++++++++------ 2 files changed, 55 insertions(+), 9 deletions(-) diff --git a/Cython/Compiler/Parsing.py b/Cython/Compiler/Parsing.py index dd665e2..e3e57fb 100644 --- a/Cython/Compiler/Parsing.py +++ b/Cython/Compiler/Parsing.py @@ -2074,7 +2074,8 @@ def p_c_simple_base_type(s, self_flag, nonempty, templates = None): # Make sure this is not a declaration of a variable or function. if s.sy == '(': s.next() - if s.sy == '*' or s.sy == '**' or s.sy == '&': + if (s.sy == '*' or s.sy == '**' or s.sy == '&' + or (s.sy == 'IDENT' and s.systring in calling_convention_words)): s.put_back('(', '(') else: s.put_back('(', '(') diff --git a/tests/errors/e_callspec.pyx b/tests/errors/e_callspec.pyx index cd02e6c..4510a9c 100644 --- a/tests/errors/e_callspec.pyx +++ b/tests/errors/e_callspec.pyx @@ -2,6 +2,10 @@ cimport cython +ctypedef int USERTYPE + +# Functions + @cython.callspec("") cdef void h1(): pass @@ -14,21 +18,62 @@ cdef void __stdcall h3(): pass @cython.callspec("__fastcall") cdef void __fastcall h4(): pass +cdef USERTYPE h5(): return 0 + +cdef USERTYPE __cdecl h6(): return 0 + +cdef USERTYPE __stdcall h7(): return 0 + +cdef USERTYPE __fastcall h8(): return 0 + @cython.callspec("__cdecl") -cdef void __stdcall h5(): pass # fail +cdef void __stdcall herr1(): pass # fail @cython.callspec("__cdecl") -cdef void __fastcall h6(): pass # fail +cdef void __fastcall herr2(): pass # fail + +# Pointer typedefs + +ctypedef void (*PT1)() +ctypedef void (__cdecl *PT2)() +ctypedef void (__stdcall *PT3)() +ctypedef void (__fastcall *PT4)() +ctypedef USERTYPE (*PT5)() +ctypedef USERTYPE (__cdecl *PT6)() +ctypedef USERTYPE (__stdcall *PT7)() +ctypedef USERTYPE (__fastcall *PT8)() + +# Pointers cdef void (*p1)() cdef void (__cdecl *p2)() cdef void (__stdcall *p3)() cdef void (__fastcall *p4)() +cdef USERTYPE (*p5)() +cdef USERTYPE (__cdecl *p6)() +cdef USERTYPE (__stdcall *p7)() +cdef USERTYPE (__fastcall *p8)() + +cdef PT1 pt1 +cdef PT2 pt2 +cdef PT3 pt3 +cdef PT4 pt4 +cdef PT5 pt5 +cdef PT6 pt6 +cdef PT7 pt7 +cdef PT8 pt8 + +# Assignments + +p1 = pt1 = p2 = pt2 = h1 +p1 = pt1 = p2 = pt2 = h2 +p3 = pt3 = h3 +p4 = pt4 = h4 -p1 = h1 -p2 = h2 -p3 = h3 -p4 = h4 +p5 = pt5 = p6 = pt6 = h5 +p5 = pt5 = p6 = pt6 = h6 +p7 = pt7 = h7 +p8 = pt8 = h8 #p1 = h2 # fail #p1 = h3 # fail @@ -39,8 +84,8 @@ p4 = h4 #p2 = h4 # fail _ERRORS = u""" -18:22: cannot have both '__stdcall' and '__cdecl' calling conventions -21:23: cannot have both '__fastcall' and '__cdecl' calling conventions +30:25: cannot have both '__stdcall' and '__cdecl' calling conventions +33:26: 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)' -- 2.7.4