]> granicus.if.org Git - php/commitdiff
Fixed bug #78714 (funcs returning pointer can't use call convention spec)
authorDmitry Stogov <dmitry@zend.com>
Mon, 11 Nov 2019 09:07:48 +0000 (12:07 +0300)
committerDmitry Stogov <dmitry@zend.com>
Mon, 11 Nov 2019 09:07:48 +0000 (12:07 +0300)
NEWS
ext/ffi/ffi.g
ext/ffi/ffi_parser.c
ext/ffi/tests/bug78714.phpt [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index f0247cbead06e534c2326157c75fc490f2f7525b..740abaa4214b411d3e509d0bfe93be00c7fa3d9c 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -6,6 +6,10 @@ PHP                                                                        NEWS
   . Fixed bug #78768 (redefinition of typedef zend_property_info). (Nikita)
   . Fixed bug #78788 (./configure generates invalid php_version.h). (max)
 
+- FFI:
+  . Fixed bug #78714 (funcs returning pointer can't use call convention spec).
+    (Dmitry)
+
 - Standard:
   . Fixed bug #77930 (stream_copy_to_stream should use mmap more often).
     (Nikita)
index a79eb8cef60a0412e043172dc080ac396cc8cf40..68c002df844e541e11e09bca7c613ce42613ba92 100644 (file)
@@ -127,16 +127,6 @@ declaration_specifiers(zend_ffi_dcl *dcl):
                        {dcl->flags |= ZEND_FFI_DCL_INLINE;}
                |       "_Noreturn"
                        {dcl->flags |= ZEND_FFI_DCL_NO_RETURN;}
-               |       "__cdecl"
-                       {zend_ffi_set_abi(dcl, ZEND_FFI_ABI_CDECL);}
-               |       "__stdcall"
-                       {zend_ffi_set_abi(dcl, ZEND_FFI_ABI_STDCALL);}
-               |       "__fastcall"
-                       {zend_ffi_set_abi(dcl, ZEND_FFI_ABI_FASTCALL);}
-               |       "__thiscall"
-                       {zend_ffi_set_abi(dcl, ZEND_FFI_ABI_THISCALL);}
-               |       "__vectorcall"
-                       {zend_ffi_set_abi(dcl, ZEND_FFI_ABI_VECTORCALL);}
                |       "_Alignas"
                        "("
                        (       &type_name_start
@@ -494,6 +484,16 @@ attributes(zend_ffi_dcl *dcl):
                                )?
                        )+
                ")"
+       |       "__cdecl"
+               {zend_ffi_set_abi(dcl, ZEND_FFI_ABI_CDECL);}
+       |       "__stdcall"
+               {zend_ffi_set_abi(dcl, ZEND_FFI_ABI_STDCALL);}
+       |       "__fastcall"
+               {zend_ffi_set_abi(dcl, ZEND_FFI_ABI_FASTCALL);}
+       |       "__thiscall"
+               {zend_ffi_set_abi(dcl, ZEND_FFI_ABI_THISCALL);}
+       |       "__vectorcall"
+               {zend_ffi_set_abi(dcl, ZEND_FFI_ABI_VECTORCALL);}
        )++
 ;
 
index 263197e0f1f7d4e0b2e12bedd78cf7398549c9a4..efb0cf96ca84c53a7c8311c6eab3e73c04db6ca8 100644 (file)
@@ -56,50 +56,50 @@ static void yy_error_sym(const char *msg, int sym);
 #define YY___INLINE 13
 #define YY___INLINE__ 14
 #define YY__NORETURN 15
-#define YY___CDECL 16
-#define YY___STDCALL 17
-#define YY___FASTCALL 18
-#define YY___THISCALL 19
-#define YY___VECTORCALL 20
-#define YY__ALIGNAS 21
-#define YY_CONST 22
-#define YY___CONST 23
-#define YY___CONST__ 24
-#define YY_RESTRICT 25
-#define YY___RESTRICT 26
-#define YY___RESTRICT__ 27
-#define YY_VOLATILE 28
-#define YY___VOLATILE 29
-#define YY___VOLATILE__ 30
-#define YY__ATOMIC 31
-#define YY_VOID 32
-#define YY_CHAR 33
-#define YY_SHORT 34
-#define YY_INT 35
-#define YY_LONG 36
-#define YY_FLOAT 37
-#define YY_DOUBLE 38
-#define YY_SIGNED 39
-#define YY_UNSIGNED 40
-#define YY__BOOL 41
-#define YY__COMPLEX 42
-#define YY_COMPLEX 43
-#define YY___COMPLEX 44
-#define YY___COMPLEX__ 45
-#define YY_STRUCT 46
-#define YY_UNION 47
-#define YY__LBRACE 48
-#define YY__RBRACE 49
-#define YY__COLON 50
-#define YY_ENUM 51
-#define YY__EQUAL 52
-#define YY__STAR 53
-#define YY__LBRACK 54
-#define YY__RBRACK 55
-#define YY__POINT_POINT_POINT 56
-#define YY___ATTRIBUTE 57
-#define YY___ATTRIBUTE__ 58
-#define YY___DECLSPEC 59
+#define YY__ALIGNAS 16
+#define YY_CONST 17
+#define YY___CONST 18
+#define YY___CONST__ 19
+#define YY_RESTRICT 20
+#define YY___RESTRICT 21
+#define YY___RESTRICT__ 22
+#define YY_VOLATILE 23
+#define YY___VOLATILE 24
+#define YY___VOLATILE__ 25
+#define YY__ATOMIC 26
+#define YY_VOID 27
+#define YY_CHAR 28
+#define YY_SHORT 29
+#define YY_INT 30
+#define YY_LONG 31
+#define YY_FLOAT 32
+#define YY_DOUBLE 33
+#define YY_SIGNED 34
+#define YY_UNSIGNED 35
+#define YY__BOOL 36
+#define YY__COMPLEX 37
+#define YY_COMPLEX 38
+#define YY___COMPLEX 39
+#define YY___COMPLEX__ 40
+#define YY_STRUCT 41
+#define YY_UNION 42
+#define YY__LBRACE 43
+#define YY__RBRACE 44
+#define YY__COLON 45
+#define YY_ENUM 46
+#define YY__EQUAL 47
+#define YY__STAR 48
+#define YY__LBRACK 49
+#define YY__RBRACK 50
+#define YY__POINT_POINT_POINT 51
+#define YY___ATTRIBUTE 52
+#define YY___ATTRIBUTE__ 53
+#define YY___DECLSPEC 54
+#define YY___CDECL 55
+#define YY___STDCALL 56
+#define YY___FASTCALL 57
+#define YY___THISCALL 58
+#define YY___VECTORCALL 59
 #define YY__POINT 60
 #define YY__QUERY 61
 #define YY__BAR_BAR 62
@@ -158,11 +158,6 @@ static const char * sym_name[] = {
        "__inline",
        "__inline__",
        "_Noreturn",
-       "__cdecl",
-       "__stdcall",
-       "__fastcall",
-       "__thiscall",
-       "__vectorcall",
        "_Alignas",
        "const",
        "__const",
@@ -202,6 +197,11 @@ static const char * sym_name[] = {
        "__attribute",
        "__attribute__",
        "__declspec",
+       "__cdecl",
+       "__stdcall",
+       "__fastcall",
+       "__thiscall",
+       "__vectorcall",
        ".",
        "?",
        "||",
@@ -369,6 +369,58 @@ _yy_state_start:
                                                        if (ch != '_') goto _yy_tunnel_9;
                                                        ret = YY___INLINE__;
                                                        goto _yy_state_390;
+                                               case 'a':
+                                                       ch = *++YYPOS;
+                                                       if (ch == 'l') {
+                                                               ch = *++YYPOS;
+                                                               if (ch != 'i') goto _yy_tunnel_9;
+                                                               ch = *++YYPOS;
+                                                               if (ch != 'g') goto _yy_tunnel_9;
+                                                               ch = *++YYPOS;
+                                                               if (ch != 'n') goto _yy_tunnel_9;
+                                                               ch = *++YYPOS;
+                                                               if (ch != 'o') goto _yy_tunnel_9;
+                                                               ch = *++YYPOS;
+                                                               if (ch != 'f') goto _yy_tunnel_9;
+                                                               ch = *++YYPOS;
+                                                               if (ch != '_') {ret = YY___ALIGNOF; goto _yy_tunnel_390;}
+                                                               ch = *++YYPOS;
+                                                               if (ch != '_') goto _yy_tunnel_9;
+                                                               ret = YY___ALIGNOF__;
+                                                               goto _yy_state_390;
+                                                       } else if (ch == 's') {
+                                                               ch = *++YYPOS;
+                                                               if (ch != 'm') goto _yy_tunnel_9;
+                                                               ch = *++YYPOS;
+                                                               if (ch != '_') goto _yy_tunnel_9;
+                                                               ch = *++YYPOS;
+                                                               if (ch != '_') goto _yy_tunnel_9;
+                                                               ret = YY___ASM__;
+                                                               goto _yy_state_390;
+                                                       } else if (ch == 't') {
+                                                               ch = *++YYPOS;
+                                                               if (ch != 't') goto _yy_tunnel_9;
+                                                               ch = *++YYPOS;
+                                                               if (ch != 'r') goto _yy_tunnel_9;
+                                                               ch = *++YYPOS;
+                                                               if (ch != 'i') goto _yy_tunnel_9;
+                                                               ch = *++YYPOS;
+                                                               if (ch != 'b') goto _yy_tunnel_9;
+                                                               ch = *++YYPOS;
+                                                               if (ch != 'u') goto _yy_tunnel_9;
+                                                               ch = *++YYPOS;
+                                                               if (ch != 't') goto _yy_tunnel_9;
+                                                               ch = *++YYPOS;
+                                                               if (ch != 'e') goto _yy_tunnel_9;
+                                                               ch = *++YYPOS;
+                                                               if (ch != '_') {ret = YY___ATTRIBUTE; goto _yy_tunnel_390;}
+                                                               ch = *++YYPOS;
+                                                               if (ch != '_') goto _yy_tunnel_9;
+                                                               ret = YY___ATTRIBUTE__;
+                                                               goto _yy_state_390;
+                                                       } else {
+                                                               goto _yy_tunnel_9;
+                                                       }
                                                case 'c':
                                                        ch = *++YYPOS;
                                                        if (ch == 'd') {
@@ -414,11 +466,30 @@ _yy_state_start:
                                                        } else {
                                                                goto _yy_tunnel_9;
                                                        }
-                                               case 's':
+                                               case 'd':
                                                        ch = *++YYPOS;
-                                                       if (ch != 't') goto _yy_tunnel_9;
+                                                       if (ch != 'e') goto _yy_tunnel_9;
                                                        ch = *++YYPOS;
-                                                       if (ch != 'd') goto _yy_tunnel_9;
+                                                       if (ch != 'c') goto _yy_tunnel_9;
+                                                       ch = *++YYPOS;
+                                                       if (ch != 'l') goto _yy_tunnel_9;
+                                                       ch = *++YYPOS;
+                                                       if (ch != 's') goto _yy_tunnel_9;
+                                                       ch = *++YYPOS;
+                                                       if (ch != 'p') goto _yy_tunnel_9;
+                                                       ch = *++YYPOS;
+                                                       if (ch != 'e') goto _yy_tunnel_9;
+                                                       ch = *++YYPOS;
+                                                       if (ch != 'c') goto _yy_tunnel_9;
+                                                       ret = YY___DECLSPEC;
+                                                       goto _yy_state_390;
+                                               case 'f':
+                                                       ch = *++YYPOS;
+                                                       if (ch != 'a') goto _yy_tunnel_9;
+                                                       ch = *++YYPOS;
+                                                       if (ch != 's') goto _yy_tunnel_9;
+                                                       ch = *++YYPOS;
+                                                       if (ch != 't') goto _yy_tunnel_9;
                                                        ch = *++YYPOS;
                                                        if (ch != 'c') goto _yy_tunnel_9;
                                                        ch = *++YYPOS;
@@ -427,16 +498,45 @@ _yy_state_start:
                                                        if (ch != 'l') goto _yy_tunnel_9;
                                                        ch = *++YYPOS;
                                                        if (ch != 'l') goto _yy_tunnel_9;
-                                                       ret = YY___STDCALL;
+                                                       ret = YY___FASTCALL;
                                                        goto _yy_state_390;
-                                               case 'f':
+                                               case 'r':
                                                        ch = *++YYPOS;
-                                                       if (ch != 'a') goto _yy_tunnel_9;
+                                                       if (ch != 'e') goto _yy_tunnel_9;
                                                        ch = *++YYPOS;
                                                        if (ch != 's') goto _yy_tunnel_9;
                                                        ch = *++YYPOS;
                                                        if (ch != 't') goto _yy_tunnel_9;
                                                        ch = *++YYPOS;
+                                                       if (ch == 'i') {
+                                                               ch = *++YYPOS;
+                                                               if (ch != 'c') goto _yy_tunnel_9;
+                                                               ch = *++YYPOS;
+                                                               if (ch != 't') goto _yy_tunnel_9;
+                                                               ret = YY___RESTICT;
+                                                               goto _yy_state_390;
+                                                       } else if (ch == 'r') {
+                                                               ch = *++YYPOS;
+                                                               if (ch != 'i') goto _yy_tunnel_9;
+                                                               ch = *++YYPOS;
+                                                               if (ch != 'c') goto _yy_tunnel_9;
+                                                               ch = *++YYPOS;
+                                                               if (ch != 't') goto _yy_tunnel_9;
+                                                               ch = *++YYPOS;
+                                                               if (ch != '_') {ret = YY___RESTRICT; goto _yy_tunnel_390;}
+                                                               ch = *++YYPOS;
+                                                               if (ch != '_') goto _yy_tunnel_9;
+                                                               ret = YY___RESTRICT__;
+                                                               goto _yy_state_390;
+                                                       } else {
+                                                               goto _yy_tunnel_9;
+                                                       }
+                                               case 's':
+                                                       ch = *++YYPOS;
+                                                       if (ch != 't') goto _yy_tunnel_9;
+                                                       ch = *++YYPOS;
+                                                       if (ch != 'd') goto _yy_tunnel_9;
+                                                       ch = *++YYPOS;
                                                        if (ch != 'c') goto _yy_tunnel_9;
                                                        ch = *++YYPOS;
                                                        if (ch != 'a') goto _yy_tunnel_9;
@@ -444,7 +544,7 @@ _yy_state_start:
                                                        if (ch != 'l') goto _yy_tunnel_9;
                                                        ch = *++YYPOS;
                                                        if (ch != 'l') goto _yy_tunnel_9;
-                                                       ret = YY___FASTCALL;
+                                                       ret = YY___STDCALL;
                                                        goto _yy_state_390;
                                                case 't':
                                                        ch = *++YYPOS;
@@ -506,106 +606,6 @@ _yy_state_start:
                                                        } else {
                                                                goto _yy_tunnel_9;
                                                        }
-                                               case 'a':
-                                                       ch = *++YYPOS;
-                                                       if (ch == 'l') {
-                                                               ch = *++YYPOS;
-                                                               if (ch != 'i') goto _yy_tunnel_9;
-                                                               ch = *++YYPOS;
-                                                               if (ch != 'g') goto _yy_tunnel_9;
-                                                               ch = *++YYPOS;
-                                                               if (ch != 'n') goto _yy_tunnel_9;
-                                                               ch = *++YYPOS;
-                                                               if (ch != 'o') goto _yy_tunnel_9;
-                                                               ch = *++YYPOS;
-                                                               if (ch != 'f') goto _yy_tunnel_9;
-                                                               ch = *++YYPOS;
-                                                               if (ch != '_') {ret = YY___ALIGNOF; goto _yy_tunnel_390;}
-                                                               ch = *++YYPOS;
-                                                               if (ch != '_') goto _yy_tunnel_9;
-                                                               ret = YY___ALIGNOF__;
-                                                               goto _yy_state_390;
-                                                       } else if (ch == 's') {
-                                                               ch = *++YYPOS;
-                                                               if (ch != 'm') goto _yy_tunnel_9;
-                                                               ch = *++YYPOS;
-                                                               if (ch != '_') goto _yy_tunnel_9;
-                                                               ch = *++YYPOS;
-                                                               if (ch != '_') goto _yy_tunnel_9;
-                                                               ret = YY___ASM__;
-                                                               goto _yy_state_390;
-                                                       } else if (ch == 't') {
-                                                               ch = *++YYPOS;
-                                                               if (ch != 't') goto _yy_tunnel_9;
-                                                               ch = *++YYPOS;
-                                                               if (ch != 'r') goto _yy_tunnel_9;
-                                                               ch = *++YYPOS;
-                                                               if (ch != 'i') goto _yy_tunnel_9;
-                                                               ch = *++YYPOS;
-                                                               if (ch != 'b') goto _yy_tunnel_9;
-                                                               ch = *++YYPOS;
-                                                               if (ch != 'u') goto _yy_tunnel_9;
-                                                               ch = *++YYPOS;
-                                                               if (ch != 't') goto _yy_tunnel_9;
-                                                               ch = *++YYPOS;
-                                                               if (ch != 'e') goto _yy_tunnel_9;
-                                                               ch = *++YYPOS;
-                                                               if (ch != '_') {ret = YY___ATTRIBUTE; goto _yy_tunnel_390;}
-                                                               ch = *++YYPOS;
-                                                               if (ch != '_') goto _yy_tunnel_9;
-                                                               ret = YY___ATTRIBUTE__;
-                                                               goto _yy_state_390;
-                                                       } else {
-                                                               goto _yy_tunnel_9;
-                                                       }
-                                               case 'd':
-                                                       ch = *++YYPOS;
-                                                       if (ch != 'e') goto _yy_tunnel_9;
-                                                       ch = *++YYPOS;
-                                                       if (ch != 'c') goto _yy_tunnel_9;
-                                                       ch = *++YYPOS;
-                                                       if (ch != 'l') goto _yy_tunnel_9;
-                                                       ch = *++YYPOS;
-                                                       if (ch != 's') goto _yy_tunnel_9;
-                                                       ch = *++YYPOS;
-                                                       if (ch != 'p') goto _yy_tunnel_9;
-                                                       ch = *++YYPOS;
-                                                       if (ch != 'e') goto _yy_tunnel_9;
-                                                       ch = *++YYPOS;
-                                                       if (ch != 'c') goto _yy_tunnel_9;
-                                                       ret = YY___DECLSPEC;
-                                                       goto _yy_state_390;
-                                               case 'r':
-                                                       ch = *++YYPOS;
-                                                       if (ch != 'e') goto _yy_tunnel_9;
-                                                       ch = *++YYPOS;
-                                                       if (ch != 's') goto _yy_tunnel_9;
-                                                       ch = *++YYPOS;
-                                                       if (ch != 't') goto _yy_tunnel_9;
-                                                       ch = *++YYPOS;
-                                                       if (ch == 'i') {
-                                                               ch = *++YYPOS;
-                                                               if (ch != 'c') goto _yy_tunnel_9;
-                                                               ch = *++YYPOS;
-                                                               if (ch != 't') goto _yy_tunnel_9;
-                                                               ret = YY___RESTICT;
-                                                               goto _yy_state_390;
-                                                       } else if (ch == 'r') {
-                                                               ch = *++YYPOS;
-                                                               if (ch != 'i') goto _yy_tunnel_9;
-                                                               ch = *++YYPOS;
-                                                               if (ch != 'c') goto _yy_tunnel_9;
-                                                               ch = *++YYPOS;
-                                                               if (ch != 't') goto _yy_tunnel_9;
-                                                               ch = *++YYPOS;
-                                                               if (ch != '_') {ret = YY___RESTRICT; goto _yy_tunnel_390;}
-                                                               ch = *++YYPOS;
-                                                               if (ch != '_') goto _yy_tunnel_9;
-                                                               ret = YY___RESTRICT__;
-                                                               goto _yy_state_390;
-                                                       } else {
-                                                               goto _yy_tunnel_9;
-                                                       }
                                                default:
                                                        goto _yy_tunnel_9;
                                        }
@@ -2012,7 +2012,7 @@ static int synpred_6(int sym) {
 }
 
 static int parse_declarations(int sym) {
-       while (YY_IN_SET(sym, (YY___EXTENSION__,YY_TYPEDEF,YY_EXTERN,YY_STATIC,YY_AUTO,YY_REGISTER,YY_INLINE,YY___INLINE,YY___INLINE__,YY__NORETURN,YY___CDECL,YY___STDCALL,YY___FASTCALL,YY___THISCALL,YY___VECTORCALL,YY__ALIGNAS,YY___ATTRIBUTE,YY___ATTRIBUTE__,YY___DECLSPEC,YY_CONST,YY___CONST,YY___CONST__,YY_RESTRICT,YY___RESTRICT,YY___RESTRICT__,YY_VOLATILE,YY___VOLATILE,YY___VOLATILE__,YY__ATOMIC,YY_VOID,YY_CHAR,YY_SHORT,YY_INT,YY_LONG,YY_FLOAT,YY_DOUBLE,YY_SIGNED,YY_UNSIGNED,YY__BOOL,YY__COMPLEX,YY_COMPLEX,YY___COMPLEX,YY___COMPLEX__,YY_STRUCT,YY_UNION,YY_ENUM,YY_ID), "\202\377\377\377\377\377\010\016\000\000\000\002\000")) {
+       while (YY_IN_SET(sym, (YY___EXTENSION__,YY_TYPEDEF,YY_EXTERN,YY_STATIC,YY_AUTO,YY_REGISTER,YY_INLINE,YY___INLINE,YY___INLINE__,YY__NORETURN,YY__ALIGNAS,YY___ATTRIBUTE,YY___ATTRIBUTE__,YY___DECLSPEC,YY___CDECL,YY___STDCALL,YY___FASTCALL,YY___THISCALL,YY___VECTORCALL,YY_CONST,YY___CONST,YY___CONST__,YY_RESTRICT,YY___RESTRICT,YY___RESTRICT__,YY_VOLATILE,YY___VOLATILE,YY___VOLATILE__,YY__ATOMIC,YY_VOID,YY_CHAR,YY_SHORT,YY_INT,YY_LONG,YY_FLOAT,YY_DOUBLE,YY_SIGNED,YY_UNSIGNED,YY__BOOL,YY__COMPLEX,YY_COMPLEX,YY___COMPLEX,YY___COMPLEX__,YY_STRUCT,YY_UNION,YY_ENUM,YY_ID), "\202\377\377\377\377\107\360\017\000\000\000\002\000")) {
                zend_ffi_dcl common_dcl = ZEND_FFI_ATTR_INIT;
                if (sym == YY___EXTENSION__) {
                        sym = get_sym();
@@ -2039,7 +2039,7 @@ static int parse_declarations(int sym) {
                                }
                                sym = get_sym();
                        }
-                       if (sym == YY___ATTRIBUTE || sym == YY___ATTRIBUTE__ || sym == YY___DECLSPEC) {
+                       if (YY_IN_SET(sym, (YY___ATTRIBUTE,YY___ATTRIBUTE__,YY___DECLSPEC,YY___CDECL,YY___STDCALL,YY___FASTCALL,YY___THISCALL,YY___VECTORCALL), "\000\000\000\000\000\000\360\017\000\000\000\000\000")) {
                                sym = parse_attributes(sym, &dcl);
                        }
                        if (sym == YY__EQUAL) {
@@ -2050,7 +2050,7 @@ static int parse_declarations(int sym) {
                                sym = get_sym();
                                dcl = common_dcl;
                                sym = parse_declarator(sym, &dcl, &name, &name_len);
-                               if (sym == YY___ATTRIBUTE || sym == YY___ATTRIBUTE__ || sym == YY___DECLSPEC) {
+                               if (YY_IN_SET(sym, (YY___ATTRIBUTE,YY___ATTRIBUTE__,YY___DECLSPEC,YY___CDECL,YY___STDCALL,YY___FASTCALL,YY___THISCALL,YY___VECTORCALL), "\000\000\000\000\000\000\360\017\000\000\000\000\000")) {
                                        sym = parse_attributes(sym, &dcl);
                                }
                                if (sym == YY__EQUAL) {
@@ -2105,37 +2105,17 @@ static int parse_declaration_specifiers(int sym, zend_ffi_dcl *dcl) {
                                sym = get_sym();
                                dcl->flags |= ZEND_FFI_DCL_NO_RETURN;
                                break;
-                       case YY___CDECL:
-                               sym = get_sym();
-                               zend_ffi_set_abi(dcl, ZEND_FFI_ABI_CDECL);
-                               break;
-                       case YY___STDCALL:
-                               sym = get_sym();
-                               zend_ffi_set_abi(dcl, ZEND_FFI_ABI_STDCALL);
-                               break;
-                       case YY___FASTCALL:
-                               sym = get_sym();
-                               zend_ffi_set_abi(dcl, ZEND_FFI_ABI_FASTCALL);
-                               break;
-                       case YY___THISCALL:
-                               sym = get_sym();
-                               zend_ffi_set_abi(dcl, ZEND_FFI_ABI_THISCALL);
-                               break;
-                       case YY___VECTORCALL:
-                               sym = get_sym();
-                               zend_ffi_set_abi(dcl, ZEND_FFI_ABI_VECTORCALL);
-                               break;
                        case YY__ALIGNAS:
                                sym = get_sym();
                                if (sym != YY__LPAREN) {
                                        yy_error_sym("'(' expected, got", sym);
                                }
                                sym = get_sym();
-                               if ((YY_IN_SET(sym, (YY___EXTENSION__,YY_VOID,YY_CHAR,YY_SHORT,YY_INT,YY_LONG,YY_FLOAT,YY_DOUBLE,YY_SIGNED,YY_UNSIGNED,YY__BOOL,YY__COMPLEX,YY_COMPLEX,YY___COMPLEX,YY___COMPLEX__,YY_STRUCT,YY_UNION,YY_ENUM,YY_ID,YY_CONST,YY___CONST,YY___CONST__,YY_RESTRICT,YY___RESTRICT,YY___RESTRICT__,YY_VOLATILE,YY___VOLATILE,YY___VOLATILE__,YY__ATOMIC,YY___ATTRIBUTE,YY___ATTRIBUTE__,YY___DECLSPEC), "\002\000\300\377\377\377\010\016\000\000\000\002\000")) && synpred_1(sym)) {
+                               if ((YY_IN_SET(sym, (YY___EXTENSION__,YY_VOID,YY_CHAR,YY_SHORT,YY_INT,YY_LONG,YY_FLOAT,YY_DOUBLE,YY_SIGNED,YY_UNSIGNED,YY__BOOL,YY__COMPLEX,YY_COMPLEX,YY___COMPLEX,YY___COMPLEX__,YY_STRUCT,YY_UNION,YY_ENUM,YY_ID,YY_CONST,YY___CONST,YY___CONST__,YY_RESTRICT,YY___RESTRICT,YY___RESTRICT__,YY_VOLATILE,YY___VOLATILE,YY___VOLATILE__,YY__ATOMIC,YY___ATTRIBUTE,YY___ATTRIBUTE__,YY___DECLSPEC,YY___CDECL,YY___STDCALL,YY___FASTCALL,YY___THISCALL,YY___VECTORCALL), "\002\000\376\377\377\107\360\017\000\000\000\002\000")) && synpred_1(sym)) {
                                        zend_ffi_dcl align_dcl = ZEND_FFI_ATTR_INIT;
                                        sym = parse_type_name(sym, &align_dcl);
                                        zend_ffi_align_as_type(dcl, &align_dcl);
-                               } else if (YY_IN_SET(sym, (YY__LPAREN,YY_ID,YY_OCTNUMBER,YY_DECNUMBER,YY_HEXNUMBER,YY_FLOATNUMBER,YY_STRING,YY_CHARACTER,YY__PLUS_PLUS,YY__MINUS_MINUS,YY__AND,YY__STAR,YY__PLUS,YY__MINUS,YY__TILDE,YY__BANG,YY_SIZEOF,YY__ALIGNOF,YY___ALIGNOF,YY___ALIGNOF__), "\010\000\000\000\000\000\040\000\004\030\377\376\000")) {
+                               } else if (YY_IN_SET(sym, (YY__LPAREN,YY_ID,YY_OCTNUMBER,YY_DECNUMBER,YY_HEXNUMBER,YY_FLOATNUMBER,YY_STRING,YY_CHARACTER,YY__PLUS_PLUS,YY__MINUS_MINUS,YY__AND,YY__STAR,YY__PLUS,YY__MINUS,YY__TILDE,YY__BANG,YY_SIZEOF,YY__ALIGNOF,YY___ALIGNOF,YY___ALIGNOF__), "\010\000\000\000\000\000\001\000\004\030\377\376\000")) {
                                        zend_ffi_val align_val;
                                        sym = parse_constant_expression(sym, &align_val);
                                        zend_ffi_align_as_val(dcl, &align_val);
@@ -2150,6 +2130,11 @@ static int parse_declaration_specifiers(int sym, zend_ffi_dcl *dcl) {
                        case YY___ATTRIBUTE:
                        case YY___ATTRIBUTE__:
                        case YY___DECLSPEC:
+                       case YY___CDECL:
+                       case YY___STDCALL:
+                       case YY___FASTCALL:
+                       case YY___THISCALL:
+                       case YY___VECTORCALL:
                                sym = parse_attributes(sym, dcl);
                                break;
                        case YY_CONST:
@@ -2187,7 +2172,7 @@ static int parse_declaration_specifiers(int sym, zend_ffi_dcl *dcl) {
                        default:
                                yy_error_sym("unexpected", sym);
                }
-       } while ((YY_IN_SET(sym, (YY_TYPEDEF,YY_EXTERN,YY_STATIC,YY_AUTO,YY_REGISTER,YY_INLINE,YY___INLINE,YY___INLINE__,YY__NORETURN,YY___CDECL,YY___STDCALL,YY___FASTCALL,YY___THISCALL,YY___VECTORCALL,YY__ALIGNAS,YY___ATTRIBUTE,YY___ATTRIBUTE__,YY___DECLSPEC,YY_CONST,YY___CONST,YY___CONST__,YY_RESTRICT,YY___RESTRICT,YY___RESTRICT__,YY_VOLATILE,YY___VOLATILE,YY___VOLATILE__,YY__ATOMIC,YY_VOID,YY_CHAR,YY_SHORT,YY_INT,YY_LONG,YY_FLOAT,YY_DOUBLE,YY_SIGNED,YY_UNSIGNED,YY__BOOL,YY__COMPLEX,YY_COMPLEX,YY___COMPLEX,YY___COMPLEX__,YY_STRUCT,YY_UNION,YY_ENUM,YY_ID), "\200\377\377\377\377\377\010\016\000\000\000\002\000")) && (sym != YY_ID || !(dcl->flags & ZEND_FFI_DCL_TYPE_SPECIFIERS)));
+       } while ((YY_IN_SET(sym, (YY_TYPEDEF,YY_EXTERN,YY_STATIC,YY_AUTO,YY_REGISTER,YY_INLINE,YY___INLINE,YY___INLINE__,YY__NORETURN,YY__ALIGNAS,YY___ATTRIBUTE,YY___ATTRIBUTE__,YY___DECLSPEC,YY___CDECL,YY___STDCALL,YY___FASTCALL,YY___THISCALL,YY___VECTORCALL,YY_CONST,YY___CONST,YY___CONST__,YY_RESTRICT,YY___RESTRICT,YY___RESTRICT__,YY_VOLATILE,YY___VOLATILE,YY___VOLATILE__,YY__ATOMIC,YY_VOID,YY_CHAR,YY_SHORT,YY_INT,YY_LONG,YY_FLOAT,YY_DOUBLE,YY_SIGNED,YY_UNSIGNED,YY__BOOL,YY__COMPLEX,YY_COMPLEX,YY___COMPLEX,YY___COMPLEX__,YY_STRUCT,YY_UNION,YY_ENUM,YY_ID), "\200\377\377\377\377\107\360\017\000\000\000\002\000")) && (sym != YY_ID || !(dcl->flags & ZEND_FFI_DCL_TYPE_SPECIFIERS)));
        return sym;
 }
 
@@ -2196,29 +2181,29 @@ static int parse_specifier_qualifier_list(int sym, zend_ffi_dcl *dcl) {
                sym = get_sym();
        }
        do {
-               if (YY_IN_SET(sym, (YY_VOID,YY_CHAR,YY_SHORT,YY_INT,YY_LONG,YY_FLOAT,YY_DOUBLE,YY_SIGNED,YY_UNSIGNED,YY__BOOL,YY__COMPLEX,YY_COMPLEX,YY___COMPLEX,YY___COMPLEX__,YY_STRUCT,YY_UNION,YY_ENUM,YY_ID), "\000\000\000\000\377\377\010\000\000\000\000\002\000")) {
+               if (YY_IN_SET(sym, (YY_VOID,YY_CHAR,YY_SHORT,YY_INT,YY_LONG,YY_FLOAT,YY_DOUBLE,YY_SIGNED,YY_UNSIGNED,YY__BOOL,YY__COMPLEX,YY_COMPLEX,YY___COMPLEX,YY___COMPLEX__,YY_STRUCT,YY_UNION,YY_ENUM,YY_ID), "\000\000\000\370\377\107\000\000\000\000\000\002\000")) {
                        sym = parse_type_specifier(sym, dcl);
-               } else if (YY_IN_SET(sym, (YY_CONST,YY___CONST,YY___CONST__,YY_RESTRICT,YY___RESTRICT,YY___RESTRICT__,YY_VOLATILE,YY___VOLATILE,YY___VOLATILE__,YY__ATOMIC), "\000\000\300\377\000\000\000\000\000\000\000\000\000")) {
+               } else if (YY_IN_SET(sym, (YY_CONST,YY___CONST,YY___CONST__,YY_RESTRICT,YY___RESTRICT,YY___RESTRICT__,YY_VOLATILE,YY___VOLATILE,YY___VOLATILE__,YY__ATOMIC), "\000\000\376\007\000\000\000\000\000\000\000\000\000")) {
                        sym = parse_type_qualifier(sym, dcl);
-               } else if (sym == YY___ATTRIBUTE || sym == YY___ATTRIBUTE__ || sym == YY___DECLSPEC) {
+               } else if (YY_IN_SET(sym, (YY___ATTRIBUTE,YY___ATTRIBUTE__,YY___DECLSPEC,YY___CDECL,YY___STDCALL,YY___FASTCALL,YY___THISCALL,YY___VECTORCALL), "\000\000\000\000\000\000\360\017\000\000\000\000\000")) {
                        sym = parse_attributes(sym, dcl);
                } else {
                        yy_error_sym("unexpected", sym);
                }
-       } while ((YY_IN_SET(sym, (YY_VOID,YY_CHAR,YY_SHORT,YY_INT,YY_LONG,YY_FLOAT,YY_DOUBLE,YY_SIGNED,YY_UNSIGNED,YY__BOOL,YY__COMPLEX,YY_COMPLEX,YY___COMPLEX,YY___COMPLEX__,YY_STRUCT,YY_UNION,YY_ENUM,YY_ID,YY_CONST,YY___CONST,YY___CONST__,YY_RESTRICT,YY___RESTRICT,YY___RESTRICT__,YY_VOLATILE,YY___VOLATILE,YY___VOLATILE__,YY__ATOMIC,YY___ATTRIBUTE,YY___ATTRIBUTE__,YY___DECLSPEC), "\000\000\300\377\377\377\010\016\000\000\000\002\000")) && (sym != YY_ID || zend_ffi_is_typedef_name((const char*)yy_text, yy_pos - yy_text)));
+       } while ((YY_IN_SET(sym, (YY_VOID,YY_CHAR,YY_SHORT,YY_INT,YY_LONG,YY_FLOAT,YY_DOUBLE,YY_SIGNED,YY_UNSIGNED,YY__BOOL,YY__COMPLEX,YY_COMPLEX,YY___COMPLEX,YY___COMPLEX__,YY_STRUCT,YY_UNION,YY_ENUM,YY_ID,YY_CONST,YY___CONST,YY___CONST__,YY_RESTRICT,YY___RESTRICT,YY___RESTRICT__,YY_VOLATILE,YY___VOLATILE,YY___VOLATILE__,YY__ATOMIC,YY___ATTRIBUTE,YY___ATTRIBUTE__,YY___DECLSPEC,YY___CDECL,YY___STDCALL,YY___FASTCALL,YY___THISCALL,YY___VECTORCALL), "\000\000\376\377\377\107\360\017\000\000\000\002\000")) && (sym != YY_ID || zend_ffi_is_typedef_name((const char*)yy_text, yy_pos - yy_text)));
        return sym;
 }
 
 static int parse_type_qualifier_list(int sym, zend_ffi_dcl *dcl) {
        do {
-               if (YY_IN_SET(sym, (YY_CONST,YY___CONST,YY___CONST__,YY_RESTRICT,YY___RESTRICT,YY___RESTRICT__,YY_VOLATILE,YY___VOLATILE,YY___VOLATILE__,YY__ATOMIC), "\000\000\300\377\000\000\000\000\000\000\000\000\000")) {
+               if (YY_IN_SET(sym, (YY_CONST,YY___CONST,YY___CONST__,YY_RESTRICT,YY___RESTRICT,YY___RESTRICT__,YY_VOLATILE,YY___VOLATILE,YY___VOLATILE__,YY__ATOMIC), "\000\000\376\007\000\000\000\000\000\000\000\000\000")) {
                        sym = parse_type_qualifier(sym, dcl);
-               } else if (sym == YY___ATTRIBUTE || sym == YY___ATTRIBUTE__ || sym == YY___DECLSPEC) {
+               } else if (YY_IN_SET(sym, (YY___ATTRIBUTE,YY___ATTRIBUTE__,YY___DECLSPEC,YY___CDECL,YY___STDCALL,YY___FASTCALL,YY___THISCALL,YY___VECTORCALL), "\000\000\000\000\000\000\360\017\000\000\000\000\000")) {
                        sym = parse_attributes(sym, dcl);
                } else {
                        yy_error_sym("unexpected", sym);
                }
-       } while (YY_IN_SET(sym, (YY_CONST,YY___CONST,YY___CONST__,YY_RESTRICT,YY___RESTRICT,YY___RESTRICT__,YY_VOLATILE,YY___VOLATILE,YY___VOLATILE__,YY__ATOMIC,YY___ATTRIBUTE,YY___ATTRIBUTE__,YY___DECLSPEC), "\000\000\300\377\000\000\000\016\000\000\000\000\000"));
+       } while (YY_IN_SET(sym, (YY_CONST,YY___CONST,YY___CONST__,YY_RESTRICT,YY___RESTRICT,YY___RESTRICT__,YY_VOLATILE,YY___VOLATILE,YY___VOLATILE__,YY__ATOMIC,YY___ATTRIBUTE,YY___ATTRIBUTE__,YY___DECLSPEC,YY___CDECL,YY___STDCALL,YY___FASTCALL,YY___THISCALL,YY___VECTORCALL), "\000\000\376\007\000\000\360\017\000\000\000\000\000"));
        return sym;
 }
 
@@ -2341,7 +2326,7 @@ static int parse_struct_or_union_specifier(int sym, zend_ffi_dcl *dcl) {
        } else {
                yy_error_sym("unexpected", sym);
        }
-       if (sym == YY___ATTRIBUTE || sym == YY___ATTRIBUTE__ || sym == YY___DECLSPEC) {
+       if (YY_IN_SET(sym, (YY___ATTRIBUTE,YY___ATTRIBUTE__,YY___DECLSPEC,YY___CDECL,YY___STDCALL,YY___FASTCALL,YY___THISCALL,YY___VECTORCALL), "\000\000\000\000\000\000\360\017\000\000\000\000\000")) {
                sym = parse_attributes(sym, dcl);
        }
        if (sym == YY_ID) {
@@ -2372,7 +2357,7 @@ static int parse_struct_contents(int sym, zend_ffi_dcl *dcl) {
                yy_error_sym("'{' expected, got", sym);
        }
        sym = get_sym();
-       if (YY_IN_SET(sym, (YY___EXTENSION__,YY_VOID,YY_CHAR,YY_SHORT,YY_INT,YY_LONG,YY_FLOAT,YY_DOUBLE,YY_SIGNED,YY_UNSIGNED,YY__BOOL,YY__COMPLEX,YY_COMPLEX,YY___COMPLEX,YY___COMPLEX__,YY_STRUCT,YY_UNION,YY_ENUM,YY_ID,YY_CONST,YY___CONST,YY___CONST__,YY_RESTRICT,YY___RESTRICT,YY___RESTRICT__,YY_VOLATILE,YY___VOLATILE,YY___VOLATILE__,YY__ATOMIC,YY___ATTRIBUTE,YY___ATTRIBUTE__,YY___DECLSPEC), "\002\000\300\377\377\377\010\016\000\000\000\002\000")) {
+       if (YY_IN_SET(sym, (YY___EXTENSION__,YY_VOID,YY_CHAR,YY_SHORT,YY_INT,YY_LONG,YY_FLOAT,YY_DOUBLE,YY_SIGNED,YY_UNSIGNED,YY__BOOL,YY__COMPLEX,YY_COMPLEX,YY___COMPLEX,YY___COMPLEX__,YY_STRUCT,YY_UNION,YY_ENUM,YY_ID,YY_CONST,YY___CONST,YY___CONST__,YY_RESTRICT,YY___RESTRICT,YY___RESTRICT__,YY_VOLATILE,YY___VOLATILE,YY___VOLATILE__,YY__ATOMIC,YY___ATTRIBUTE,YY___ATTRIBUTE__,YY___DECLSPEC,YY___CDECL,YY___STDCALL,YY___FASTCALL,YY___THISCALL,YY___VECTORCALL), "\002\000\376\377\377\107\360\017\000\000\000\002\000")) {
                sym = parse_struct_declaration(sym, dcl);
                while (1) {
                        save_pos  = yy_pos;
@@ -2390,7 +2375,7 @@ static int parse_struct_contents(int sym, zend_ffi_dcl *dcl) {
                                yy_error_sym("unexpected", sym2);
                        }
 _yy_state_2_1:
-                       if (YY_IN_SET(sym2, (YY___EXTENSION__,YY_VOID,YY_CHAR,YY_SHORT,YY_INT,YY_LONG,YY_FLOAT,YY_DOUBLE,YY_SIGNED,YY_UNSIGNED,YY__BOOL,YY__COMPLEX,YY_COMPLEX,YY___COMPLEX,YY___COMPLEX__,YY_STRUCT,YY_UNION,YY_ENUM,YY_ID,YY_CONST,YY___CONST,YY___CONST__,YY_RESTRICT,YY___RESTRICT,YY___RESTRICT__,YY_VOLATILE,YY___VOLATILE,YY___VOLATILE__,YY__ATOMIC,YY___ATTRIBUTE,YY___ATTRIBUTE__,YY___DECLSPEC), "\002\000\300\377\377\377\010\016\000\000\000\002\000")) {
+                       if (YY_IN_SET(sym2, (YY___EXTENSION__,YY_VOID,YY_CHAR,YY_SHORT,YY_INT,YY_LONG,YY_FLOAT,YY_DOUBLE,YY_SIGNED,YY_UNSIGNED,YY__BOOL,YY__COMPLEX,YY_COMPLEX,YY___COMPLEX,YY___COMPLEX__,YY_STRUCT,YY_UNION,YY_ENUM,YY_ID,YY_CONST,YY___CONST,YY___CONST__,YY_RESTRICT,YY___RESTRICT,YY___RESTRICT__,YY_VOLATILE,YY___VOLATILE,YY___VOLATILE__,YY__ATOMIC,YY___ATTRIBUTE,YY___ATTRIBUTE__,YY___DECLSPEC,YY___CDECL,YY___STDCALL,YY___FASTCALL,YY___THISCALL,YY___VECTORCALL), "\002\000\376\377\377\107\360\017\000\000\000\002\000")) {
                                alt2 = 3;
                                goto _yy_state_2;
                        } else if (sym2 == YY__RBRACE) {
@@ -2417,7 +2402,7 @@ _yy_state_2:
                yy_error_sym("'}' expected, got", sym);
        }
        sym = get_sym();
-       if (sym == YY___ATTRIBUTE || sym == YY___ATTRIBUTE__ || sym == YY___DECLSPEC) {
+       if (YY_IN_SET(sym, (YY___ATTRIBUTE,YY___ATTRIBUTE__,YY___DECLSPEC,YY___CDECL,YY___STDCALL,YY___FASTCALL,YY___THISCALL,YY___VECTORCALL), "\000\000\000\000\000\000\360\017\000\000\000\000\000")) {
                sym = parse_attributes(sym, dcl);
        }
        zend_ffi_adjust_struct_size(dcl);
@@ -2434,7 +2419,7 @@ static int parse_struct_declaration(int sym, zend_ffi_dcl *struct_dcl) {
                while (sym == YY__COMMA) {
                        sym = get_sym();
                        zend_ffi_dcl field_dcl = common_field_dcl;
-                       if (sym == YY___ATTRIBUTE || sym == YY___ATTRIBUTE__ || sym == YY___DECLSPEC) {
+                       if (YY_IN_SET(sym, (YY___ATTRIBUTE,YY___ATTRIBUTE__,YY___DECLSPEC,YY___CDECL,YY___STDCALL,YY___FASTCALL,YY___THISCALL,YY___VECTORCALL), "\000\000\000\000\000\000\360\017\000\000\000\000\000")) {
                                sym = parse_attributes(sym, &field_dcl);
                        }
                        sym = parse_struct_declarator(sym, struct_dcl, &field_dcl);
@@ -2454,12 +2439,12 @@ static int parse_struct_declarator(int sym, zend_ffi_dcl *struct_dcl, zend_ffi_d
                if (sym == YY__COLON) {
                        sym = get_sym();
                        sym = parse_constant_expression(sym, &bits);
-                       if (sym == YY___ATTRIBUTE || sym == YY___ATTRIBUTE__ || sym == YY___DECLSPEC) {
+                       if (YY_IN_SET(sym, (YY___ATTRIBUTE,YY___ATTRIBUTE__,YY___DECLSPEC,YY___CDECL,YY___STDCALL,YY___FASTCALL,YY___THISCALL,YY___VECTORCALL), "\000\000\000\000\000\000\360\017\000\000\000\000\000")) {
                                sym = parse_attributes(sym, field_dcl);
                        }
                        zend_ffi_add_bit_field(struct_dcl, name, name_len, field_dcl, &bits);
-               } else if (YY_IN_SET(sym, (YY___ATTRIBUTE,YY___ATTRIBUTE__,YY___DECLSPEC,YY__COMMA,YY__SEMICOLON,YY__RBRACE), "\140\000\000\000\000\000\002\016\000\000\000\000\000")) {
-                       if (sym == YY___ATTRIBUTE || sym == YY___ATTRIBUTE__ || sym == YY___DECLSPEC) {
+               } else if (YY_IN_SET(sym, (YY___ATTRIBUTE,YY___ATTRIBUTE__,YY___DECLSPEC,YY___CDECL,YY___STDCALL,YY___FASTCALL,YY___THISCALL,YY___VECTORCALL,YY__COMMA,YY__SEMICOLON,YY__RBRACE), "\140\000\000\000\000\020\360\017\000\000\000\000\000")) {
+                       if (YY_IN_SET(sym, (YY___ATTRIBUTE,YY___ATTRIBUTE__,YY___DECLSPEC,YY___CDECL,YY___STDCALL,YY___FASTCALL,YY___THISCALL,YY___VECTORCALL), "\000\000\000\000\000\000\360\017\000\000\000\000\000")) {
                                sym = parse_attributes(sym, field_dcl);
                        }
                        zend_ffi_add_field(struct_dcl, name, name_len, field_dcl);
@@ -2482,7 +2467,7 @@ static int parse_enum_specifier(int sym, zend_ffi_dcl *dcl) {
        }
        sym = get_sym();
        dcl->flags |= ZEND_FFI_DCL_ENUM;
-       if (sym == YY___ATTRIBUTE || sym == YY___ATTRIBUTE__ || sym == YY___DECLSPEC) {
+       if (YY_IN_SET(sym, (YY___ATTRIBUTE,YY___ATTRIBUTE__,YY___DECLSPEC,YY___CDECL,YY___STDCALL,YY___FASTCALL,YY___THISCALL,YY___VECTORCALL), "\000\000\000\000\000\000\360\017\000\000\000\000\000")) {
                sym = parse_attributes(sym, dcl);
        }
        if (sym == YY_ID) {
@@ -2497,10 +2482,10 @@ static int parse_enum_specifier(int sym, zend_ffi_dcl *dcl) {
                                yy_error_sym("'}' expected, got", sym);
                        }
                        sym = get_sym();
-                       if (sym == YY___ATTRIBUTE || sym == YY___ATTRIBUTE__ || sym == YY___DECLSPEC) {
+                       if (YY_IN_SET(sym, (YY___ATTRIBUTE,YY___ATTRIBUTE__,YY___DECLSPEC,YY___CDECL,YY___STDCALL,YY___FASTCALL,YY___THISCALL,YY___VECTORCALL), "\000\000\000\000\000\000\360\017\000\000\000\000\000")) {
                                sym = parse_attributes(sym, dcl);
                        }
-               } else if (YY_IN_SET(sym, (YY_TYPEDEF,YY_EXTERN,YY_STATIC,YY_AUTO,YY_REGISTER,YY_INLINE,YY___INLINE,YY___INLINE__,YY__NORETURN,YY___CDECL,YY___STDCALL,YY___FASTCALL,YY___THISCALL,YY___VECTORCALL,YY__ALIGNAS,YY___ATTRIBUTE,YY___ATTRIBUTE__,YY___DECLSPEC,YY_CONST,YY___CONST,YY___CONST__,YY_RESTRICT,YY___RESTRICT,YY___RESTRICT__,YY_VOLATILE,YY___VOLATILE,YY___VOLATILE__,YY__ATOMIC,YY_VOID,YY_CHAR,YY_SHORT,YY_INT,YY_LONG,YY_FLOAT,YY_DOUBLE,YY_SIGNED,YY_UNSIGNED,YY__BOOL,YY__COMPLEX,YY_COMPLEX,YY___COMPLEX,YY___COMPLEX__,YY_STRUCT,YY_UNION,YY_ENUM,YY_ID,YY__STAR,YY__LPAREN,YY__SEMICOLON,YY__COLON,YY__LBRACK,YY__RBRACE,YY__COMMA,YY__RPAREN,YY_EOF), "\371\377\377\377\377\377\156\016\000\000\000\002\000")) {
+               } else if (YY_IN_SET(sym, (YY_TYPEDEF,YY_EXTERN,YY_STATIC,YY_AUTO,YY_REGISTER,YY_INLINE,YY___INLINE,YY___INLINE__,YY__NORETURN,YY__ALIGNAS,YY___ATTRIBUTE,YY___ATTRIBUTE__,YY___DECLSPEC,YY___CDECL,YY___STDCALL,YY___FASTCALL,YY___THISCALL,YY___VECTORCALL,YY_CONST,YY___CONST,YY___CONST__,YY_RESTRICT,YY___RESTRICT,YY___RESTRICT__,YY_VOLATILE,YY___VOLATILE,YY___VOLATILE__,YY__ATOMIC,YY_VOID,YY_CHAR,YY_SHORT,YY_INT,YY_LONG,YY_FLOAT,YY_DOUBLE,YY_SIGNED,YY_UNSIGNED,YY__BOOL,YY__COMPLEX,YY_COMPLEX,YY___COMPLEX,YY___COMPLEX__,YY_STRUCT,YY_UNION,YY_ENUM,YY_ID,YY__STAR,YY__LPAREN,YY__SEMICOLON,YY__COLON,YY__LBRACK,YY__RBRACE,YY__COMMA,YY__RPAREN,YY_EOF), "\371\377\377\377\377\167\363\017\000\000\000\002\000")) {
                        zend_ffi_declare_tag(name, name_len, dcl, 1);
                } else {
                        yy_error_sym("unexpected", sym);
@@ -2513,7 +2498,7 @@ static int parse_enum_specifier(int sym, zend_ffi_dcl *dcl) {
                        yy_error_sym("'}' expected, got", sym);
                }
                sym = get_sym();
-               if (sym == YY___ATTRIBUTE || sym == YY___ATTRIBUTE__ || sym == YY___DECLSPEC) {
+               if (YY_IN_SET(sym, (YY___ATTRIBUTE,YY___ATTRIBUTE__,YY___DECLSPEC,YY___CDECL,YY___STDCALL,YY___FASTCALL,YY___THISCALL,YY___VECTORCALL), "\000\000\000\000\000\000\360\017\000\000\000\000\000")) {
                        sym = parse_attributes(sym, dcl);
                }
        } else {
@@ -2594,7 +2579,7 @@ static int parse_declarator(int sym, zend_ffi_dcl *dcl, const char **name, size_
                sym = parse_ID(sym, name, name_len);
        } else if (sym == YY__LPAREN) {
                sym = get_sym();
-               if (sym == YY___ATTRIBUTE || sym == YY___ATTRIBUTE__ || sym == YY___DECLSPEC) {
+               if (YY_IN_SET(sym, (YY___ATTRIBUTE,YY___ATTRIBUTE__,YY___DECLSPEC,YY___CDECL,YY___STDCALL,YY___FASTCALL,YY___THISCALL,YY___VECTORCALL), "\000\000\000\000\000\000\360\017\000\000\000\000\000")) {
                        sym = parse_attributes(sym, &nested_dcl);
                }
                sym = parse_declarator(sym, &nested_dcl, name, name_len);
@@ -2621,7 +2606,7 @@ static int parse_abstract_declarator(int sym, zend_ffi_dcl *dcl) {
        }
        if ((sym == YY__LPAREN) && synpred_2(sym)) {
                sym = get_sym();
-               if (sym == YY___ATTRIBUTE || sym == YY___ATTRIBUTE__ || sym == YY___DECLSPEC) {
+               if (YY_IN_SET(sym, (YY___ATTRIBUTE,YY___ATTRIBUTE__,YY___DECLSPEC,YY___CDECL,YY___STDCALL,YY___FASTCALL,YY___THISCALL,YY___VECTORCALL), "\000\000\000\000\000\000\360\017\000\000\000\000\000")) {
                        sym = parse_attributes(sym, &nested_dcl);
                }
                sym = parse_abstract_declarator(sym, &nested_dcl);
@@ -2646,7 +2631,7 @@ static int parse_parameter_declarator(int sym, zend_ffi_dcl *dcl, const char **n
        }
        if ((sym == YY__LPAREN) && synpred_3(sym)) {
                sym = get_sym();
-               if (sym == YY___ATTRIBUTE || sym == YY___ATTRIBUTE__ || sym == YY___DECLSPEC) {
+               if (YY_IN_SET(sym, (YY___ATTRIBUTE,YY___ATTRIBUTE__,YY___DECLSPEC,YY___CDECL,YY___STDCALL,YY___FASTCALL,YY___THISCALL,YY___VECTORCALL), "\000\000\000\000\000\000\360\017\000\000\000\000\000")) {
                        sym = parse_attributes(sym, &nested_dcl);
                }
                sym = parse_parameter_declarator(sym, &nested_dcl, name, name_len);
@@ -2675,7 +2660,7 @@ static int parse_pointer(int sym, zend_ffi_dcl *dcl) {
        do {
                sym = get_sym();
                zend_ffi_make_pointer_type(dcl);
-               if (YY_IN_SET(sym, (YY_CONST,YY___CONST,YY___CONST__,YY_RESTRICT,YY___RESTRICT,YY___RESTRICT__,YY_VOLATILE,YY___VOLATILE,YY___VOLATILE__,YY__ATOMIC,YY___ATTRIBUTE,YY___ATTRIBUTE__,YY___DECLSPEC), "\000\000\300\377\000\000\000\016\000\000\000\000\000")) {
+               if (YY_IN_SET(sym, (YY_CONST,YY___CONST,YY___CONST__,YY_RESTRICT,YY___RESTRICT,YY___RESTRICT__,YY_VOLATILE,YY___VOLATILE,YY___VOLATILE__,YY__ATOMIC,YY___ATTRIBUTE,YY___ATTRIBUTE__,YY___DECLSPEC,YY___CDECL,YY___STDCALL,YY___FASTCALL,YY___THISCALL,YY___VECTORCALL), "\000\000\376\007\000\000\360\017\000\000\000\000\000")) {
                        sym = parse_type_qualifier_list(sym, dcl);
                }
        } while (sym == YY__STAR);
@@ -2687,9 +2672,9 @@ static int parse_array_or_function_declarators(int sym, zend_ffi_dcl *dcl, zend_
        const unsigned char *save_pos;
        const unsigned char *save_text;
        int   save_line;
-       int alt104;
-       int alt100;
-       int alt114;
+       int alt109;
+       int alt105;
+       int alt119;
        zend_ffi_dcl dummy = ZEND_FFI_ATTR_INIT;
        zend_ffi_val len = {.kind = ZEND_FFI_VAL_EMPTY};
        HashTable *args = NULL;
@@ -2699,99 +2684,99 @@ static int parse_array_or_function_declarators(int sym, zend_ffi_dcl *dcl, zend_
                save_pos  = yy_pos;
                save_text = yy_text;
                save_line = yy_line;
-               alt100 = -2;
+               alt105 = -2;
                sym2 = sym;
                if (sym2 == YY_STATIC) {
-                       alt100 = 101;
-                       goto _yy_state_100;
-               } else if (YY_IN_SET(sym2, (YY_CONST,YY___CONST,YY___CONST__,YY_RESTRICT,YY___RESTRICT,YY___RESTRICT__,YY_VOLATILE,YY___VOLATILE,YY___VOLATILE__,YY__ATOMIC,YY___ATTRIBUTE,YY___ATTRIBUTE__,YY___DECLSPEC), "\000\000\300\377\000\000\000\016\000\000\000\000\000")) {
-                       alt100 = 104;
-                       goto _yy_state_100;
+                       alt105 = 106;
+                       goto _yy_state_105;
+               } else if (YY_IN_SET(sym2, (YY_CONST,YY___CONST,YY___CONST__,YY_RESTRICT,YY___RESTRICT,YY___RESTRICT__,YY_VOLATILE,YY___VOLATILE,YY___VOLATILE__,YY__ATOMIC,YY___ATTRIBUTE,YY___ATTRIBUTE__,YY___DECLSPEC,YY___CDECL,YY___STDCALL,YY___FASTCALL,YY___THISCALL,YY___VECTORCALL), "\000\000\376\007\000\000\360\017\000\000\000\000\000")) {
+                       alt105 = 109;
+                       goto _yy_state_105;
                } else if (sym2 == YY__STAR) {
                        sym2 = get_sym();
-                       goto _yy_state_100_15;
+                       goto _yy_state_105_20;
                } else if (YY_IN_SET(sym2, (YY__LPAREN,YY__PLUS_PLUS,YY__MINUS_MINUS,YY__AND,YY__PLUS,YY__MINUS,YY__TILDE,YY__BANG,YY_SIZEOF,YY__ALIGNOF,YY___ALIGNOF,YY___ALIGNOF__,YY_ID,YY_OCTNUMBER,YY_DECNUMBER,YY_HEXNUMBER,YY_FLOATNUMBER,YY_STRING,YY_CHARACTER), "\010\000\000\000\000\000\000\000\004\030\377\376\000")) {
-                       alt100 = 110;
-                       goto _yy_state_100;
+                       alt105 = 115;
+                       goto _yy_state_105;
                } else if (sym2 == YY__RBRACK) {
-                       alt100 = 111;
-                       goto _yy_state_100;
+                       alt105 = 116;
+                       goto _yy_state_105;
                } else {
                        yy_error_sym("unexpected", sym2);
                }
-_yy_state_100_15:
+_yy_state_105_20:
                if (sym2 == YY__RBRACK) {
-                       alt100 = 109;
-                       goto _yy_state_100;
-               } else if (YY_IN_SET(sym2, (YY__LPAREN,YY__PLUS_PLUS,YY__MINUS_MINUS,YY__AND,YY__PLUS,YY__MINUS,YY__TILDE,YY__BANG,YY_SIZEOF,YY__ALIGNOF,YY___ALIGNOF,YY___ALIGNOF__,YY_ID,YY_OCTNUMBER,YY_DECNUMBER,YY_HEXNUMBER,YY_FLOATNUMBER,YY_STRING,YY_CHARACTER,YY__STAR), "\010\000\000\000\000\000\040\000\004\030\377\376\000")) {
-                       alt100 = 110;
-                       goto _yy_state_100;
+                       alt105 = 114;
+                       goto _yy_state_105;
+               } else if (YY_IN_SET(sym2, (YY__LPAREN,YY__PLUS_PLUS,YY__MINUS_MINUS,YY__AND,YY__PLUS,YY__MINUS,YY__TILDE,YY__BANG,YY_SIZEOF,YY__ALIGNOF,YY___ALIGNOF,YY___ALIGNOF__,YY_ID,YY_OCTNUMBER,YY_DECNUMBER,YY_HEXNUMBER,YY_FLOATNUMBER,YY_STRING,YY_CHARACTER,YY__STAR), "\010\000\000\000\000\000\001\000\004\030\377\376\000")) {
+                       alt105 = 115;
+                       goto _yy_state_105;
                } else {
                        yy_error_sym("unexpected", sym2);
                }
-_yy_state_100:
+_yy_state_105:
                yy_pos  = save_pos;
                yy_text = save_text;
                yy_line = save_line;
-               if (alt100 == 101) {
+               if (alt105 == 106) {
                        sym = get_sym();
-                       if (YY_IN_SET(sym, (YY_CONST,YY___CONST,YY___CONST__,YY_RESTRICT,YY___RESTRICT,YY___RESTRICT__,YY_VOLATILE,YY___VOLATILE,YY___VOLATILE__,YY__ATOMIC,YY___ATTRIBUTE,YY___ATTRIBUTE__,YY___DECLSPEC), "\000\000\300\377\000\000\000\016\000\000\000\000\000")) {
+                       if (YY_IN_SET(sym, (YY_CONST,YY___CONST,YY___CONST__,YY_RESTRICT,YY___RESTRICT,YY___RESTRICT__,YY_VOLATILE,YY___VOLATILE,YY___VOLATILE__,YY__ATOMIC,YY___ATTRIBUTE,YY___ATTRIBUTE__,YY___DECLSPEC,YY___CDECL,YY___STDCALL,YY___FASTCALL,YY___THISCALL,YY___VECTORCALL), "\000\000\376\007\000\000\360\017\000\000\000\000\000")) {
                                sym = parse_type_qualifier_list(sym, &dummy);
                        }
                        sym = parse_assignment_expression(sym, &len);
-               } else if (alt100 == 104) {
+               } else if (alt105 == 109) {
                        sym = parse_type_qualifier_list(sym, &dummy);
                        save_pos  = yy_pos;
                        save_text = yy_text;
                        save_line = yy_line;
-                       alt104 = -2;
+                       alt109 = -2;
                        sym2 = sym;
                        if (sym2 == YY_STATIC) {
-                               alt104 = 105;
-                               goto _yy_state_104;
+                               alt109 = 110;
+                               goto _yy_state_109;
                        } else if (sym2 == YY__STAR) {
                                sym2 = get_sym();
-                               goto _yy_state_104_2;
+                               goto _yy_state_109_2;
                        } else if (YY_IN_SET(sym2, (YY__LPAREN,YY__PLUS_PLUS,YY__MINUS_MINUS,YY__AND,YY__PLUS,YY__MINUS,YY__TILDE,YY__BANG,YY_SIZEOF,YY__ALIGNOF,YY___ALIGNOF,YY___ALIGNOF__,YY_ID,YY_OCTNUMBER,YY_DECNUMBER,YY_HEXNUMBER,YY_FLOATNUMBER,YY_STRING,YY_CHARACTER), "\010\000\000\000\000\000\000\000\004\030\377\376\000")) {
-                               alt104 = 108;
-                               goto _yy_state_104;
+                               alt109 = 113;
+                               goto _yy_state_109;
                        } else if (sym2 == YY__RBRACK) {
-                               alt104 = 111;
-                               goto _yy_state_104;
+                               alt109 = 116;
+                               goto _yy_state_109;
                        } else {
                                yy_error_sym("unexpected", sym2);
                        }
-_yy_state_104_2:
+_yy_state_109_2:
                        if (sym2 == YY__RBRACK) {
-                               alt104 = 107;
-                               goto _yy_state_104;
-                       } else if (YY_IN_SET(sym2, (YY__LPAREN,YY__PLUS_PLUS,YY__MINUS_MINUS,YY__AND,YY__PLUS,YY__MINUS,YY__TILDE,YY__BANG,YY_SIZEOF,YY__ALIGNOF,YY___ALIGNOF,YY___ALIGNOF__,YY_ID,YY_OCTNUMBER,YY_DECNUMBER,YY_HEXNUMBER,YY_FLOATNUMBER,YY_STRING,YY_CHARACTER,YY__STAR), "\010\000\000\000\000\000\040\000\004\030\377\376\000")) {
-                               alt104 = 108;
-                               goto _yy_state_104;
+                               alt109 = 112;
+                               goto _yy_state_109;
+                       } else if (YY_IN_SET(sym2, (YY__LPAREN,YY__PLUS_PLUS,YY__MINUS_MINUS,YY__AND,YY__PLUS,YY__MINUS,YY__TILDE,YY__BANG,YY_SIZEOF,YY__ALIGNOF,YY___ALIGNOF,YY___ALIGNOF__,YY_ID,YY_OCTNUMBER,YY_DECNUMBER,YY_HEXNUMBER,YY_FLOATNUMBER,YY_STRING,YY_CHARACTER,YY__STAR), "\010\000\000\000\000\000\001\000\004\030\377\376\000")) {
+                               alt109 = 113;
+                               goto _yy_state_109;
                        } else {
                                yy_error_sym("unexpected", sym2);
                        }
-_yy_state_104:
+_yy_state_109:
                        yy_pos  = save_pos;
                        yy_text = save_text;
                        yy_line = save_line;
-                       if (alt104 == 105) {
+                       if (alt109 == 110) {
                                sym = get_sym();
                                sym = parse_assignment_expression(sym, &len);
-                       } else if (alt104 == 111) {
+                       } else if (alt109 == 116) {
                                attr |= ZEND_FFI_ATTR_INCOMPLETE_ARRAY;
-                       } else if (alt104 == 107) {
+                       } else if (alt109 == 112) {
                                sym = get_sym();
                                attr |= ZEND_FFI_ATTR_VLA;
-                       } else if (alt104 == 108) {
+                       } else if (alt109 == 113) {
                                sym = parse_assignment_expression(sym, &len);
                        } else {
                                yy_error_sym("unexpected", sym);
                        }
-               } else if (alt100 == 111 || alt100 == 109 || alt100 == 110) {
-                       if (alt100 == 111) {
+               } else if (alt105 == 116 || alt105 == 114 || alt105 == 115) {
+                       if (alt105 == 116) {
                                attr |= ZEND_FFI_ATTR_INCOMPLETE_ARRAY;
-                       } else if (alt100 == 109) {
+                       } else if (alt105 == 114) {
                                sym = get_sym();
                                attr |= ZEND_FFI_ATTR_VLA;
                        } else {
@@ -2811,45 +2796,45 @@ _yy_state_104:
                zend_ffi_make_array_type(dcl, &len);
        } else if (sym == YY__LPAREN) {
                sym = get_sym();
-               if (YY_IN_SET(sym, (YY___EXTENSION__,YY_VOID,YY_CHAR,YY_SHORT,YY_INT,YY_LONG,YY_FLOAT,YY_DOUBLE,YY_SIGNED,YY_UNSIGNED,YY__BOOL,YY__COMPLEX,YY_COMPLEX,YY___COMPLEX,YY___COMPLEX__,YY_STRUCT,YY_UNION,YY_ENUM,YY_ID,YY_CONST,YY___CONST,YY___CONST__,YY_RESTRICT,YY___RESTRICT,YY___RESTRICT__,YY_VOLATILE,YY___VOLATILE,YY___VOLATILE__,YY__ATOMIC,YY___ATTRIBUTE,YY___ATTRIBUTE__,YY___DECLSPEC,YY__POINT_POINT_POINT), "\002\000\300\377\377\377\010\017\000\000\000\002\000")) {
-                       if (YY_IN_SET(sym, (YY___EXTENSION__,YY_VOID,YY_CHAR,YY_SHORT,YY_INT,YY_LONG,YY_FLOAT,YY_DOUBLE,YY_SIGNED,YY_UNSIGNED,YY__BOOL,YY__COMPLEX,YY_COMPLEX,YY___COMPLEX,YY___COMPLEX__,YY_STRUCT,YY_UNION,YY_ENUM,YY_ID,YY_CONST,YY___CONST,YY___CONST__,YY_RESTRICT,YY___RESTRICT,YY___RESTRICT__,YY_VOLATILE,YY___VOLATILE,YY___VOLATILE__,YY__ATOMIC,YY___ATTRIBUTE,YY___ATTRIBUTE__,YY___DECLSPEC), "\002\000\300\377\377\377\010\016\000\000\000\002\000")) {
+               if (YY_IN_SET(sym, (YY___EXTENSION__,YY_VOID,YY_CHAR,YY_SHORT,YY_INT,YY_LONG,YY_FLOAT,YY_DOUBLE,YY_SIGNED,YY_UNSIGNED,YY__BOOL,YY__COMPLEX,YY_COMPLEX,YY___COMPLEX,YY___COMPLEX__,YY_STRUCT,YY_UNION,YY_ENUM,YY_ID,YY_CONST,YY___CONST,YY___CONST__,YY_RESTRICT,YY___RESTRICT,YY___RESTRICT__,YY_VOLATILE,YY___VOLATILE,YY___VOLATILE__,YY__ATOMIC,YY___ATTRIBUTE,YY___ATTRIBUTE__,YY___DECLSPEC,YY___CDECL,YY___STDCALL,YY___FASTCALL,YY___THISCALL,YY___VECTORCALL,YY__POINT_POINT_POINT), "\002\000\376\377\377\107\370\017\000\000\000\002\000")) {
+                       if (YY_IN_SET(sym, (YY___EXTENSION__,YY_VOID,YY_CHAR,YY_SHORT,YY_INT,YY_LONG,YY_FLOAT,YY_DOUBLE,YY_SIGNED,YY_UNSIGNED,YY__BOOL,YY__COMPLEX,YY_COMPLEX,YY___COMPLEX,YY___COMPLEX__,YY_STRUCT,YY_UNION,YY_ENUM,YY_ID,YY_CONST,YY___CONST,YY___CONST__,YY_RESTRICT,YY___RESTRICT,YY___RESTRICT__,YY_VOLATILE,YY___VOLATILE,YY___VOLATILE__,YY__ATOMIC,YY___ATTRIBUTE,YY___ATTRIBUTE__,YY___DECLSPEC,YY___CDECL,YY___STDCALL,YY___FASTCALL,YY___THISCALL,YY___VECTORCALL), "\002\000\376\377\377\107\360\017\000\000\000\002\000")) {
                                sym = parse_parameter_declaration(sym, &args);
                                while (1) {
                                        save_pos  = yy_pos;
                                        save_text = yy_text;
                                        save_line = yy_line;
-                                       alt114 = -2;
+                                       alt119 = -2;
                                        sym2 = sym;
                                        if (sym2 == YY__COMMA) {
                                                sym2 = get_sym();
-                                               goto _yy_state_114_1;
+                                               goto _yy_state_119_1;
                                        } else if (sym2 == YY__RPAREN) {
-                                               alt114 = 120;
-                                               goto _yy_state_114;
+                                               alt119 = 125;
+                                               goto _yy_state_119;
                                        } else {
                                                yy_error_sym("unexpected", sym2);
                                        }
-_yy_state_114_1:
-                                       if (YY_IN_SET(sym2, (YY___EXTENSION__,YY_VOID,YY_CHAR,YY_SHORT,YY_INT,YY_LONG,YY_FLOAT,YY_DOUBLE,YY_SIGNED,YY_UNSIGNED,YY__BOOL,YY__COMPLEX,YY_COMPLEX,YY___COMPLEX,YY___COMPLEX__,YY_STRUCT,YY_UNION,YY_ENUM,YY_ID,YY_CONST,YY___CONST,YY___CONST__,YY_RESTRICT,YY___RESTRICT,YY___RESTRICT__,YY_VOLATILE,YY___VOLATILE,YY___VOLATILE__,YY__ATOMIC,YY___ATTRIBUTE,YY___ATTRIBUTE__,YY___DECLSPEC), "\002\000\300\377\377\377\010\016\000\000\000\002\000")) {
-                                               alt114 = 115;
-                                               goto _yy_state_114;
+_yy_state_119_1:
+                                       if (YY_IN_SET(sym2, (YY___EXTENSION__,YY_VOID,YY_CHAR,YY_SHORT,YY_INT,YY_LONG,YY_FLOAT,YY_DOUBLE,YY_SIGNED,YY_UNSIGNED,YY__BOOL,YY__COMPLEX,YY_COMPLEX,YY___COMPLEX,YY___COMPLEX__,YY_STRUCT,YY_UNION,YY_ENUM,YY_ID,YY_CONST,YY___CONST,YY___CONST__,YY_RESTRICT,YY___RESTRICT,YY___RESTRICT__,YY_VOLATILE,YY___VOLATILE,YY___VOLATILE__,YY__ATOMIC,YY___ATTRIBUTE,YY___ATTRIBUTE__,YY___DECLSPEC,YY___CDECL,YY___STDCALL,YY___FASTCALL,YY___THISCALL,YY___VECTORCALL), "\002\000\376\377\377\107\360\017\000\000\000\002\000")) {
+                                               alt119 = 120;
+                                               goto _yy_state_119;
                                        } else if (sym2 == YY__POINT_POINT_POINT) {
-                                               alt114 = 117;
-                                               goto _yy_state_114;
+                                               alt119 = 122;
+                                               goto _yy_state_119;
                                        } else {
                                                yy_error_sym("unexpected", sym2);
                                        }
-_yy_state_114:
+_yy_state_119:
                                        yy_pos  = save_pos;
                                        yy_text = save_text;
                                        yy_line = save_line;
-                                       if (alt114 != 115) {
+                                       if (alt119 != 120) {
                                                break;
                                        }
                                        sym = get_sym();
                                        sym = parse_parameter_declaration(sym, &args);
                                }
-                               if (alt114 == 117) {
+                               if (alt119 == 122) {
                                        sym = get_sym();
                                        if (sym != YY__POINT_POINT_POINT) {
                                                yy_error_sym("'...' expected, got", sym);
@@ -2901,55 +2886,79 @@ static int parse_attributes(int sym, zend_ffi_dcl *dcl) {
        size_t name_len;
        zend_ffi_val val;
        do {
-               if (sym == YY___ATTRIBUTE || sym == YY___ATTRIBUTE__) {
-                       sym = get_sym();
-                       if (sym != YY__LPAREN) {
-                               yy_error_sym("'(' expected, got", sym);
-                       }
-                       sym = get_sym();
-                       if (sym != YY__LPAREN) {
-                               yy_error_sym("'(' expected, got", sym);
-                       }
-                       sym = get_sym();
-                       sym = parse_attrib(sym, dcl);
-                       while (sym == YY__COMMA) {
+               switch (sym) {
+                       case YY___ATTRIBUTE:
+                       case YY___ATTRIBUTE__:
+                               sym = get_sym();
+                               if (sym != YY__LPAREN) {
+                                       yy_error_sym("'(' expected, got", sym);
+                               }
+                               sym = get_sym();
+                               if (sym != YY__LPAREN) {
+                                       yy_error_sym("'(' expected, got", sym);
+                               }
                                sym = get_sym();
                                sym = parse_attrib(sym, dcl);
-                       }
-                       if (sym != YY__RPAREN) {
-                               yy_error_sym("')' expected, got", sym);
-                       }
-                       sym = get_sym();
-                       if (sym != YY__RPAREN) {
-                               yy_error_sym("')' expected, got", sym);
-                       }
-                       sym = get_sym();
-               } else if (sym == YY___DECLSPEC) {
-                       sym = get_sym();
-                       if (sym != YY__LPAREN) {
-                               yy_error_sym("'(' expected, got", sym);
-                       }
-                       sym = get_sym();
-                       do {
-                               sym = parse_ID(sym, &name, &name_len);
-                               if (sym == YY__LPAREN) {
+                               while (sym == YY__COMMA) {
                                        sym = get_sym();
-                                       sym = parse_assignment_expression(sym, &val);
-                                       zend_ffi_add_msvc_attribute_value(dcl, name, name_len, &val);
-                                       if (sym != YY__RPAREN) {
-                                               yy_error_sym("')' expected, got", sym);
+                                       sym = parse_attrib(sym, dcl);
+                               }
+                               if (sym != YY__RPAREN) {
+                                       yy_error_sym("')' expected, got", sym);
+                               }
+                               sym = get_sym();
+                               if (sym != YY__RPAREN) {
+                                       yy_error_sym("')' expected, got", sym);
+                               }
+                               sym = get_sym();
+                               break;
+                       case YY___DECLSPEC:
+                               sym = get_sym();
+                               if (sym != YY__LPAREN) {
+                                       yy_error_sym("'(' expected, got", sym);
+                               }
+                               sym = get_sym();
+                               do {
+                                       sym = parse_ID(sym, &name, &name_len);
+                                       if (sym == YY__LPAREN) {
+                                               sym = get_sym();
+                                               sym = parse_assignment_expression(sym, &val);
+                                               zend_ffi_add_msvc_attribute_value(dcl, name, name_len, &val);
+                                               if (sym != YY__RPAREN) {
+                                                       yy_error_sym("')' expected, got", sym);
+                                               }
+                                               sym = get_sym();
                                        }
-                                       sym = get_sym();
+                               } while (sym == YY_ID);
+                               if (sym != YY__RPAREN) {
+                                       yy_error_sym("')' expected, got", sym);
                                }
-                       } while (sym == YY_ID);
-                       if (sym != YY__RPAREN) {
-                               yy_error_sym("')' expected, got", sym);
-                       }
-                       sym = get_sym();
-               } else {
-                       yy_error_sym("unexpected", sym);
+                               sym = get_sym();
+                               break;
+                       case YY___CDECL:
+                               sym = get_sym();
+                               zend_ffi_set_abi(dcl, ZEND_FFI_ABI_CDECL);
+                               break;
+                       case YY___STDCALL:
+                               sym = get_sym();
+                               zend_ffi_set_abi(dcl, ZEND_FFI_ABI_STDCALL);
+                               break;
+                       case YY___FASTCALL:
+                               sym = get_sym();
+                               zend_ffi_set_abi(dcl, ZEND_FFI_ABI_FASTCALL);
+                               break;
+                       case YY___THISCALL:
+                               sym = get_sym();
+                               zend_ffi_set_abi(dcl, ZEND_FFI_ABI_THISCALL);
+                               break;
+                       case YY___VECTORCALL:
+                               sym = get_sym();
+                               zend_ffi_set_abi(dcl, ZEND_FFI_ABI_VECTORCALL);
+                               break;
+                       default:
+                               yy_error_sym("unexpected", sym);
                }
-       } while (sym == YY___ATTRIBUTE || sym == YY___ATTRIBUTE__ || sym == YY___DECLSPEC);
+       } while (YY_IN_SET(sym, (YY___ATTRIBUTE,YY___ATTRIBUTE__,YY___DECLSPEC,YY___CDECL,YY___STDCALL,YY___FASTCALL,YY___THISCALL,YY___VECTORCALL), "\000\000\000\000\000\000\360\017\000\000\000\000\000"));
        return sym;
 }
 
@@ -3006,7 +3015,7 @@ static int parse_initializer(int sym) {
                yy_error_sym("'=' expected, got", sym);
        }
        sym = get_sym();
-       if (YY_IN_SET(sym, (YY__LPAREN,YY_ID,YY_OCTNUMBER,YY_DECNUMBER,YY_HEXNUMBER,YY_FLOATNUMBER,YY_STRING,YY_CHARACTER,YY__PLUS_PLUS,YY__MINUS_MINUS,YY__AND,YY__STAR,YY__PLUS,YY__MINUS,YY__TILDE,YY__BANG,YY_SIZEOF,YY__ALIGNOF,YY___ALIGNOF,YY___ALIGNOF__), "\010\000\000\000\000\000\040\000\004\030\377\376\000")) {
+       if (YY_IN_SET(sym, (YY__LPAREN,YY_ID,YY_OCTNUMBER,YY_DECNUMBER,YY_HEXNUMBER,YY_FLOATNUMBER,YY_STRING,YY_CHARACTER,YY__PLUS_PLUS,YY__MINUS_MINUS,YY__AND,YY__STAR,YY__PLUS,YY__MINUS,YY__TILDE,YY__BANG,YY_SIZEOF,YY__ALIGNOF,YY___ALIGNOF,YY___ALIGNOF__), "\010\000\000\000\000\000\001\000\004\030\377\376\000")) {
                sym = parse_assignment_expression(sym, &dummy);
        } else if (sym == YY__LBRACE) {
                sym = get_sym();
@@ -3313,7 +3322,7 @@ static int parse_unary_expression(int sym, zend_ffi_val *val) {
                case YY_ID:
                        sym = parse_ID(sym, &name, &name_len);
                        zend_ffi_resolve_const(name, name_len, val);
-                       while (YY_IN_SET(sym, (YY__LBRACK,YY__LPAREN,YY__POINT,YY__MINUS_GREATER,YY__PLUS_PLUS,YY__MINUS_MINUS), "\010\000\000\000\000\000\100\020\000\200\003\000\000")) {
+                       while (YY_IN_SET(sym, (YY__LBRACK,YY__LPAREN,YY__POINT,YY__MINUS_GREATER,YY__PLUS_PLUS,YY__MINUS_MINUS), "\010\000\000\000\000\000\002\020\000\200\003\000\000")) {
                                switch (sym) {
                                        case YY__LBRACK:
                                                sym = get_sym();
@@ -3325,7 +3334,7 @@ static int parse_unary_expression(int sym, zend_ffi_val *val) {
                                                break;
                                        case YY__LPAREN:
                                                sym = get_sym();
-                                               if (YY_IN_SET(sym, (YY__LPAREN,YY_ID,YY_OCTNUMBER,YY_DECNUMBER,YY_HEXNUMBER,YY_FLOATNUMBER,YY_STRING,YY_CHARACTER,YY__PLUS_PLUS,YY__MINUS_MINUS,YY__AND,YY__STAR,YY__PLUS,YY__MINUS,YY__TILDE,YY__BANG,YY_SIZEOF,YY__ALIGNOF,YY___ALIGNOF,YY___ALIGNOF__), "\010\000\000\000\000\000\040\000\004\030\377\376\000")) {
+                                               if (YY_IN_SET(sym, (YY__LPAREN,YY_ID,YY_OCTNUMBER,YY_DECNUMBER,YY_HEXNUMBER,YY_FLOATNUMBER,YY_STRING,YY_CHARACTER,YY__PLUS_PLUS,YY__MINUS_MINUS,YY__AND,YY__STAR,YY__PLUS,YY__MINUS,YY__TILDE,YY__BANG,YY_SIZEOF,YY__ALIGNOF,YY___ALIGNOF,YY___ALIGNOF__), "\010\000\000\000\000\000\001\000\004\030\377\376\000")) {
                                                        sym = parse_expr_list(sym);
                                                }
                                                if (sym != YY__RPAREN) {
@@ -3427,7 +3436,7 @@ static int parse_unary_expression(int sym, zend_ffi_val *val) {
                                }
                                sym = get_sym();
                                zend_ffi_expr_sizeof_type(val, &dcl);
-                       } else if (YY_IN_SET(sym, (YY_ID,YY_OCTNUMBER,YY_DECNUMBER,YY_HEXNUMBER,YY_FLOATNUMBER,YY_STRING,YY_CHARACTER,YY__LPAREN,YY__PLUS_PLUS,YY__MINUS_MINUS,YY__AND,YY__STAR,YY__PLUS,YY__MINUS,YY__TILDE,YY__BANG,YY_SIZEOF,YY__ALIGNOF,YY___ALIGNOF,YY___ALIGNOF__), "\010\000\000\000\000\000\040\000\004\030\377\376\000")) {
+                       } else if (YY_IN_SET(sym, (YY_ID,YY_OCTNUMBER,YY_DECNUMBER,YY_HEXNUMBER,YY_FLOATNUMBER,YY_STRING,YY_CHARACTER,YY__LPAREN,YY__PLUS_PLUS,YY__MINUS_MINUS,YY__AND,YY__STAR,YY__PLUS,YY__MINUS,YY__TILDE,YY__BANG,YY_SIZEOF,YY__ALIGNOF,YY___ALIGNOF,YY___ALIGNOF__), "\010\000\000\000\000\000\001\000\004\030\377\376\000")) {
                                sym = parse_unary_expression(sym, val);
                                zend_ffi_expr_sizeof_val(val);
                        } else {
@@ -3458,7 +3467,7 @@ static int parse_unary_expression(int sym, zend_ffi_val *val) {
                                }
                                sym = get_sym();
                                zend_ffi_expr_alignof_type(val, &dcl);
-                       } else if (YY_IN_SET(sym, (YY_ID,YY_OCTNUMBER,YY_DECNUMBER,YY_HEXNUMBER,YY_FLOATNUMBER,YY_STRING,YY_CHARACTER,YY__LPAREN,YY__PLUS_PLUS,YY__MINUS_MINUS,YY__AND,YY__STAR,YY__PLUS,YY__MINUS,YY__TILDE,YY__BANG,YY_SIZEOF,YY__ALIGNOF,YY___ALIGNOF,YY___ALIGNOF__), "\010\000\000\000\000\000\040\000\004\030\377\376\000")) {
+                       } else if (YY_IN_SET(sym, (YY_ID,YY_OCTNUMBER,YY_DECNUMBER,YY_HEXNUMBER,YY_FLOATNUMBER,YY_STRING,YY_CHARACTER,YY__LPAREN,YY__PLUS_PLUS,YY__MINUS_MINUS,YY__AND,YY__STAR,YY__PLUS,YY__MINUS,YY__TILDE,YY__BANG,YY_SIZEOF,YY__ALIGNOF,YY___ALIGNOF,YY___ALIGNOF__), "\010\000\000\000\000\000\001\000\004\030\377\376\000")) {
                                sym = parse_unary_expression(sym, val);
                                zend_ffi_expr_alignof_val(val);
                        } else {
diff --git a/ext/ffi/tests/bug78714.phpt b/ext/ffi/tests/bug78714.phpt
new file mode 100644 (file)
index 0000000..c99607c
--- /dev/null
@@ -0,0 +1,13 @@
+--TEST--
+Bug #78714 (funcs returning pointer can't use call convention spec)
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--INI--
+ffi.enable=1
+--FILE--
+<?php
+$ffi = FFI::cdef('char * __cdecl get_zend_version(void);');
+echo substr(FFI::string($ffi->get_zend_version()), 0, 4) . "\n";
+?>
+--EXPECT--
+Zend