]> granicus.if.org Git - php/commitdiff
Added support for more GCC extensions: attributes, __extension__, __asm__ (ignored)
authorDmitry Stogov <dmitry@zend.com>
Thu, 28 Mar 2019 23:36:55 +0000 (02:36 +0300)
committerDmitry Stogov <dmitry@zend.com>
Thu, 28 Mar 2019 23:36:55 +0000 (02:36 +0300)
ext/ffi/ffi.c
ext/ffi/ffi.g
ext/ffi/ffi_parser.c

index 5ee1cadbf4c33be114f9f55ef479d42d1e1d1979..7b8591f0b6323c058e2c7bf17d6d60ea06e64c4b 100644 (file)
@@ -1149,7 +1149,7 @@ static void zend_ffi_cdata_write_dim(zval *object, zval *offset, zval *value) /*
                zend_throw_error(zend_ffi_exception_ce, "Cannot add next element to object of type FFI\\CData");
                return;
        }
-       
+
        dim = zval_get_long(offset);
        if (EXPECTED(type->kind == ZEND_FFI_TYPE_ARRAY)) {
                if (UNEXPECTED((zend_ulong)(dim) >= (zend_ulong)type->array.length)
@@ -5946,69 +5946,166 @@ void zend_ffi_set_abi(zend_ffi_dcl *dcl, uint16_t abi) /* {{{ */
 # define __BIGGEST_ALIGNMENT__ sizeof(size_t)
 #endif
 
+#define SIMPLE_ATTRIBUTES(_) \
+       _(cdecl) \
+       _(fastcall) \
+       _(thiscall) \
+       _(stdcall) \
+       _(ms_abi) \
+       _(sysv_abi) \
+       _(aligned) \
+       _(packed) \
+       _(ms_struct) \
+       _(gcc_struct) \
+       _(const) \
+       _(malloc) \
+       _(deprecated) \
+       _(nothrow) \
+       _(leaf) \
+       _(pure) \
+       _(noreturn) \
+       _(warn_unused_result)
+
+#define ATTR_ID(name)   attr_ ## name,
+#define ATTR_NAME(name) {sizeof(#name)-1, #name},
+
 void zend_ffi_add_attribute(zend_ffi_dcl *dcl, const char *name, size_t name_len) /* {{{ */
 {
-       if (name_len == sizeof("cdecl")-1 && memcmp(name, "cdecl", sizeof("cdecl")-1) == 0) {
-               zend_ffi_set_abi(dcl, ZEND_FFI_ABI_CDECL);
-       } else if (name_len == sizeof("fastcall")-1 && memcmp(name, "fastcall", sizeof("fastcall")-1) == 0) {
-               zend_ffi_set_abi(dcl, ZEND_FFI_ABI_FASTCALL);
-       } else if (name_len == sizeof("thiscall")-1 && memcmp(name, "thiscall", sizeof("thiscall")-1) == 0) {
-               zend_ffi_set_abi(dcl, ZEND_FFI_ABI_THISCALL);
-       } else if (name_len == sizeof("stdcall")-1 && memcmp(name, "stdcall", sizeof("stdcall")-1) == 0) {
-               zend_ffi_set_abi(dcl, ZEND_FFI_ABI_STDCALL);
-       } else if (name_len == sizeof("ms_abi")-1 && memcmp(name, "ms_abi", sizeof("ms_abi")-1) == 0) {
-               zend_ffi_set_abi(dcl, ZEND_FFI_ABI_MS);
-       } else if (name_len == sizeof("sysv_abi")-1 && memcmp(name, "sysv_abi", sizeof("sysv_abi")-1) == 0) {
-               zend_ffi_set_abi(dcl, ZEND_FFI_ABI_SYSV);
-       } else if (name_len == sizeof("aligned")-1 && memcmp(name, "aligned", sizeof("aligned")-1) == 0) {
-               dcl->align = __BIGGEST_ALIGNMENT__;
-       } else if (name_len == sizeof("packed")-1 && memcmp(name, "packed", sizeof("packed")-1) == 0) {
-               dcl->attr |= ZEND_FFI_ATTR_PACKED;
-       } else if (name_len == sizeof("ms_struct")-1 && memcmp(name, "ms_struct", sizeof("ms_struct")-1) == 0) {
-               dcl->attr |= ZEND_FFI_ATTR_MS_STRUCT;
-       } else if (name_len == sizeof("gcc_struct")-1 && memcmp(name, "gcc_struct", sizeof("gcc_struct")-1) == 0) {
-               dcl->attr |= ZEND_FFI_ATTR_GCC_STRUCT;
-       } else if (name_len == sizeof("const")-1 && memcmp(name, "const", sizeof("const")-1) == 0) {
-               /* ignore */
-       } else if (name_len == sizeof("malloc")-1 && memcmp(name, "malloc", sizeof("malloc")-1) == 0) {
-               /* ignore */
-       } else if (name_len == sizeof("deprecated")-1 && memcmp(name, "deprecated", sizeof("deprecated")-1) == 0) {
-               /* ignore */
-       } else if (name_len == sizeof("__nothrow__")-1 && memcmp(name, "__nothrow__", sizeof("__nothrow__")-1) == 0) {
-               /* ignore */
-       } else if (name_len == sizeof("__leaf__")-1 && memcmp(name, "__leaf__", sizeof("__leaf__")-1) == 0) {
-               /* ignore */
-       } else if (name_len == sizeof("__malloc__")-1 && memcmp(name, "__malloc__", sizeof("__malloc__")-1) == 0) {
-               /* ignore */
-       } else {
-               zend_ffi_parser_error("unsupported attribute '%.*s' at line %d", name_len, name, FFI_G(line));
+       enum {
+               SIMPLE_ATTRIBUTES(ATTR_ID)
+               attr_unsupported
+       };
+       static const struct {
+               size_t len;
+               const char * const name;
+       } names[] = {
+               SIMPLE_ATTRIBUTES(ATTR_NAME)
+               {0, NULL}
+       };
+       int id;
+
+       if (name_len > 4
+        && name[0] == '_'
+        && name[1] == '_'
+        && name[name_len-2] == '_'
+        && name[name_len-1] == '_') {
+               name += 2;
+               name_len -= 4;
+       }
+       for (id = 0; names[id].len != 0; id++) {
+               if (name_len == names[id].len) {
+                       if (memcmp(name, names[id].name, name_len) == 0) {
+                               break;
+                       }
+               }
+       }
+       switch (id) {
+               case attr_cdecl:
+                       zend_ffi_set_abi(dcl, ZEND_FFI_ABI_CDECL);
+                       break;
+               case attr_fastcall:
+                       zend_ffi_set_abi(dcl, ZEND_FFI_ABI_FASTCALL);
+                       break;
+               case attr_thiscall:
+                       zend_ffi_set_abi(dcl, ZEND_FFI_ABI_THISCALL);
+                       break;
+               case attr_stdcall:
+                       zend_ffi_set_abi(dcl, ZEND_FFI_ABI_STDCALL);
+                       break;
+               case attr_ms_abi:
+                       zend_ffi_set_abi(dcl, ZEND_FFI_ABI_MS);
+                       break;
+               case attr_sysv_abi:
+                       zend_ffi_set_abi(dcl, ZEND_FFI_ABI_SYSV);
+                       break;
+               case attr_aligned:
+                       dcl->align = __BIGGEST_ALIGNMENT__;
+                       break;
+               case attr_packed:
+                       dcl->attr |= ZEND_FFI_ATTR_PACKED;
+                       break;
+               case attr_ms_struct:
+                       dcl->attr |= ZEND_FFI_ATTR_MS_STRUCT;
+                       break;
+               case attr_gcc_struct:
+                       dcl->attr |= ZEND_FFI_ATTR_GCC_STRUCT;
+                       break;
+               case attr_unsupported:
+                       zend_ffi_parser_error("unsupported attribute '%.*s' at line %d", name_len, name, FFI_G(line));
+                       break;
+               default:
+                       /* ignore */
+                       break;
        }
 }
 /* }}} */
 
+#define VALUE_ATTRIBUTES(_) \
+       _(regparam) \
+       _(aligned) \
+       _(mode) \
+       _(nonnull) \
+       _(alloc_size) \
+       _(format) \
+       _(deprecated)
+
 void zend_ffi_add_attribute_value(zend_ffi_dcl *dcl, const char *name, size_t name_len, int n, zend_ffi_val *val) /* {{{ */
 {
-       if (n == 0 && name_len == sizeof("regparam")-1 && memcmp(name, "regparam", sizeof("regparam")-1) == 0) {
-               if ((val->kind == ZEND_FFI_VAL_INT32 || val->kind == ZEND_FFI_VAL_UINT32 || val->kind == ZEND_FFI_VAL_INT64 || val->kind == ZEND_FFI_VAL_UINT64) && val->i64 == 3) {
-                       zend_ffi_set_abi(dcl, ZEND_FFI_ABI_REGISTER);
-               } else {
-                       zend_ffi_parser_error("incorrect 'regparam' value at line %d", FFI_G(line));
-               }
-       } else if (n == 0 && name_len == sizeof("aligned")-1 && memcmp(name, "aligned", sizeof("aligned")-1) == 0) {
-               if ((val->kind == ZEND_FFI_VAL_INT32 || val->kind == ZEND_FFI_VAL_UINT32 || val->kind == ZEND_FFI_VAL_INT64 || val->kind == ZEND_FFI_VAL_UINT64)
-                && val->i64 > 0 && val->i64 <= 0x80000000 && (val->i64 & (val->i64 - 1)) == 0) {
-                       dcl->align = val->i64;
-               } else {
-                       zend_ffi_parser_error("incorrect 'alignemnt' value at line %d", FFI_G(line));
+       enum {
+               VALUE_ATTRIBUTES(ATTR_ID)
+               attr_unsupported
+       };
+       static const struct {
+               size_t len;
+               const char * const name;
+       } names[] = {
+               VALUE_ATTRIBUTES(ATTR_NAME)
+               {0, NULL}
+       };
+       int id;
+
+       if (name_len > 4
+        && name[0] == '_'
+        && name[1] == '_'
+        && name[name_len-2] == '_'
+        && name[name_len-1] == '_') {
+               name += 2;
+               name_len -= 4;
+       }
+       for (id = 0; names[id].len != 0; id++) {
+               if (name_len == names[id].len) {
+                       if (memcmp(name, names[id].name, name_len) == 0) {
+                               break;
+                       }
                }
-       } else if (name_len == sizeof("format")-1 && memcmp(name, "format", sizeof("format")-1) == 0) {
-               /* ignore */
-       } else if (name_len == sizeof("__format__")-1 && memcmp(name, "__format__", sizeof("__format__")-1) == 0) {
-               /* ignore */
-       } else if (name_len == sizeof("deprecated")-1 && memcmp(name, "deprecated", sizeof("deprecated")-1) == 0) {
-               /* ignore */
-       } else {
-               zend_ffi_parser_error("unsupported attribute '%.*s' at line %d", name_len, name, FFI_G(line));
+       }
+       switch (id) {
+               case attr_regparam:
+                       if (n == 0
+                        && (val->kind == ZEND_FFI_VAL_INT32 || val->kind == ZEND_FFI_VAL_UINT32 || val->kind == ZEND_FFI_VAL_INT64 || val->kind == ZEND_FFI_VAL_UINT64)
+                        && val->i64 == 3) {
+                               zend_ffi_set_abi(dcl, ZEND_FFI_ABI_REGISTER);
+                       } else {
+                               zend_ffi_parser_error("incorrect 'regparam' value at line %d", FFI_G(line));
+                       }
+                       break;
+               case attr_aligned:
+                       if (n == 0
+                        && (val->kind == ZEND_FFI_VAL_INT32 || val->kind == ZEND_FFI_VAL_UINT32 || val->kind == ZEND_FFI_VAL_INT64 || val->kind == ZEND_FFI_VAL_UINT64)
+                        && val->i64 > 0 && val->i64 <= 0x80000000 && (val->i64 & (val->i64 - 1)) == 0) {
+                               dcl->align = val->i64;
+                       } else {
+                               zend_ffi_parser_error("incorrect 'alignemnt' value at line %d", FFI_G(line));
+                       }
+                       break;
+               case attr_mode:
+                       // TODO: ???
+               case attr_unsupported:
+                       zend_ffi_parser_error("unsupported attribute '%.*s' at line %d", name_len, name, FFI_G(line));
+                       break;
+               default:
+                       /* ignore */
+                       break;
        }
 }
 /* }}} */
index 7c950ec95f1b1898d682bcfc4ede86de399a2047..a1dde95c6424989775d6e779a4a2d2e7104a0911 100644 (file)
@@ -69,6 +69,7 @@ static void yy_error_sym(const char *msg, int sym);
 declarations:
        (
                {zend_ffi_dcl common_dcl = ZEND_FFI_ATTR_INIT;}
+               "__extension__"?
                declaration_specifiers(&common_dcl)
                (
                        {const char *name;}
@@ -76,6 +77,14 @@ declarations:
                        {zend_ffi_dcl dcl;}
                        {dcl = common_dcl;}
                        declarator(&dcl, &name, &name_len)
+                       (
+                               {zend_ffi_val asm_str;}
+                               "__asm__"
+                               "("
+                               STRING(&asm_str)+
+                               /*TODO*/
+                               ")"
+                       )?
                        attributes(&dcl)?
                        initializer?
                        {zend_ffi_declare(name, name_len, &dcl);}
@@ -140,6 +149,7 @@ declaration_specifiers(zend_ffi_dcl *dcl):
 ;
 
 specifier_qualifier_list(zend_ffi_dcl *dcl):
+       "__extension__"?
        (       ?{sym != YY_ID || zend_ffi_is_typedef_name((const char*)yy_text, yy_pos - yy_text)}
                (       type_specifier(dcl)
                |       type_qualifier(dcl)
@@ -498,6 +508,9 @@ attrib(zend_ffi_dcl *dcl):
                        )*
                        ")"
                )
+       |       "const"
+       |       "__const"
+       |       "__const__"
        )?
 ;
 
index 9fc1321ddc53970fcea20d260946cc90cc446c51..94fb11d17b8d9c0f35fbfc02de56dc11247e30a9 100644 (file)
@@ -41,105 +41,111 @@ static void yy_error_sym(const char *msg, int sym);
 #define YYEND cend
 
 #define YY_EOF 0
-#define YY__COMMA 1
-#define YY__SEMICOLON 2
-#define YY_TYPEDEF 3
-#define YY_EXTERN 4
-#define YY_STATIC 5
-#define YY_AUTO 6
-#define YY_REGISTER 7
-#define YY_INLINE 8
-#define YY___INLINE 9
-#define YY___INLINE__ 10
-#define YY__NORETURN 11
-#define YY___CDECL 12
-#define YY___STDCALL 13
-#define YY___FASTCALL 14
-#define YY___THISCALL 15
-#define YY__ALIGNAS 16
-#define YY__LPAREN 17
-#define YY__RPAREN 18
-#define YY_CONST 19
-#define YY___CONST 20
-#define YY___CONST__ 21
-#define YY_RESTRICT 22
-#define YY___RESTRICT 23
-#define YY___RESTRICT__ 24
-#define YY_VOLATILE 25
-#define YY___VOLATILE 26
-#define YY___VOLATILE__ 27
-#define YY__ATOMIC 28
-#define YY_VOID 29
-#define YY_CHAR 30
-#define YY_SHORT 31
-#define YY_INT 32
-#define YY_LONG 33
-#define YY_FLOAT 34
-#define YY_DOUBLE 35
-#define YY_SIGNED 36
-#define YY_UNSIGNED 37
-#define YY__BOOL 38
-#define YY__COMPLEX 39
-#define YY_COMPLEX 40
-#define YY___COMPLEX 41
-#define YY___COMPLEX__ 42
-#define YY_STRUCT 43
-#define YY_UNION 44
-#define YY__LBRACE 45
-#define YY__RBRACE 46
-#define YY__COLON 47
-#define YY_ENUM 48
-#define YY__EQUAL 49
-#define YY__STAR 50
-#define YY__LBRACK 51
-#define YY__RBRACK 52
-#define YY__POINT_POINT_POINT 53
-#define YY___ATTRIBUTE 54
-#define YY___ATTRIBUTE__ 55
-#define YY___DECLSPEC 56
-#define YY__POINT 57
-#define YY__QUERY 58
-#define YY__BAR_BAR 59
-#define YY__AND_AND 60
-#define YY__BAR 61
-#define YY__UPARROW 62
-#define YY__AND 63
-#define YY__EQUAL_EQUAL 64
-#define YY__BANG_EQUAL 65
-#define YY__LESS 66
-#define YY__GREATER 67
-#define YY__LESS_EQUAL 68
-#define YY__GREATER_EQUAL 69
-#define YY__LESS_LESS 70
-#define YY__GREATER_GREATER 71
-#define YY__PLUS 72
-#define YY__MINUS 73
-#define YY__SLASH 74
-#define YY__PERCENT 75
-#define YY__MINUS_GREATER 76
-#define YY__PLUS_PLUS 77
-#define YY__MINUS_MINUS 78
-#define YY__TILDE 79
-#define YY__BANG 80
-#define YY_SIZEOF 81
-#define YY__ALIGNOF 82
-#define YY___ALIGNOF 83
-#define YY___ALIGNOF__ 84
-#define YY___RESTICT 85
-#define YY_ID 86
-#define YY_OCTNUMBER 87
-#define YY_DECNUMBER 88
-#define YY_HEXNUMBER 89
-#define YY_FLOATNUMBER 90
-#define YY_STRING 91
-#define YY_CHARACTER 92
-#define YY_EOL 93
-#define YY_WS 94
-#define YY_ONE_LINE_COMMENT 95
-#define YY_COMMENT 96
+#define YY___EXTENSION__ 1
+#define YY___ASM__ 2
+#define YY__LPAREN 3
+#define YY__RPAREN 4
+#define YY__COMMA 5
+#define YY__SEMICOLON 6
+#define YY_TYPEDEF 7
+#define YY_EXTERN 8
+#define YY_STATIC 9
+#define YY_AUTO 10
+#define YY_REGISTER 11
+#define YY_INLINE 12
+#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__ALIGNAS 20
+#define YY_CONST 21
+#define YY___CONST 22
+#define YY___CONST__ 23
+#define YY_RESTRICT 24
+#define YY___RESTRICT 25
+#define YY___RESTRICT__ 26
+#define YY_VOLATILE 27
+#define YY___VOLATILE 28
+#define YY___VOLATILE__ 29
+#define YY__ATOMIC 30
+#define YY_VOID 31
+#define YY_CHAR 32
+#define YY_SHORT 33
+#define YY_INT 34
+#define YY_LONG 35
+#define YY_FLOAT 36
+#define YY_DOUBLE 37
+#define YY_SIGNED 38
+#define YY_UNSIGNED 39
+#define YY__BOOL 40
+#define YY__COMPLEX 41
+#define YY_COMPLEX 42
+#define YY___COMPLEX 43
+#define YY___COMPLEX__ 44
+#define YY_STRUCT 45
+#define YY_UNION 46
+#define YY__LBRACE 47
+#define YY__RBRACE 48
+#define YY__COLON 49
+#define YY_ENUM 50
+#define YY__EQUAL 51
+#define YY__STAR 52
+#define YY__LBRACK 53
+#define YY__RBRACK 54
+#define YY__POINT_POINT_POINT 55
+#define YY___ATTRIBUTE 56
+#define YY___ATTRIBUTE__ 57
+#define YY___DECLSPEC 58
+#define YY__POINT 59
+#define YY__QUERY 60
+#define YY__BAR_BAR 61
+#define YY__AND_AND 62
+#define YY__BAR 63
+#define YY__UPARROW 64
+#define YY__AND 65
+#define YY__EQUAL_EQUAL 66
+#define YY__BANG_EQUAL 67
+#define YY__LESS 68
+#define YY__GREATER 69
+#define YY__LESS_EQUAL 70
+#define YY__GREATER_EQUAL 71
+#define YY__LESS_LESS 72
+#define YY__GREATER_GREATER 73
+#define YY__PLUS 74
+#define YY__MINUS 75
+#define YY__SLASH 76
+#define YY__PERCENT 77
+#define YY__MINUS_GREATER 78
+#define YY__PLUS_PLUS 79
+#define YY__MINUS_MINUS 80
+#define YY__TILDE 81
+#define YY__BANG 82
+#define YY_SIZEOF 83
+#define YY__ALIGNOF 84
+#define YY___ALIGNOF 85
+#define YY___ALIGNOF__ 86
+#define YY___RESTICT 87
+#define YY_ID 88
+#define YY_OCTNUMBER 89
+#define YY_DECNUMBER 90
+#define YY_HEXNUMBER 91
+#define YY_FLOATNUMBER 92
+#define YY_STRING 93
+#define YY_CHARACTER 94
+#define YY_EOL 95
+#define YY_WS 96
+#define YY_ONE_LINE_COMMENT 97
+#define YY_COMMENT 98
 
 static const char * sym_name[] = {
        "<EOF>",
+       "__extension__",
+       "__asm__",
+       "(",
+       ")",
        ",",
        ";",
        "typedef",
@@ -156,8 +162,6 @@ static const char * sym_name[] = {
        "__fastcall",
        "__thiscall",
        "_Alignas",
-       "(",
-       ")",
        "const",
        "__const",
        "__const__",
@@ -317,171 +321,35 @@ _yy_state_start:
        yy_text = YYPOS;
        ch = *YYPOS;
        switch (ch) {
-               case 't':
-                       ch = *++YYPOS;
-                       if (ch != 'y') 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 != 'd') goto _yy_tunnel_9;
-                       ch = *++YYPOS;
-                       if (ch != 'e') goto _yy_tunnel_9;
-                       ch = *++YYPOS;
-                       if (ch != 'f') goto _yy_tunnel_9;
-                       ret = YY_TYPEDEF;
-                       goto _yy_state_366;
-               case 'e':
-                       ch = *++YYPOS;
-                       if (ch == 'x') {
-                               ch = *++YYPOS;
-                               if (ch != 't') goto _yy_tunnel_9;
-                               ch = *++YYPOS;
-                               if (ch != 'e') goto _yy_tunnel_9;
-                               ch = *++YYPOS;
-                               if (ch != 'r') goto _yy_tunnel_9;
-                               ch = *++YYPOS;
-                               if (ch != 'n') goto _yy_tunnel_9;
-                               ret = YY_EXTERN;
-                               goto _yy_state_366;
-                       } else if (ch == 'n') {
-                               ch = *++YYPOS;
-                               if (ch != 'u') goto _yy_tunnel_9;
-                               ch = *++YYPOS;
-                               if (ch != 'm') goto _yy_tunnel_9;
-                               ret = YY_ENUM;
-                               goto _yy_state_366;
-                       } else {
-                               goto _yy_tunnel_9;
-                       }
-               case 's':
-                       ch = *++YYPOS;
-                       if (ch == 't') {
-                               ch = *++YYPOS;
-                               if (ch == 'a') {
-                                       ch = *++YYPOS;
-                                       if (ch != 't') goto _yy_tunnel_9;
-                                       ch = *++YYPOS;
-                                       if (ch != 'i') goto _yy_tunnel_9;
-                                       ch = *++YYPOS;
-                                       if (ch != 'c') goto _yy_tunnel_9;
-                                       ret = YY_STATIC;
-                                       goto _yy_state_366;
-                               } else if (ch == 'r') {
-                                       ch = *++YYPOS;
-                                       if (ch != 'u') goto _yy_tunnel_9;
-                                       ch = *++YYPOS;
-                                       if (ch != 'c') goto _yy_tunnel_9;
-                                       ch = *++YYPOS;
-                                       if (ch != 't') goto _yy_tunnel_9;
-                                       ret = YY_STRUCT;
-                                       goto _yy_state_366;
-                               } else {
-                                       goto _yy_tunnel_9;
-                               }
-                       } else if (ch == 'h') {
-                               ch = *++YYPOS;
-                               if (ch != 'o') goto _yy_tunnel_9;
-                               ch = *++YYPOS;
-                               if (ch != 'r') goto _yy_tunnel_9;
-                               ch = *++YYPOS;
-                               if (ch != 't') goto _yy_tunnel_9;
-                               ret = YY_SHORT;
-                               goto _yy_state_366;
-                       } else if (ch == 'i') {
-                               ch = *++YYPOS;
-                               if (ch == 'g') {
-                                       ch = *++YYPOS;
-                                       if (ch != 'n') goto _yy_tunnel_9;
-                                       ch = *++YYPOS;
-                                       if (ch != 'e') goto _yy_tunnel_9;
-                                       ch = *++YYPOS;
-                                       if (ch != 'd') goto _yy_tunnel_9;
-                                       ret = YY_SIGNED;
-                                       goto _yy_state_366;
-                               } else if (ch == 'z') {
-                                       ch = *++YYPOS;
-                                       if (ch != 'e') goto _yy_tunnel_9;
-                                       ch = *++YYPOS;
-                                       if (ch != 'o') goto _yy_tunnel_9;
-                                       ch = *++YYPOS;
-                                       if (ch != 'f') goto _yy_tunnel_9;
-                                       ret = YY_SIZEOF;
-                                       goto _yy_state_366;
-                               } else {
-                                       goto _yy_tunnel_9;
-                               }
-                       } else {
-                               goto _yy_tunnel_9;
-                       }
-               case 'a':
-                       ch = *++YYPOS;
-                       if (ch != 'u') goto _yy_tunnel_9;
-                       ch = *++YYPOS;
-                       if (ch != 't') goto _yy_tunnel_9;
-                       ch = *++YYPOS;
-                       if (ch != 'o') goto _yy_tunnel_9;
-                       ret = YY_AUTO;
-                       goto _yy_state_366;
-               case 'r':
-                       ch = *++YYPOS;
-                       if (ch != 'e') goto _yy_tunnel_9;
-                       ch = *++YYPOS;
-                       if (ch == 'g') {
-                               ch = *++YYPOS;
-                               if (ch != 'i') 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 != 'e') goto _yy_tunnel_9;
-                               ch = *++YYPOS;
-                               if (ch != 'r') goto _yy_tunnel_9;
-                               ret = YY_REGISTER;
-                               goto _yy_state_366;
-                       } else if (ch == 's') {
-                               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 != 'c') goto _yy_tunnel_9;
-                               ch = *++YYPOS;
-                               if (ch != 't') goto _yy_tunnel_9;
-                               ret = YY_RESTRICT;
-                               goto _yy_state_366;
-                       } else {
-                               goto _yy_tunnel_9;
-                       }
-               case 'i':
-                       ch = *++YYPOS;
-                       if (ch != 'n') goto _yy_tunnel_9;
-                       ch = *++YYPOS;
-                       if (ch == 'l') {
-                               ch = *++YYPOS;
-                               if (ch != 'i') goto _yy_tunnel_9;
-                               ch = *++YYPOS;
-                               if (ch != 'n') goto _yy_tunnel_9;
-                               ch = *++YYPOS;
-                               if (ch != 'e') goto _yy_tunnel_9;
-                               ret = YY_INLINE;
-                               goto _yy_state_366;
-                       } else if (ch == 't') {
-                               ret = YY_INT;
-                               goto _yy_state_366;
-                       } else {
-                               goto _yy_tunnel_9;
-                       }
                case '_':
                        ch = *++YYPOS;
                        switch (ch) {
                                case '_':
                                        ch = *++YYPOS;
                                        switch (ch) {
+                                               case 'e':
+                                                       ch = *++YYPOS;
+                                                       if (ch != 'x') 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 != 'n') goto _yy_tunnel_9;
+                                                       ch = *++YYPOS;
+                                                       if (ch != 's') goto _yy_tunnel_9;
+                                                       ch = *++YYPOS;
+                                                       if (ch != 'i') goto _yy_tunnel_9;
+                                                       ch = *++YYPOS;
+                                                       if (ch != 'o') goto _yy_tunnel_9;
+                                                       ch = *++YYPOS;
+                                                       if (ch != 'n') goto _yy_tunnel_9;
+                                                       ch = *++YYPOS;
+                                                       if (ch != '_') goto _yy_tunnel_9;
+                                                       ch = *++YYPOS;
+                                                       if (ch != '_') goto _yy_tunnel_9;
+                                                       ret = YY___EXTENSION__;
+                                                       goto _yy_state_381;
                                                case 'i':
                                                        ch = *++YYPOS;
                                                        if (ch != 'n') goto _yy_tunnel_9;
@@ -494,11 +362,11 @@ _yy_state_start:
                                                        ch = *++YYPOS;
                                                        if (ch != 'e') goto _yy_tunnel_9;
                                                        ch = *++YYPOS;
-                                                       if (ch != '_') {ret = YY___INLINE; goto _yy_tunnel_366;}
+                                                       if (ch != '_') {ret = YY___INLINE; goto _yy_tunnel_381;}
                                                        ch = *++YYPOS;
                                                        if (ch != '_') goto _yy_tunnel_9;
                                                        ret = YY___INLINE__;
-                                                       goto _yy_state_366;
+                                                       goto _yy_state_381;
                                                case 'c':
                                                        ch = *++YYPOS;
                                                        if (ch == 'd') {
@@ -509,7 +377,7 @@ _yy_state_start:
                                                                ch = *++YYPOS;
                                                                if (ch != 'l') goto _yy_tunnel_9;
                                                                ret = YY___CDECL;
-                                                               goto _yy_state_366;
+                                                               goto _yy_state_381;
                                                        } else if (ch == 'o') {
                                                                ch = *++YYPOS;
                                                                if (ch == 'm') {
@@ -522,22 +390,22 @@ _yy_state_start:
                                                                        ch = *++YYPOS;
                                                                        if (ch != 'x') goto _yy_tunnel_9;
                                                                        ch = *++YYPOS;
-                                                                       if (ch != '_') {ret = YY___COMPLEX; goto _yy_tunnel_366;}
+                                                                       if (ch != '_') {ret = YY___COMPLEX; goto _yy_tunnel_381;}
                                                                        ch = *++YYPOS;
                                                                        if (ch != '_') goto _yy_tunnel_9;
                                                                        ret = YY___COMPLEX__;
-                                                                       goto _yy_state_366;
+                                                                       goto _yy_state_381;
                                                                } else if (ch == 'n') {
                                                                        ch = *++YYPOS;
                                                                        if (ch != 's') goto _yy_tunnel_9;
                                                                        ch = *++YYPOS;
                                                                        if (ch != 't') goto _yy_tunnel_9;
                                                                        ch = *++YYPOS;
-                                                                       if (ch != '_') {ret = YY___CONST; goto _yy_tunnel_366;}
+                                                                       if (ch != '_') {ret = YY___CONST; goto _yy_tunnel_381;}
                                                                        ch = *++YYPOS;
                                                                        if (ch != '_') goto _yy_tunnel_9;
                                                                        ret = YY___CONST__;
-                                                                       goto _yy_state_366;
+                                                                       goto _yy_state_381;
                                                                } else {
                                                                        goto _yy_tunnel_9;
                                                                }
@@ -558,7 +426,7 @@ _yy_state_start:
                                                        ch = *++YYPOS;
                                                        if (ch != 'l') goto _yy_tunnel_9;
                                                        ret = YY___STDCALL;
-                                                       goto _yy_state_366;
+                                                       goto _yy_state_381;
                                                case 'f':
                                                        ch = *++YYPOS;
                                                        if (ch != 'a') goto _yy_tunnel_9;
@@ -575,7 +443,7 @@ _yy_state_start:
                                                        ch = *++YYPOS;
                                                        if (ch != 'l') goto _yy_tunnel_9;
                                                        ret = YY___FASTCALL;
-                                                       goto _yy_state_366;
+                                                       goto _yy_state_381;
                                                case 't':
                                                        ch = *++YYPOS;
                                                        if (ch != 'h') goto _yy_tunnel_9;
@@ -592,7 +460,7 @@ _yy_state_start:
                                                        ch = *++YYPOS;
                                                        if (ch != 'l') goto _yy_tunnel_9;
                                                        ret = YY___THISCALL;
-                                                       goto _yy_state_366;
+                                                       goto _yy_state_381;
                                                case 'a':
                                                        ch = *++YYPOS;
                                                        if (ch == 'l') {
@@ -607,11 +475,20 @@ _yy_state_start:
                                                                ch = *++YYPOS;
                                                                if (ch != 'f') goto _yy_tunnel_9;
                                                                ch = *++YYPOS;
-                                                               if (ch != '_') {ret = YY___ALIGNOF; goto _yy_tunnel_366;}
+                                                               if (ch != '_') {ret = YY___ALIGNOF; goto _yy_tunnel_381;}
                                                                ch = *++YYPOS;
                                                                if (ch != '_') goto _yy_tunnel_9;
                                                                ret = YY___ALIGNOF__;
-                                                               goto _yy_state_366;
+                                                               goto _yy_state_381;
+                                                       } 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_381;
                                                        } else if (ch == 't') {
                                                                ch = *++YYPOS;
                                                                if (ch != 't') goto _yy_tunnel_9;
@@ -628,11 +505,11 @@ _yy_state_start:
                                                                ch = *++YYPOS;
                                                                if (ch != 'e') goto _yy_tunnel_9;
                                                                ch = *++YYPOS;
-                                                               if (ch != '_') {ret = YY___ATTRIBUTE; goto _yy_tunnel_366;}
+                                                               if (ch != '_') {ret = YY___ATTRIBUTE; goto _yy_tunnel_381;}
                                                                ch = *++YYPOS;
                                                                if (ch != '_') goto _yy_tunnel_9;
                                                                ret = YY___ATTRIBUTE__;
-                                                               goto _yy_state_366;
+                                                               goto _yy_state_381;
                                                        } else {
                                                                goto _yy_tunnel_9;
                                                        }
@@ -652,7 +529,7 @@ _yy_state_start:
                                                        ch = *++YYPOS;
                                                        if (ch != 'c') goto _yy_tunnel_9;
                                                        ret = YY___DECLSPEC;
-                                                       goto _yy_state_366;
+                                                       goto _yy_state_381;
                                                case 'r':
                                                        ch = *++YYPOS;
                                                        if (ch != 'e') goto _yy_tunnel_9;
@@ -667,7 +544,7 @@ _yy_state_start:
                                                                ch = *++YYPOS;
                                                                if (ch != 't') goto _yy_tunnel_9;
                                                                ret = YY___RESTICT;
-                                                               goto _yy_state_366;
+                                                               goto _yy_state_381;
                                                        } else if (ch == 'r') {
                                                                ch = *++YYPOS;
                                                                if (ch != 'i') goto _yy_tunnel_9;
@@ -676,11 +553,11 @@ _yy_state_start:
                                                                ch = *++YYPOS;
                                                                if (ch != 't') goto _yy_tunnel_9;
                                                                ch = *++YYPOS;
-                                                               if (ch != '_') {ret = YY___RESTRICT; goto _yy_tunnel_366;}
+                                                               if (ch != '_') {ret = YY___RESTRICT; goto _yy_tunnel_381;}
                                                                ch = *++YYPOS;
                                                                if (ch != '_') goto _yy_tunnel_9;
                                                                ret = YY___RESTRICT__;
-                                                               goto _yy_state_366;
+                                                               goto _yy_state_381;
                                                        } else {
                                                                goto _yy_tunnel_9;
                                                        }
@@ -700,11 +577,11 @@ _yy_state_start:
                                                        ch = *++YYPOS;
                                                        if (ch != 'e') goto _yy_tunnel_9;
                                                        ch = *++YYPOS;
-                                                       if (ch != '_') {ret = YY___VOLATILE; goto _yy_tunnel_366;}
+                                                       if (ch != '_') {ret = YY___VOLATILE; goto _yy_tunnel_381;}
                                                        ch = *++YYPOS;
                                                        if (ch != '_') goto _yy_tunnel_9;
                                                        ret = YY___VOLATILE__;
-                                                       goto _yy_state_366;
+                                                       goto _yy_state_381;
                                                default:
                                                        goto _yy_tunnel_9;
                                        }
@@ -724,7 +601,7 @@ _yy_state_start:
                                        ch = *++YYPOS;
                                        if (ch != 'n') goto _yy_tunnel_9;
                                        ret = YY__NORETURN;
-                                       goto _yy_state_366;
+                                       goto _yy_state_381;
                                case 'A':
                                        ch = *++YYPOS;
                                        if (ch == 'l') {
@@ -739,12 +616,12 @@ _yy_state_start:
                                                        ch = *++YYPOS;
                                                        if (ch != 's') goto _yy_tunnel_9;
                                                        ret = YY__ALIGNAS;
-                                                       goto _yy_state_366;
+                                                       goto _yy_state_381;
                                                } else if (ch == 'o') {
                                                        ch = *++YYPOS;
                                                        if (ch != 'f') goto _yy_tunnel_9;
                                                        ret = YY__ALIGNOF;
-                                                       goto _yy_state_366;
+                                                       goto _yy_state_381;
                                                } else {
                                                        goto _yy_tunnel_9;
                                                }
@@ -758,7 +635,7 @@ _yy_state_start:
                                                ch = *++YYPOS;
                                                if (ch != 'c') goto _yy_tunnel_9;
                                                ret = YY__ATOMIC;
-                                               goto _yy_state_366;
+                                               goto _yy_state_381;
                                        } else {
                                                goto _yy_tunnel_9;
                                        }
@@ -770,7 +647,7 @@ _yy_state_start:
                                        ch = *++YYPOS;
                                        if (ch != 'l') goto _yy_tunnel_9;
                                        ret = YY__BOOL;
-                                       goto _yy_state_366;
+                                       goto _yy_state_381;
                                case 'C':
                                        ch = *++YYPOS;
                                        if (ch != 'o') goto _yy_tunnel_9;
@@ -785,10 +662,169 @@ _yy_state_start:
                                        ch = *++YYPOS;
                                        if (ch != 'x') goto _yy_tunnel_9;
                                        ret = YY__COMPLEX;
-                                       goto _yy_state_366;
+                                       goto _yy_state_381;
                                default:
                                        goto _yy_tunnel_9;
                        }
+               case 't':
+                       ch = *++YYPOS;
+                       if (ch != 'y') 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 != 'd') goto _yy_tunnel_9;
+                       ch = *++YYPOS;
+                       if (ch != 'e') goto _yy_tunnel_9;
+                       ch = *++YYPOS;
+                       if (ch != 'f') goto _yy_tunnel_9;
+                       ret = YY_TYPEDEF;
+                       goto _yy_state_381;
+               case 'e':
+                       ch = *++YYPOS;
+                       if (ch == 'x') {
+                               ch = *++YYPOS;
+                               if (ch != 't') goto _yy_tunnel_9;
+                               ch = *++YYPOS;
+                               if (ch != 'e') goto _yy_tunnel_9;
+                               ch = *++YYPOS;
+                               if (ch != 'r') goto _yy_tunnel_9;
+                               ch = *++YYPOS;
+                               if (ch != 'n') goto _yy_tunnel_9;
+                               ret = YY_EXTERN;
+                               goto _yy_state_381;
+                       } else if (ch == 'n') {
+                               ch = *++YYPOS;
+                               if (ch != 'u') goto _yy_tunnel_9;
+                               ch = *++YYPOS;
+                               if (ch != 'm') goto _yy_tunnel_9;
+                               ret = YY_ENUM;
+                               goto _yy_state_381;
+                       } else {
+                               goto _yy_tunnel_9;
+                       }
+               case 's':
+                       ch = *++YYPOS;
+                       if (ch == 't') {
+                               ch = *++YYPOS;
+                               if (ch == 'a') {
+                                       ch = *++YYPOS;
+                                       if (ch != 't') goto _yy_tunnel_9;
+                                       ch = *++YYPOS;
+                                       if (ch != 'i') goto _yy_tunnel_9;
+                                       ch = *++YYPOS;
+                                       if (ch != 'c') goto _yy_tunnel_9;
+                                       ret = YY_STATIC;
+                                       goto _yy_state_381;
+                               } else if (ch == 'r') {
+                                       ch = *++YYPOS;
+                                       if (ch != 'u') goto _yy_tunnel_9;
+                                       ch = *++YYPOS;
+                                       if (ch != 'c') goto _yy_tunnel_9;
+                                       ch = *++YYPOS;
+                                       if (ch != 't') goto _yy_tunnel_9;
+                                       ret = YY_STRUCT;
+                                       goto _yy_state_381;
+                               } else {
+                                       goto _yy_tunnel_9;
+                               }
+                       } else if (ch == 'h') {
+                               ch = *++YYPOS;
+                               if (ch != 'o') goto _yy_tunnel_9;
+                               ch = *++YYPOS;
+                               if (ch != 'r') goto _yy_tunnel_9;
+                               ch = *++YYPOS;
+                               if (ch != 't') goto _yy_tunnel_9;
+                               ret = YY_SHORT;
+                               goto _yy_state_381;
+                       } else if (ch == 'i') {
+                               ch = *++YYPOS;
+                               if (ch == 'g') {
+                                       ch = *++YYPOS;
+                                       if (ch != 'n') goto _yy_tunnel_9;
+                                       ch = *++YYPOS;
+                                       if (ch != 'e') goto _yy_tunnel_9;
+                                       ch = *++YYPOS;
+                                       if (ch != 'd') goto _yy_tunnel_9;
+                                       ret = YY_SIGNED;
+                                       goto _yy_state_381;
+                               } else if (ch == 'z') {
+                                       ch = *++YYPOS;
+                                       if (ch != 'e') goto _yy_tunnel_9;
+                                       ch = *++YYPOS;
+                                       if (ch != 'o') goto _yy_tunnel_9;
+                                       ch = *++YYPOS;
+                                       if (ch != 'f') goto _yy_tunnel_9;
+                                       ret = YY_SIZEOF;
+                                       goto _yy_state_381;
+                               } else {
+                                       goto _yy_tunnel_9;
+                               }
+                       } else {
+                               goto _yy_tunnel_9;
+                       }
+               case 'a':
+                       ch = *++YYPOS;
+                       if (ch != 'u') goto _yy_tunnel_9;
+                       ch = *++YYPOS;
+                       if (ch != 't') goto _yy_tunnel_9;
+                       ch = *++YYPOS;
+                       if (ch != 'o') goto _yy_tunnel_9;
+                       ret = YY_AUTO;
+                       goto _yy_state_381;
+               case 'r':
+                       ch = *++YYPOS;
+                       if (ch != 'e') goto _yy_tunnel_9;
+                       ch = *++YYPOS;
+                       if (ch == 'g') {
+                               ch = *++YYPOS;
+                               if (ch != 'i') 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 != 'e') goto _yy_tunnel_9;
+                               ch = *++YYPOS;
+                               if (ch != 'r') goto _yy_tunnel_9;
+                               ret = YY_REGISTER;
+                               goto _yy_state_381;
+                       } else if (ch == 's') {
+                               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 != 'c') goto _yy_tunnel_9;
+                               ch = *++YYPOS;
+                               if (ch != 't') goto _yy_tunnel_9;
+                               ret = YY_RESTRICT;
+                               goto _yy_state_381;
+                       } else {
+                               goto _yy_tunnel_9;
+                       }
+               case 'i':
+                       ch = *++YYPOS;
+                       if (ch != 'n') goto _yy_tunnel_9;
+                       ch = *++YYPOS;
+                       if (ch == 'l') {
+                               ch = *++YYPOS;
+                               if (ch != 'i') goto _yy_tunnel_9;
+                               ch = *++YYPOS;
+                               if (ch != 'n') goto _yy_tunnel_9;
+                               ch = *++YYPOS;
+                               if (ch != 'e') goto _yy_tunnel_9;
+                               ret = YY_INLINE;
+                               goto _yy_state_381;
+                       } else if (ch == 't') {
+                               ret = YY_INT;
+                               goto _yy_state_381;
+                       } else {
+                               goto _yy_tunnel_9;
+                       }
                case '(':
                        YYPOS++;
                        ret = YY__LPAREN;
@@ -850,7 +886,7 @@ _yy_state_start:
                                ch = *++YYPOS;
                                if (ch != 'r') goto _yy_tunnel_9;
                                ret = YY_CHAR;
-                               goto _yy_state_366;
+                               goto _yy_state_381;
                        } else if (ch == 'o') {
                                ch = *++YYPOS;
                                if (ch == 'm') {
@@ -863,14 +899,14 @@ _yy_state_start:
                                        ch = *++YYPOS;
                                        if (ch != 'x') goto _yy_tunnel_9;
                                        ret = YY_COMPLEX;
-                                       goto _yy_state_366;
+                                       goto _yy_state_381;
                                } else if (ch == 'n') {
                                        ch = *++YYPOS;
                                        if (ch != 's') goto _yy_tunnel_9;
                                        ch = *++YYPOS;
                                        if (ch != 't') goto _yy_tunnel_9;
                                        ret = YY_CONST;
-                                       goto _yy_state_366;
+                                       goto _yy_state_381;
                                } else {
                                        goto _yy_tunnel_9;
                                }
@@ -889,7 +925,7 @@ _yy_state_start:
                        ch = *++YYPOS;
                        if (ch != 'e') goto _yy_tunnel_9;
                        ret = YY_DOUBLE;
-                       goto _yy_state_366;
+                       goto _yy_state_381;
                case 'f':
                        ch = *++YYPOS;
                        if (ch != 'l') goto _yy_tunnel_9;
@@ -900,7 +936,7 @@ _yy_state_start:
                        ch = *++YYPOS;
                        if (ch != 't') goto _yy_tunnel_9;
                        ret = YY_FLOAT;
-                       goto _yy_state_366;
+                       goto _yy_state_381;
                case 'l':
                        ch = *++YYPOS;
                        if (ch != 'o') goto _yy_tunnel_9;
@@ -909,7 +945,7 @@ _yy_state_start:
                        ch = *++YYPOS;
                        if (ch != 'g') goto _yy_tunnel_9;
                        ret = YY_LONG;
-                       goto _yy_state_366;
+                       goto _yy_state_381;
                case 'u':
                        ch = *++YYPOS;
                        if (ch == 'n') {
@@ -920,7 +956,7 @@ _yy_state_start:
                                        ch = *++YYPOS;
                                        if (ch != 'n') goto _yy_tunnel_9;
                                        ret = YY_UNION;
-                                       goto _yy_state_366;
+                                       goto _yy_state_381;
                                } else if (ch == 's') {
                                        ch = *++YYPOS;
                                        if (ch != 'i') goto _yy_tunnel_9;
@@ -933,7 +969,7 @@ _yy_state_start:
                                        ch = *++YYPOS;
                                        if (ch != 'd') goto _yy_tunnel_9;
                                        ret = YY_UNSIGNED;
-                                       goto _yy_state_366;
+                                       goto _yy_state_381;
                                } else {
                                        goto _yy_tunnel_9;
                                }
@@ -956,7 +992,7 @@ _yy_state_start:
                                ch = *++YYPOS;
                                if (ch != 'd') goto _yy_tunnel_9;
                                ret = YY_VOID;
-                               goto _yy_state_366;
+                               goto _yy_state_381;
                        } else if (ch == 'l') {
                                ch = *++YYPOS;
                                if (ch != 'a') goto _yy_tunnel_9;
@@ -969,7 +1005,7 @@ _yy_state_start:
                                ch = *++YYPOS;
                                if (ch != 'e') goto _yy_tunnel_9;
                                ret = YY_VOLATILE;
-                               goto _yy_state_366;
+                               goto _yy_state_381;
                        } else {
                                goto _yy_tunnel_9;
                        }
@@ -1037,7 +1073,7 @@ _yy_state_start:
                        if (ch != 'X' && ch != 'x') goto _yy_tunnel_78;
                        ch = *++YYPOS;
                        if ((ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'F') || (ch >= 'a' && ch <= 'f')) {
-                               goto _yy_state_155;
+                               goto _yy_state_156;
                        } else {
                                goto _yy_state_error;
                        }
@@ -1242,7 +1278,7 @@ _yy_state_26:
                        accept = YY_DECNUMBER;
                        accept_pos = yy_pos;
                        if (ch == 'L') {
-                               goto _yy_state_162;
+                               goto _yy_state_163;
                        } else if (ch == 'U' || ch == 'u') {
                                YYPOS++;
                                ret = YY_DECNUMBER;
@@ -1260,7 +1296,7 @@ _yy_state_26:
                                ret = YY_DECNUMBER;
                                goto _yy_fin;
                        } else if (ch == 'l') {
-                               goto _yy_state_162;
+                               goto _yy_state_163;
                        } else {
                                ret = YY_DECNUMBER;
                                goto _yy_fin;
@@ -1421,7 +1457,7 @@ _yy_tunnel_78:
                        accept = YY_OCTNUMBER;
                        accept_pos = yy_pos;
                        if (ch == 'L') {
-                               goto _yy_state_153;
+                               goto _yy_state_154;
                        } else if (ch == 'U' || ch == 'u') {
                                YYPOS++;
                                ret = YY_OCTNUMBER;
@@ -1435,7 +1471,7 @@ _yy_tunnel_78:
                        accept = YY_OCTNUMBER;
                        accept_pos = yy_pos;
                        if (ch == 'l') {
-                               goto _yy_state_153;
+                               goto _yy_state_154;
                        } else if (ch == 'U' || ch == 'u') {
                                YYPOS++;
                                ret = YY_OCTNUMBER;
@@ -1472,12 +1508,12 @@ _yy_state_85:
        if (ch == '+' || ch == '-') {
                ch = *++YYPOS;
                if ((ch >= '0' && ch <= '9')) {
-                       goto _yy_state_158;
+                       goto _yy_state_159;
                } else {
                        goto _yy_state_error;
                }
        } else if ((ch >= '0' && ch <= '9')) {
-               goto _yy_state_158;
+               goto _yy_state_159;
        } else {
                goto _yy_state_error;
        }
@@ -1498,7 +1534,7 @@ _yy_tunnel_99:
        } else {
                goto _yy_state_error;
        }
-_yy_state_153:
+_yy_state_154:
        ch = *++YYPOS;
        if (ch == 'U' || ch == 'u') {
                YYPOS++;
@@ -1507,7 +1543,7 @@ _yy_state_153:
        } else {
                goto _yy_state_error;
        }
-_yy_state_155:
+_yy_state_156:
        ch = *++YYPOS;
        if (ch == 'U' || ch == 'u') {
                ch = *++YYPOS;
@@ -1534,7 +1570,7 @@ _yy_state_155:
                accept = YY_HEXNUMBER;
                accept_pos = yy_pos;
                if (ch == 'L') {
-                       goto _yy_state_258;
+                       goto _yy_state_263;
                } else if (ch == 'U' || ch == 'u') {
                        YYPOS++;
                        ret = YY_HEXNUMBER;
@@ -1552,21 +1588,21 @@ _yy_state_155:
                        ret = YY_HEXNUMBER;
                        goto _yy_fin;
                } else if (ch == 'l') {
-                       goto _yy_state_258;
+                       goto _yy_state_263;
                } else {
                        ret = YY_HEXNUMBER;
                        goto _yy_fin;
                }
        } else if ((ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'F') || (ch >= 'a' && ch <= 'f')) {
-               goto _yy_state_155;
+               goto _yy_state_156;
        } else {
                ret = YY_HEXNUMBER;
                goto _yy_fin;
        }
-_yy_state_158:
+_yy_state_159:
        ch = *++YYPOS;
        if ((ch >= '0' && ch <= '9')) {
-               goto _yy_state_158;
+               goto _yy_state_159;
        } else if (ch == 'F' || ch == 'L' || ch == 'f' || ch == 'l') {
                YYPOS++;
                ret = YY_FLOATNUMBER;
@@ -1575,7 +1611,7 @@ _yy_state_158:
                ret = YY_FLOATNUMBER;
                goto _yy_fin;
        }
-_yy_state_162:
+_yy_state_163:
        ch = *++YYPOS;
        if (ch == 'U' || ch == 'u') {
                YYPOS++;
@@ -1584,7 +1620,7 @@ _yy_state_162:
        } else {
                goto _yy_state_error;
        }
-_yy_state_258:
+_yy_state_263:
        ch = *++YYPOS;
        if (ch == 'U' || ch == 'u') {
                YYPOS++;
@@ -1593,9 +1629,9 @@ _yy_state_258:
        } else {
                goto _yy_state_error;
        }
-_yy_state_366:
+_yy_state_381:
        ch = *++YYPOS;
-_yy_tunnel_366:
+_yy_tunnel_381:
        if ((ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'Z') || ch == '_' || (ch >= 'a' && ch <= 'z')) {
                goto _yy_state_9;
        } else {
@@ -1952,8 +1988,11 @@ static int synpred_6(int sym) {
 }
 
 static int parse_declarations(int 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__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), "\370\377\371\377\377\037\301\001\000\000\100\000\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___CDECL,YY___STDCALL,YY___FASTCALL,YY___THISCALL,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\177\004\007\000\000\000\001\000")) {
                zend_ffi_dcl common_dcl = ZEND_FFI_ATTR_INIT;
+               if (sym == YY___EXTENSION__) {
+                       sym = get_sym();
+               }
                sym = parse_declaration_specifiers(sym, &common_dcl);
                if (sym == YY__STAR || sym == YY_ID || sym == YY__LPAREN) {
                        const char *name;
@@ -1961,6 +2000,21 @@ static int parse_declarations(int sym) {
                        zend_ffi_dcl dcl;
                        dcl = common_dcl;
                        sym = parse_declarator(sym, &dcl, &name, &name_len);
+                       if (sym == YY___ASM__) {
+                               zend_ffi_val asm_str;
+                               sym = get_sym();
+                               if (sym != YY__LPAREN) {
+                                       yy_error_sym("'(' expected, got", sym);
+                               }
+                               sym = get_sym();
+                               do {
+                                       sym = parse_STRING(sym, &asm_str);
+                               } while (sym == YY_STRING);
+                               if (sym != YY__RPAREN) {
+                                       yy_error_sym("')' expected, got", sym);
+                               }
+                               sym = get_sym();
+                       }
                        if (sym == YY___ATTRIBUTE || sym == YY___ATTRIBUTE__ || sym == YY___DECLSPEC) {
                                sym = parse_attributes(sym, &dcl);
                        }
@@ -2049,11 +2103,11 @@ static int parse_declaration_specifiers(int sym, zend_ffi_dcl *dcl) {
                                        yy_error_sym("'(' expected, got", sym);
                                }
                                sym = get_sym();
-                               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,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\370\377\377\037\301\001\000\000\100\000\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), "\002\000\340\377\377\177\004\007\000\000\000\001\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__), "\000\000\002\000\000\000\004\200\000\343\337\037\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\020\000\002\214\177\177\000")) {
                                        zend_ffi_val align_val;
                                        sym = parse_constant_expression(sym, &align_val);
                                        zend_ffi_align_as_val(dcl, &align_val);
@@ -2105,35 +2159,38 @@ 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__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), "\370\377\371\377\377\037\301\001\000\000\100\000\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___CDECL,YY___STDCALL,YY___FASTCALL,YY___THISCALL,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\177\004\007\000\000\000\001\000")) && (sym != YY_ID || !(dcl->flags & ZEND_FFI_DCL_TYPE_SPECIFIERS)));
        return sym;
 }
 
 static int parse_specifier_qualifier_list(int sym, zend_ffi_dcl *dcl) {
+       if (sym == YY___EXTENSION__) {
+               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\340\377\037\001\000\000\000\100\000\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\200\377\177\004\000\000\000\000\001\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\370\037\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\340\177\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) {
                        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\370\377\377\037\301\001\000\000\100\000\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), "\000\000\340\377\377\177\004\007\000\000\000\001\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\370\037\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\340\177\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) {
                        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\370\037\000\000\300\001\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), "\000\000\340\177\000\000\000\007\000\000\000\000\000"));
        return sym;
 }
 
@@ -2287,7 +2344,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_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\370\377\377\037\301\001\000\000\100\000\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\340\377\377\177\004\007\000\000\000\001\000")) {
                sym = parse_struct_declaration(sym, dcl);
                while (1) {
                        save_pos  = yy_pos;
@@ -2305,7 +2362,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_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\370\377\377\037\301\001\000\000\100\000\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), "\002\000\340\377\377\177\004\007\000\000\000\001\000")) {
                                alt2 = 3;
                                goto _yy_state_2;
                        } else if (sym2 == YY__RBRACE) {
@@ -2373,7 +2430,7 @@ static int parse_struct_declarator(int sym, zend_ffi_dcl *struct_dcl, zend_ffi_d
                                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), "\006\000\000\000\000\100\300\001\000\000\000\000\000")) {
+               } else if (YY_IN_SET(sym, (YY___ATTRIBUTE,YY___ATTRIBUTE__,YY___DECLSPEC,YY__COMMA,YY__SEMICOLON,YY__RBRACE), "\140\000\000\000\000\000\001\007\000\000\000\000\000")) {
                        if (sym == YY___ATTRIBUTE || sym == YY___ATTRIBUTE__ || sym == YY___DECLSPEC) {
                                sym = parse_attributes(sym, field_dcl);
                        }
@@ -2415,7 +2472,7 @@ static int parse_enum_specifier(int sym, zend_ffi_dcl *dcl) {
                        if (sym == YY___ATTRIBUTE || sym == YY___ATTRIBUTE__ || sym == YY___DECLSPEC) {
                                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__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), "\377\377\377\377\377\337\315\001\000\000\100\000\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___CDECL,YY___STDCALL,YY___FASTCALL,YY___THISCALL,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\177\067\007\000\000\000\001\000")) {
                        zend_ffi_declare_tag(name, name_len, dcl, 1);
                } else {
                        yy_error_sym("unexpected", sym);
@@ -2442,45 +2499,45 @@ static int parse_enumerator_list(int sym, zend_ffi_dcl *enum_dcl) {
        const unsigned char *save_pos;
        const unsigned char *save_text;
        int   save_line;
-       int alt243;
+       int alt249;
        int64_t min = 0, max = 0, last = -1;
        sym = parse_enumerator(sym, enum_dcl, &min, &max, &last);
        while (1) {
                save_pos  = yy_pos;
                save_text = yy_text;
                save_line = yy_line;
-               alt243 = -2;
+               alt249 = -2;
                sym2 = sym;
                if (sym2 == YY__COMMA) {
                        sym2 = get_sym();
-                       goto _yy_state_243_1;
+                       goto _yy_state_249_1;
                } else if (sym2 == YY__RBRACE) {
-                       alt243 = -1;
-                       goto _yy_state_243;
+                       alt249 = -1;
+                       goto _yy_state_249;
                } else {
                        yy_error_sym("unexpected", sym2);
                }
-_yy_state_243_1:
+_yy_state_249_1:
                if (sym2 == YY_ID) {
-                       alt243 = 244;
-                       goto _yy_state_243;
+                       alt249 = 250;
+                       goto _yy_state_249;
                } else if (sym2 == YY__RBRACE) {
-                       alt243 = 246;
-                       goto _yy_state_243;
+                       alt249 = 252;
+                       goto _yy_state_249;
                } else {
                        yy_error_sym("unexpected", sym2);
                }
-_yy_state_243:
+_yy_state_249:
                yy_pos  = save_pos;
                yy_text = save_text;
                yy_line = save_line;
-               if (alt243 != 244) {
+               if (alt249 != 250) {
                        break;
                }
                sym = get_sym();
                sym = parse_enumerator(sym, enum_dcl, &min, &max, &last);
        }
-       if (alt243 == 246) {
+       if (alt249 == 252) {
                sym = get_sym();
        }
        return sym;
@@ -2590,7 +2647,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\370\037\000\000\300\001\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), "\000\000\340\177\000\000\000\007\000\000\000\000\000")) {
                        sym = parse_type_qualifier_list(sym, dcl);
                }
        } while (sym == YY__STAR);
@@ -2602,9 +2659,9 @@ static int parse_array_or_function_declarators(int sym, zend_ffi_dcl *dcl) {
        const unsigned char *save_pos;
        const unsigned char *save_text;
        int   save_line;
-       int alt103;
-       int alt99;
-       int alt113;
+       int alt104;
+       int alt100;
+       int alt114;
        zend_ffi_dcl dummy = ZEND_FFI_ATTR_INIT;
        zend_ffi_val len = {.kind = ZEND_FFI_VAL_EMPTY};
        HashTable *args = NULL;
@@ -2614,99 +2671,99 @@ static int parse_array_or_function_declarators(int sym, zend_ffi_dcl *dcl) {
                save_pos  = yy_pos;
                save_text = yy_text;
                save_line = yy_line;
-               alt99 = -2;
+               alt100 = -2;
                sym2 = sym;
                if (sym2 == YY_STATIC) {
-                       alt99 = 100;
-                       goto _yy_state_99;
-               } 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\370\037\000\000\300\001\000\000\000\000\000")) {
-                       alt99 = 103;
-                       goto _yy_state_99;
+                       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\340\177\000\000\000\007\000\000\000\000\000")) {
+                       alt100 = 104;
+                       goto _yy_state_100;
                } else if (sym2 == YY__STAR) {
                        sym2 = get_sym();
-                       goto _yy_state_99_15;
-               } 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), "\000\000\002\000\000\000\000\200\000\343\337\037\000")) {
-                       alt99 = 109;
-                       goto _yy_state_99;
+                       goto _yy_state_100_15;
+               } 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\002\214\177\177\000")) {
+                       alt100 = 110;
+                       goto _yy_state_100;
                } else if (sym2 == YY__RBRACK) {
-                       alt99 = 110;
-                       goto _yy_state_99;
+                       alt100 = 111;
+                       goto _yy_state_100;
                } else {
                        yy_error_sym("unexpected", sym2);
                }
-_yy_state_99_15:
+_yy_state_100_15:
                if (sym2 == YY__RBRACK) {
-                       alt99 = 108;
-                       goto _yy_state_99;
-               } 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), "\000\000\002\000\000\000\004\200\000\343\337\037\000")) {
-                       alt99 = 109;
-                       goto _yy_state_99;
+                       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\020\000\002\214\177\177\000")) {
+                       alt100 = 110;
+                       goto _yy_state_100;
                } else {
                        yy_error_sym("unexpected", sym2);
                }
-_yy_state_99:
+_yy_state_100:
                yy_pos  = save_pos;
                yy_text = save_text;
                yy_line = save_line;
-               if (alt99 == 100) {
+               if (alt100 == 101) {
                        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\370\037\000\000\300\001\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), "\000\000\340\177\000\000\000\007\000\000\000\000\000")) {
                                sym = parse_type_qualifier_list(sym, &dummy);
                        }
                        sym = parse_assignment_expression(sym, &len);
-               } else if (alt99 == 103) {
+               } else if (alt100 == 104) {
                        sym = parse_type_qualifier_list(sym, &dummy);
                        save_pos  = yy_pos;
                        save_text = yy_text;
                        save_line = yy_line;
-                       alt103 = -2;
+                       alt104 = -2;
                        sym2 = sym;
                        if (sym2 == YY_STATIC) {
-                               alt103 = 104;
-                               goto _yy_state_103;
+                               alt104 = 105;
+                               goto _yy_state_104;
                        } else if (sym2 == YY__STAR) {
                                sym2 = get_sym();
-                               goto _yy_state_103_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), "\000\000\002\000\000\000\000\200\000\343\337\037\000")) {
-                               alt103 = 107;
-                               goto _yy_state_103;
+                               goto _yy_state_104_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\002\214\177\177\000")) {
+                               alt104 = 108;
+                               goto _yy_state_104;
                        } else if (sym2 == YY__RBRACK) {
-                               alt103 = 110;
-                               goto _yy_state_103;
+                               alt104 = 111;
+                               goto _yy_state_104;
                        } else {
                                yy_error_sym("unexpected", sym2);
                        }
-_yy_state_103_2:
+_yy_state_104_2:
                        if (sym2 == YY__RBRACK) {
-                               alt103 = 106;
-                               goto _yy_state_103;
-                       } 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), "\000\000\002\000\000\000\004\200\000\343\337\037\000")) {
-                               alt103 = 107;
-                               goto _yy_state_103;
+                               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\020\000\002\214\177\177\000")) {
+                               alt104 = 108;
+                               goto _yy_state_104;
                        } else {
                                yy_error_sym("unexpected", sym2);
                        }
-_yy_state_103:
+_yy_state_104:
                        yy_pos  = save_pos;
                        yy_text = save_text;
                        yy_line = save_line;
-                       if (alt103 == 104) {
+                       if (alt104 == 105) {
                                sym = get_sym();
                                sym = parse_assignment_expression(sym, &len);
-                       } else if (alt103 == 110) {
+                       } else if (alt104 == 111) {
                                attr |= ZEND_FFI_ATTR_INCOMPLETE_ARRAY;
-                       } else if (alt103 == 106) {
+                       } else if (alt104 == 107) {
                                sym = get_sym();
                                attr |= ZEND_FFI_ATTR_VLA;
-                       } else if (alt103 == 107) {
+                       } else if (alt104 == 108) {
                                sym = parse_assignment_expression(sym, &len);
                        } else {
                                yy_error_sym("unexpected", sym);
                        }
-               } else if (alt99 == 110 || alt99 == 108 || alt99 == 109) {
-                       if (alt99 == 110) {
+               } else if (alt100 == 111 || alt100 == 109 || alt100 == 110) {
+                       if (alt100 == 111) {
                                attr |= ZEND_FFI_ATTR_INCOMPLETE_ARRAY;
-                       } else if (alt99 == 108) {
+                       } else if (alt100 == 109) {
                                sym = get_sym();
                                attr |= ZEND_FFI_ATTR_VLA;
                        } else {
@@ -2726,45 +2783,45 @@ _yy_state_103:
                zend_ffi_make_array_type(dcl, &len);
        } else if (sym == YY__LPAREN) {
                sym = get_sym();
-               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,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), "\000\000\370\377\377\037\341\001\000\000\100\000\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,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\370\377\377\037\301\001\000\000\100\000\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__POINT_POINT_POINT), "\002\000\340\377\377\177\204\007\000\000\000\001\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\340\377\377\177\004\007\000\000\000\001\000")) {
                                sym = parse_parameter_declaration(sym, &args);
                                while (1) {
                                        save_pos  = yy_pos;
                                        save_text = yy_text;
                                        save_line = yy_line;
-                                       alt113 = -2;
+                                       alt114 = -2;
                                        sym2 = sym;
                                        if (sym2 == YY__COMMA) {
                                                sym2 = get_sym();
-                                               goto _yy_state_113_1;
+                                               goto _yy_state_114_1;
                                        } else if (sym2 == YY__RPAREN) {
-                                               alt113 = 119;
-                                               goto _yy_state_113;
+                                               alt114 = 120;
+                                               goto _yy_state_114;
                                        } else {
                                                yy_error_sym("unexpected", sym2);
                                        }
-_yy_state_113_1:
-                                       if (YY_IN_SET(sym2, (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\370\377\377\037\301\001\000\000\100\000\000")) {
-                                               alt113 = 114;
-                                               goto _yy_state_113;
+_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\340\377\377\177\004\007\000\000\000\001\000")) {
+                                               alt114 = 115;
+                                               goto _yy_state_114;
                                        } else if (sym2 == YY__POINT_POINT_POINT) {
-                                               alt113 = 116;
-                                               goto _yy_state_113;
+                                               alt114 = 117;
+                                               goto _yy_state_114;
                                        } else {
                                                yy_error_sym("unexpected", sym2);
                                        }
-_yy_state_113:
+_yy_state_114:
                                        yy_pos  = save_pos;
                                        yy_text = save_text;
                                        yy_line = save_line;
-                                       if (alt113 != 114) {
+                                       if (alt114 != 115) {
                                                break;
                                        }
                                        sym = get_sym();
                                        sym = parse_parameter_declaration(sym, &args);
                                }
-                               if (alt113 == 116) {
+                               if (alt114 == 117) {
                                        sym = get_sym();
                                        if (sym != YY__POINT_POINT_POINT) {
                                                yy_error_sym("'...' expected, got", sym);
@@ -2873,26 +2930,34 @@ static int parse_attrib(int sym, zend_ffi_dcl *dcl) {
        size_t name_len;
        int n;
        zend_ffi_val val;
-       if (sym == YY_ID) {
-               sym = parse_ID(sym, &name, &name_len);
-               if (sym == YY__COMMA || sym == YY__RPAREN) {
-                       zend_ffi_add_attribute(dcl, name, name_len);
-               } else if (sym == YY__LPAREN) {
-                       sym = get_sym();
-                       sym = parse_assignment_expression(sym, &val);
-                       zend_ffi_add_attribute_value(dcl, name, name_len, 0, &val);
-                       n = 0;
-                       while (sym == YY__COMMA) {
+       if (sym == YY_ID || sym == YY_CONST || sym == YY___CONST || sym == YY___CONST__) {
+               if (sym == YY_ID) {
+                       sym = parse_ID(sym, &name, &name_len);
+                       if (sym == YY__COMMA || sym == YY__RPAREN) {
+                               zend_ffi_add_attribute(dcl, name, name_len);
+                       } else if (sym == YY__LPAREN) {
                                sym = get_sym();
                                sym = parse_assignment_expression(sym, &val);
-                               zend_ffi_add_attribute_value(dcl, name, name_len, ++n, &val);
-                       }
-                       if (sym != YY__RPAREN) {
-                               yy_error_sym("')' expected, got", sym);
+                               zend_ffi_add_attribute_value(dcl, name, name_len, 0, &val);
+                               n = 0;
+                               while (sym == YY__COMMA) {
+                                       sym = get_sym();
+                                       sym = parse_assignment_expression(sym, &val);
+                                       zend_ffi_add_attribute_value(dcl, name, name_len, ++n, &val);
+                               }
+                               if (sym != YY__RPAREN) {
+                                       yy_error_sym("')' expected, got", sym);
+                               }
+                               sym = get_sym();
+                       } else {
+                               yy_error_sym("unexpected", sym);
                        }
+               } else if (sym == YY_CONST) {
+                       sym = get_sym();
+               } else if (sym == YY___CONST) {
                        sym = get_sym();
                } else {
-                       yy_error_sym("unexpected", sym);
+                       sym = get_sym();
                }
        }
        return sym;
@@ -2903,13 +2968,13 @@ static int parse_initializer(int sym) {
        const unsigned char *save_pos;
        const unsigned char *save_text;
        int   save_line;
-       int alt336;
+       int alt342;
        zend_ffi_val dummy;
        if (sym != YY__EQUAL) {
                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__), "\000\000\002\000\000\000\004\200\000\343\337\037\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\020\000\002\214\177\177\000")) {
                sym = parse_assignment_expression(sym, &dummy);
        } else if (sym == YY__LBRACE) {
                sym = get_sym();
@@ -2921,32 +2986,32 @@ static int parse_initializer(int sym) {
                        save_pos  = yy_pos;
                        save_text = yy_text;
                        save_line = yy_line;
-                       alt336 = -2;
+                       alt342 = -2;
                        sym2 = sym;
                        if (sym2 == YY__COMMA) {
                                sym2 = get_sym();
-                               goto _yy_state_336_1;
+                               goto _yy_state_342_1;
                        } else if (sym2 == YY__RBRACE) {
-                               alt336 = 341;
-                               goto _yy_state_336;
+                               alt342 = 347;
+                               goto _yy_state_342;
                        } else {
                                yy_error_sym("unexpected", sym2);
                        }
-_yy_state_336_1:
+_yy_state_342_1:
                        if (sym2 == YY__LBRACK || sym2 == YY__POINT || sym2 == YY__EQUAL) {
-                               alt336 = 337;
-                               goto _yy_state_336;
+                               alt342 = 343;
+                               goto _yy_state_342;
                        } else if (sym2 == YY__RBRACE) {
-                               alt336 = 340;
-                               goto _yy_state_336;
+                               alt342 = 346;
+                               goto _yy_state_342;
                        } else {
                                yy_error_sym("unexpected", sym2);
                        }
-_yy_state_336:
+_yy_state_342:
                        yy_pos  = save_pos;
                        yy_text = save_text;
                        yy_line = save_line;
-                       if (alt336 != 337) {
+                       if (alt342 != 343) {
                                break;
                        }
                        sym = get_sym();
@@ -2955,7 +3020,7 @@ _yy_state_336:
                        }
                        sym = parse_initializer(sym);
                }
-               if (alt336 == 340) {
+               if (alt342 == 346) {
                        sym = get_sym();
                }
                if (sym != YY__RBRACE) {
@@ -3216,7 +3281,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), "\000\000\002\000\000\000\010\002\000\160\000\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\040\010\000\300\001\000\000")) {
                                switch (sym) {
                                        case YY__LBRACK:
                                                sym = get_sym();
@@ -3228,7 +3293,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__), "\000\000\002\000\000\000\004\200\000\343\337\037\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\020\000\002\214\177\177\000")) {
                                                        sym = parse_expr_list(sym);
                                                }
                                                if (sym != YY__RPAREN) {
@@ -3330,7 +3395,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__), "\000\000\002\000\000\000\004\200\000\343\337\037\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\020\000\002\214\177\177\000")) {
                                sym = parse_unary_expression(sym, val);
                                zend_ffi_expr_sizeof_val(val);
                        } else {
@@ -3361,7 +3426,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__), "\000\000\002\000\000\000\004\200\000\343\337\037\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\020\000\002\214\177\177\000")) {
                                sym = parse_unary_expression(sym, val);
                                zend_ffi_expr_alignof_val(val);
                        } else {