[PATCH 06/15] widl: refactor generators to use decl_spec_t rather than type_t where needed

Richard Pospesel richard at torproject.org
Fri Jul 5 16:51:35 CDT 2019


Signed-off-by: Richard Pospesel <richard at torproject.org>
---
 tools/widl/client.c  |   8 +-
 tools/widl/header.c  |  72 +++++++++------
 tools/widl/header.h  |   4 +-
 tools/widl/proxy.c   |   6 +-
 tools/widl/server.c  |   7 +-
 tools/widl/typegen.c | 215 ++++++++++++++++++++++++-------------------
 6 files changed, 177 insertions(+), 135 deletions(-)

diff --git a/tools/widl/client.c b/tools/widl/client.c
index 545a35c0c9..9a15153bab 100644
--- a/tools/widl/client.c
+++ b/tools/widl/client.c
@@ -54,10 +54,10 @@ static void write_client_func_decl( const type_t *iface, const var_t *func )
 {
     const char *callconv = get_attrp(func->declspec.type->attrs, ATTR_CALLCONV);
     const var_list_t *args = type_function_get_args(func->declspec.type);
-    type_t *rettype = type_function_get_rettype(func->declspec.type);
+    const decl_spec_t *retdeclspec = type_function_get_retdeclspec(func->declspec.type);
 
     if (!callconv) callconv = "__cdecl";
-    write_type_decl_left(client, rettype);
+    write_declspec_decl_left(client, retdeclspec);
     fprintf(client, " %s ", callconv);
     fprintf(client, "%s%s(\n", prefix_client, get_name(func));
     indent++;
@@ -136,7 +136,7 @@ static void write_function_stub( const type_t *iface, const var_t *func,
     if (has_ret)
     {
         print_client("%s", "");
-        write_type_decl(client, retval->declspec.type, retval->name);
+        write_declspec_decl(client, &retval->declspec, retval->name);
         fprintf(client, ";\n");
     }
     print_client("RPC_MESSAGE _RpcMessage;\n");
@@ -488,7 +488,7 @@ static void write_implicithandledecl(type_t *iface)
 
     if (implicit_handle)
     {
-        write_type_decl( client, implicit_handle->declspec.type, implicit_handle->name );
+        write_declspec_decl( client, &implicit_handle->declspec, implicit_handle->name );
         fprintf(client, ";\n\n");
     }
 }
diff --git a/tools/widl/header.c b/tools/widl/header.c
index d8f31a69f9..192abece1e 100644
--- a/tools/widl/header.c
+++ b/tools/widl/header.c
@@ -43,7 +43,7 @@ user_type_list_t user_type_list = LIST_INIT(user_type_list);
 context_handle_list_t context_handle_list = LIST_INIT(context_handle_list);
 generic_handle_list_t generic_handle_list = LIST_INIT(generic_handle_list);
 
-static void write_type_def_or_decl(FILE *f, type_t *t, int field, const char *name);
+static void write_type_def_or_decl(FILE *f, const decl_spec_t *ds, int field, const char *name);
 
 static void indent(FILE *h, int delta)
 {
@@ -252,7 +252,7 @@ static void write_fields(FILE *h, var_list_t *fields)
         default:
             ;
         }
-        write_type_def_or_decl(h, v->declspec.type, TRUE, name);
+        write_type_def_or_decl(h, &v->declspec, TRUE, name);
         fprintf(h, ";\n");
     }
 }
@@ -295,8 +295,15 @@ static void write_pointer_left(FILE *h, type_t *ref)
 }
 
 void write_type_left(FILE *h, type_t *t, enum name_type name_type, int declonly)
+{
+  decl_spec_t ds;
+  write_declspec_left(h, init_declspec(&ds, t), name_type, declonly);
+}
+
+void write_declspec_left(FILE* h, const decl_spec_t *ds, enum name_type name_type, int declonly)
 {
   const char *name;
+  type_t *t = ds->type;
 
   if (!h) return;
 
@@ -351,7 +358,7 @@ void write_type_left(FILE *h, type_t *t, enum name_type name_type, int declonly)
         break;
       case TYPE_POINTER:
       {
-        write_type_left(h, type_pointer_get_ref_type(t), name_type, declonly);
+        write_declspec_left(h, type_pointer_get_ref(t), name_type, declonly);
         write_pointer_left(h, type_pointer_get_ref_type(t));
         if (is_attr(t->attrs, ATTR_CONST)) fprintf(h, "const ");
         break;
@@ -361,7 +368,7 @@ void write_type_left(FILE *h, type_t *t, enum name_type name_type, int declonly)
           fprintf(h, "%s", t->name);
         else
         {
-          write_type_left(h, type_array_get_element_type(t), name_type, declonly);
+          write_declspec_left(h, type_array_get_element(t), name_type, declonly);
           if (type_array_is_decl_as_ptr(t))
             write_pointer_left(h, type_array_get_element_type(t));
         }
@@ -485,8 +492,9 @@ void write_type_right(FILE *h, type_t *t, int is_field)
   }
 }
 
-static void write_type_v(FILE *h, type_t *t, int is_field, int declonly, const char *name)
+static void write_type_v(FILE *h, const decl_spec_t *ds, int is_field, int declonly, const char *name)
 {
+  type_t *t = ds->type;
   type_t *pt = NULL;
   int ptr_level = 0;
 
@@ -501,14 +509,14 @@ static void write_type_v(FILE *h, type_t *t, int is_field, int declonly, const c
       const char *callconv = get_attrp(pt->attrs, ATTR_CALLCONV);
       if (!callconv && is_object_interface) callconv = "STDMETHODCALLTYPE";
       if (is_attr(pt->attrs, ATTR_INLINE)) fprintf(h, "inline ");
-      write_type_left(h, type_function_get_rettype(pt), NAME_DEFAULT, declonly);
+      write_declspec_left(h, type_function_get_retdeclspec(pt), NAME_DEFAULT, declonly);
       fputc(' ', h);
       if (ptr_level) fputc('(', h);
       if (callconv) fprintf(h, "%s ", callconv);
       for (i = 0; i < ptr_level; i++)
         fputc('*', h);
     } else
-      write_type_left(h, t, NAME_DEFAULT, declonly);
+      write_declspec_left(h, ds, NAME_DEFAULT, declonly);
   }
 
   if (name) fprintf(h, "%s%s", !t || needs_space_after(t) ? " " : "", name );
@@ -529,9 +537,9 @@ static void write_type_v(FILE *h, type_t *t, int is_field, int declonly, const c
   }
 }
 
-static void write_type_def_or_decl(FILE *f, type_t *t, int field, const char *name)
+static void write_type_def_or_decl(FILE *f, const decl_spec_t *ds, int field, const char *name)
 {
-  write_type_v(f, t, field, FALSE, name);
+  write_type_v(f, ds, field, FALSE, name);
 }
 
 static void write_type_definition(FILE *f, type_t *t)
@@ -560,12 +568,18 @@ static void write_type_definition(FILE *f, type_t *t)
 
 void write_type_decl(FILE *f, type_t *t, const char *name)
 {
-  write_type_v(f, t, FALSE, TRUE, name);
+  decl_spec_t ds;
+  write_declspec_decl(f, init_declspec(&ds, t), name);
+}
+
+void write_declspec_decl(FILE *f, const decl_spec_t *ds, const char *name)
+{
+  write_type_v(f, ds, FALSE, TRUE, name);
 }
 
-void write_type_decl_left(FILE *f, type_t *t)
+void write_declspec_decl_left(FILE *f, const decl_spec_t *ds)
 {
-  write_type_left(f, t, NAME_DEFAULT, TRUE);
+  write_declspec_left(f, ds, NAME_DEFAULT, TRUE);
 }
 
 static int user_type_registered(const char *name)
@@ -789,7 +803,7 @@ static void write_generic_handle_routines(FILE *header)
 static void write_typedef(FILE *header, type_t *type)
 {
   fprintf(header, "typedef ");
-  write_type_def_or_decl(header, type_alias_get_aliasee_type(type), FALSE, type->name);
+  write_type_def_or_decl(header, type_alias_get_aliasee(type), FALSE, type->name);
   fprintf(header, ";\n");
 }
 
@@ -833,7 +847,7 @@ static void write_declaration(FILE *header, const var_t *v)
         fprintf(header, "extern ");
         break;
     }
-    write_type_def_or_decl(header, v->declspec.type, FALSE, v->name);
+    write_type_def_or_decl(header, &v->declspec, FALSE, v->name);
     fprintf(header, ";\n\n");
   }
 }
@@ -1073,7 +1087,7 @@ void write_args(FILE *h, const var_list_t *args, const char *name, int method, i
         }
         else fprintf(h, ",");
     }
-    write_type_decl(h, arg->declspec.type, arg->name);
+    write_declspec_decl(h, &arg->declspec, arg->name);
     if (method == 2) {
         const expr_t *expr = get_attrp(arg->attrs, ATTR_DEFAULTVALUE);
         if (expr) {
@@ -1125,11 +1139,11 @@ static void write_cpp_method_def(FILE *header, const type_t *iface)
 
         indent(header, 0);
         fprintf(header, "virtual ");
-        write_type_decl_left(header, type_function_get_rettype(func->declspec.type));
+        write_declspec_decl_left(header, type_function_get_retdeclspec(func->declspec.type));
         fprintf(header, "* %s %s(\n", callconv, get_name(func));
         ++indentation;
         indent(header, 0);
-        write_type_decl_left(header, type_function_get_rettype(func->declspec.type));
+        write_declspec_decl_left(header, type_function_get_retdeclspec(func->declspec.type));
         fprintf(header, " *__ret");
         --indentation;
         if (args) {
@@ -1139,7 +1153,7 @@ static void write_cpp_method_def(FILE *header, const type_t *iface)
         fprintf(header, ") = 0;\n");
 
         indent(header, 0);
-        write_type_decl_left(header, type_function_get_rettype(func->declspec.type));
+        write_declspec_decl_left(header, type_function_get_retdeclspec(func->declspec.type));
         fprintf(header, " %s %s(\n", callconv, get_name(func));
         write_args(header, args, iface->name, 2, TRUE);
         fprintf(header, ")\n");
@@ -1147,7 +1161,7 @@ static void write_cpp_method_def(FILE *header, const type_t *iface)
         fprintf(header, "{\n");
         ++indentation;
         indent(header, 0);
-        write_type_decl_left(header, type_function_get_rettype(func->declspec.type));
+        write_declspec_decl_left(header, type_function_get_retdeclspec(func->declspec.type));
         fprintf(header, " __ret;\n");
         indent(header, 0);
         fprintf(header, "return *%s(&__ret", get_name(func));
@@ -1164,7 +1178,7 @@ static void write_cpp_method_def(FILE *header, const type_t *iface)
 
       indent(header, 0);
       fprintf(header, "virtual ");
-      write_type_decl_left(header, type_function_get_rettype(func->declspec.type));
+      write_declspec_decl_left(header, type_function_get_retdeclspec(func->declspec.type));
       fprintf(header, " %s %s(\n", callconv, get_name(func));
       write_args(header, args, iface->name, 2, TRUE);
       fprintf(header, ") = 0;\n");
@@ -1201,7 +1215,7 @@ static void write_inline_wrappers(FILE *header, const type_t *iface, const type_
       const var_t *arg;
 
       fprintf(header, "static FORCEINLINE ");
-      write_type_decl_left(header, type_function_get_rettype(func->declspec.type));
+      write_declspec_decl_left(header, type_function_get_retdeclspec(func->declspec.type));
       fprintf(header, " %s_%s(", name, get_name(func));
       write_args(header, type_function_get_args(func->declspec.type), name, 1, FALSE);
       fprintf(header, ") {\n");
@@ -1213,7 +1227,7 @@ static void write_inline_wrappers(FILE *header, const type_t *iface, const type_
                 get_vtbl_entry_name(iface, func));
       } else {
         indent(header, 0);
-        write_type_decl_left(header, type_function_get_rettype(func->declspec.type));
+        write_declspec_decl_left(header, type_function_get_retdeclspec(func->declspec.type));
         fprintf(header, " __ret;\n");
         indent(header, 0);
         fprintf(header, "return *This->lpVtbl->%s(This,&__ret", get_vtbl_entry_name(iface, func));
@@ -1248,7 +1262,7 @@ static void do_write_c_method_def(FILE *header, const type_t *iface, const char
       const char *callconv = get_attrp(func->declspec.type->attrs, ATTR_CALLCONV);
       if (!callconv) callconv = "STDMETHODCALLTYPE";
       indent(header, 0);
-      write_type_decl_left(header, type_function_get_rettype(func->declspec.type));
+      write_declspec_decl_left(header, type_function_get_retdeclspec(func->declspec.type));
       if (is_aggregate_return(func))
         fprintf(header, " *");
       if (is_inherited_method(iface, func))
@@ -1261,7 +1275,7 @@ static void do_write_c_method_def(FILE *header, const type_t *iface, const char
       if (is_aggregate_return(func)) {
         fprintf(header, ",\n");
         indent(header, 0);
-        write_type_decl_left(header, type_function_get_rettype(func->declspec.type));
+        write_declspec_decl_left(header, type_function_get_retdeclspec(func->declspec.type));
         fprintf(header, " *__ret");
       }
       --indentation;
@@ -1297,7 +1311,7 @@ static void write_method_proto(FILE *header, const type_t *iface)
       const char *callconv = get_attrp(func->declspec.type->attrs, ATTR_CALLCONV);
       if (!callconv) callconv = "STDMETHODCALLTYPE";
       /* proxy prototype */
-      write_type_decl_left(header, type_function_get_rettype(func->declspec.type));
+      write_declspec_decl_left(header, type_function_get_retdeclspec(func->declspec.type));
       fprintf(header, " %s %s_%s_Proxy(\n", callconv, iface->name, get_name(func));
       write_args(header, type_function_get_args(func->declspec.type), iface->name, 1, TRUE);
       fprintf(header, ");\n");
@@ -1332,7 +1346,7 @@ static void write_locals(FILE *fp, const type_t *iface, int body)
       if (&stmt2->entry != type_iface_get_stmts(iface)) {
         const var_t *m = stmt2->u.var;
         /* proxy prototype - use local prototype */
-        write_type_decl_left(fp, type_function_get_rettype(m->declspec.type));
+        write_declspec_decl_left(fp, type_function_get_retdeclspec(m->declspec.type));
         fprintf(fp, " CALLBACK %s_%s_Proxy(\n", iface->name, get_name(m));
         write_args(fp, type_function_get_args(m->declspec.type), iface->name, 1, TRUE);
         fprintf(fp, ")");
@@ -1354,7 +1368,7 @@ static void write_locals(FILE *fp, const type_t *iface, int body)
         else
           fprintf(fp, ";\n");
         /* stub prototype - use remotable prototype */
-        write_type_decl_left(fp, type_function_get_rettype(func->declspec.type));
+        write_declspec_decl_left(fp, type_function_get_retdeclspec(func->declspec.type));
         fprintf(fp, " __RPC_STUB %s_%s_Stub(\n", iface->name, get_name(m));
         write_args(fp, type_function_get_args(func->declspec.type), iface->name, 1, TRUE);
         fprintf(fp, ")");
@@ -1406,7 +1420,7 @@ static void write_function_proto(FILE *header, const type_t *iface, const var_t
 
   if (!callconv) callconv = "__cdecl";
   /* FIXME: do we need to handle call_as? */
-  write_type_decl_left(header, type_function_get_rettype(fun->declspec.type));
+  write_declspec_decl_left(header, type_function_get_retdeclspec(fun->declspec.type));
   fprintf(header, " %s ", callconv);
   fprintf(header, "%s%s(\n", prefix, get_name(fun));
   if (type_function_get_args(fun->declspec.type))
@@ -1536,7 +1550,7 @@ static void write_rpc_interface_start(FILE *header, const type_t *iface)
   if (var)
   {
       fprintf(header, "extern ");
-      write_type_decl( header, var->declspec.type, var->name );
+      write_declspec_decl( header, &var->declspec, var->name );
       fprintf(header, ";\n");
   }
   if (old_names)
diff --git a/tools/widl/header.h b/tools/widl/header.h
index 94b90a391f..0e62f77c8f 100644
--- a/tools/widl/header.h
+++ b/tools/widl/header.h
@@ -29,10 +29,12 @@ extern int is_attr(const attr_list_t *list, enum attr_type t);
 extern void *get_attrp(const attr_list_t *list, enum attr_type t);
 extern unsigned int get_attrv(const attr_list_t *list, enum attr_type t);
 extern const char* get_name(const var_t *v);
+extern void write_declspec_left(FILE *h, const decl_spec_t *ds, enum name_type name_type, int declonly);
 extern void write_type_left(FILE *h, type_t *t, enum name_type name_type, int declonly);
 extern void write_type_right(FILE *h, type_t *t, int is_field);
 extern void write_type_decl(FILE *f, type_t *t, const char *name);
-extern void write_type_decl_left(FILE *f, type_t *t);
+extern void write_declspec_decl(FILE *f, const decl_spec_t *ds, const char *name);
+extern void write_declspec_decl_left(FILE *f, const decl_spec_t *ds);
 extern unsigned int get_context_handle_offset( const type_t *type );
 extern unsigned int get_generic_handle_offset( const type_t *type );
 extern int needs_space_after(type_t *t);
diff --git a/tools/widl/proxy.c b/tools/widl/proxy.c
index 5b5a092c83..9f7fd530b1 100644
--- a/tools/widl/proxy.c
+++ b/tools/widl/proxy.c
@@ -202,7 +202,7 @@ static void gen_proxy(type_t *iface, const var_t *func, int idx,
   if (is_interpreted_func( iface, func ))
   {
       if (get_stub_mode() == MODE_Oif && !is_callas( func->attrs )) return;
-      write_type_decl_left(proxy, retval->declspec.type);
+      write_declspec_decl_left(proxy, &retval->declspec);
       print_proxy( " %s %s_%s_Proxy(\n", callconv, iface->name, get_name(func));
       write_args(proxy, args, iface->name, 1, TRUE);
       print_proxy( ")\n");
@@ -219,7 +219,7 @@ static void gen_proxy(type_t *iface, const var_t *func, int idx,
   print_proxy( "}\n");
   print_proxy( "\n");
 
-  write_type_decl_left(proxy, retval->declspec.type);
+  write_declspec_decl_left(proxy, &retval->declspec);
   print_proxy( " %s %s_%s_Proxy(\n", callconv, iface->name, get_name(func));
   write_args(proxy, args, iface->name, 1, TRUE);
   print_proxy( ")\n");
@@ -229,7 +229,7 @@ static void gen_proxy(type_t *iface, const var_t *func, int idx,
   /* local variables */
   if (has_ret) {
     print_proxy( "%s", "" );
-    write_type_decl(proxy, retval->declspec.type, retval->name);
+    write_declspec_decl(proxy, &retval->declspec, retval->name);
     fprintf( proxy, ";\n" );
   }
   print_proxy( "RPC_MESSAGE _RpcMessage;\n" );
diff --git a/tools/widl/server.c b/tools/widl/server.c
index 6ce3db5e1c..fa457af2f3 100644
--- a/tools/widl/server.c
+++ b/tools/widl/server.c
@@ -55,7 +55,8 @@ static void write_function_stub(const type_t *iface, const var_t *func, unsigned
     unsigned char explicit_fc, implicit_fc;
     int has_full_pointer = is_full_pointer_function(func);
     const var_t *handle_var = get_func_handle_var( iface, func, &explicit_fc, &implicit_fc );
-    type_t *ret_type = type_function_get_rettype(func->declspec.type);
+    const decl_spec_t *ret_declspec = type_function_get_retdeclspec(func->declspec.type);
+    type_t *ret_type = ret_declspec->type;
 
     if (is_interpreted_func( iface, func )) return;
 
@@ -159,7 +160,7 @@ static void write_function_stub(const type_t *iface, const var_t *func, unsigned
     {
         print_server("__frame->_RetVal = NDRSContextUnmarshall((char*)0, _pRpcMessage->DataRepresentation);\n");
         print_server("*((");
-        write_type_decl(server, ret_type, NULL);
+        write_declspec_decl(server, ret_declspec, NULL);
         fprintf(server, "*)NDRSContextValue(__frame->_RetVal)) = ");
     }
     else
@@ -185,7 +186,7 @@ static void write_function_stub(const type_t *iface, const var_t *func, unsigned
                  * be direct, otherwise it is a pointer */
                 const char *ch_ptr = is_aliaschain_attr(var->declspec.type, ATTR_CONTEXTHANDLE) ? "*" : "";
                 print_server("(");
-                write_type_decl_left(server, var->declspec.type);
+                write_declspec_decl_left(server, &var->declspec);
                 fprintf(server, ")%sNDRSContextValue(__frame->%s)", ch_ptr, var->name);
             }
             else
diff --git a/tools/widl/typegen.c b/tools/widl/typegen.c
index ddf555cd9b..eebb99f0ef 100644
--- a/tools/widl/typegen.c
+++ b/tools/widl/typegen.c
@@ -85,14 +85,14 @@ static const unsigned short IsSimpleRef = 0x0100;
 
 static unsigned int field_memsize(const type_t *type, unsigned int *offset);
 static unsigned int fields_memsize(const var_list_t *fields, unsigned int *align);
-static unsigned int write_array_tfs(FILE *file, const attr_list_t *attrs, type_t *type,
+static unsigned int write_array_tfs(FILE *file, const attr_list_t *attrs, const decl_spec_t *declspec,
                                     const char *name, unsigned int *typestring_offset);
-static unsigned int write_struct_tfs(FILE *file, type_t *type, const char *name, unsigned int *tfsoff);
-static int write_embedded_types(FILE *file, const attr_list_t *attrs, type_t *type,
+static unsigned int write_struct_tfs(FILE *file, const decl_spec_t *declspec, const char *name, unsigned int *tfsoff);
+static int write_embedded_types(FILE *file, const attr_list_t *attrs, const decl_spec_t *declspec,
                                 const char *name, int write_ptr, unsigned int *tfsoff);
 static const var_t *find_array_or_string_in_struct(const type_t *type);
 static unsigned int write_string_tfs(FILE *file, const attr_list_t *attrs,
-                                     type_t *type, enum type_context context,
+                                     const decl_spec_t *declspec, enum type_context context,
                                      const char *name, unsigned int *typestring_offset);
 static unsigned int get_required_buffer_size_type( const type_t *type, const char *name,
                                                    const attr_list_t *attrs, int toplevel_param,
@@ -2216,22 +2216,23 @@ static unsigned int write_simple_pointer(FILE *file, const attr_list_t *attrs,
     return 4;
 }
 
-static void print_start_tfs_comment(FILE *file, type_t *t, unsigned int tfsoff)
+static void print_start_tfs_comment(FILE *file, const decl_spec_t *ds, unsigned int tfsoff)
 {
     print_file(file, 0, "/* %u (", tfsoff);
-    write_type_decl(file, t, NULL);
+    write_declspec_decl(file, ds, NULL);
     print_file(file, 0, ") */\n");
 }
 
 static unsigned int write_pointer_tfs(FILE *file, const attr_list_t *attrs,
-                                      type_t *type, unsigned int ref_offset,
+                                      const decl_spec_t *declspec, unsigned int ref_offset,
                                       enum type_context context,
                                       unsigned int *typestring_offset)
 {
     unsigned int offset = *typestring_offset;
+    type_t *type = declspec->type;
     type_t *ref = type_pointer_get_ref_type(type);
 
-    print_start_tfs_comment(file, type, offset);
+    print_start_tfs_comment(file, declspec, offset);
     update_tfsoff(type, offset, file);
 
     switch (typegen_detect_type(ref, attrs, TDT_ALL_TYPES))
@@ -2274,10 +2275,11 @@ static int user_type_has_variable_size(const type_t *t)
     return FALSE;
 }
 
-static unsigned int write_user_tfs(FILE *file, type_t *type, unsigned int *tfsoff)
+static unsigned int write_user_tfs(FILE *file, const decl_spec_t *declspec, unsigned int *tfsoff)
 {
     unsigned int start, absoff, flags;
     const char *name = NULL;
+    type_t *type = declspec->type;
     type_t *utype = get_user_type(type, &name);
     unsigned int usize = type_memsize(utype);
     unsigned int ualign = type_buffer_alignment(utype);
@@ -2295,6 +2297,7 @@ static unsigned int write_user_tfs(FILE *file, type_t *type, unsigned int *tfsof
         type_get_type(utype) == TYPE_ENUM)
     {
         unsigned char fc;
+        decl_spec_t ds;
 
         if (type_get_type(utype) == TYPE_ENUM)
             fc = get_enum_fc(utype);
@@ -2302,7 +2305,7 @@ static unsigned int write_user_tfs(FILE *file, type_t *type, unsigned int *tfsof
             fc = get_basic_fc(utype);
 
         absoff = *tfsoff;
-        print_start_tfs_comment(file, utype, absoff);
+        print_start_tfs_comment(file, init_declspec(&ds, utype), absoff);
         print_file(file, 2, "0x%x,\t/* %s */\n", fc, string_of_type(fc));
         print_file(file, 2, "0x5c,\t/* FC_PAD */\n");
         *tfsoff += 2;
@@ -2310,7 +2313,10 @@ static unsigned int write_user_tfs(FILE *file, type_t *type, unsigned int *tfsof
     else
     {
         if (!processed(utype))
-            write_embedded_types(file, NULL, utype, utype->name, TRUE, tfsoff);
+        {
+            decl_spec_t ds;
+            write_embedded_types(file, NULL, init_declspec(&ds, utype), utype->name, TRUE, tfsoff);
+        }
         absoff = utype->typestring_offset;
     }
 
@@ -2323,7 +2329,7 @@ static unsigned int write_user_tfs(FILE *file, type_t *type, unsigned int *tfsof
 
     start = *tfsoff;
     update_tfsoff(type, start, file);
-    print_start_tfs_comment(file, type, start);
+    print_start_tfs_comment(file, declspec, start);
     print_file(file, 2, "0x%x,\t/* FC_USER_MARSHAL */\n", FC_USER_MARSHAL);
     print_file(file, 2, "0x%x,\t/* Alignment= %d, Flags= %02x */\n",
                flags | (ualign - 1), ualign - 1, flags);
@@ -2380,7 +2386,8 @@ static void write_member_type(FILE *file, const type_t *cont,
 static void write_array_element_type(FILE *file, const attr_list_t *attrs, const type_t *type,
                                      int cont_is_complex, unsigned int *tfsoff)
 {
-    type_t *elem = type_array_get_element_type(type);
+    const decl_spec_t *element = type_array_get_element(type);
+    type_t *elem = element->type;
 
     if (!is_embedded_complex(elem) && is_ptr(elem))
     {
@@ -2394,7 +2401,7 @@ static void write_array_element_type(FILE *file, const attr_list_t *attrs, const
         }
         if (cont_is_complex && is_string_type(attrs, elem))
         {
-            write_string_tfs(file, NULL, elem, TYPE_CONTEXT_CONTAINER, NULL, tfsoff);
+            write_string_tfs(file, NULL, element, TYPE_CONTEXT_CONTAINER, NULL, tfsoff);
             return;
         }
         if (!is_string_type(NULL, elem) &&
@@ -2449,10 +2456,11 @@ static void write_descriptors(FILE *file, type_t *type, unsigned int *tfsoff)
 }
 
 static int write_pointer_description_offsets(
-    FILE *file, const attr_list_t *attrs, type_t *type,
+    FILE *file, const attr_list_t *attrs, const decl_spec_t *declspec,
     unsigned int *offset_in_memory, unsigned int *offset_in_buffer,
     unsigned int *typestring_offset)
 {
+    type_t *type = declspec->type;
     int written = 0;
 
     if ((is_ptr(type) && type_get_type(type_pointer_get_ref_type(type)) != TYPE_INTERFACE) ||
@@ -2483,7 +2491,7 @@ static int write_pointer_description_offsets(
             type_t *ref = type_pointer_get_ref_type(type);
 
             if (is_string_type(attrs, type))
-                write_string_tfs(file, attrs, type, TYPE_CONTEXT_CONTAINER, NULL, typestring_offset);
+                write_string_tfs(file, attrs, declspec, TYPE_CONTEXT_CONTAINER, NULL, typestring_offset);
             else if (processed(ref))
                 write_nonsimple_pointer(file, attrs, type, TYPE_CONTEXT_CONTAINER,
                                         ref->typestring_offset, typestring_offset);
@@ -2508,7 +2516,7 @@ static int write_pointer_description_offsets(
     if (is_array(type))
     {
         return write_pointer_description_offsets(
-            file, attrs, type_array_get_element_type(type), offset_in_memory,
+            file, attrs, type_array_get_element(type), offset_in_memory,
             offset_in_buffer, typestring_offset);
     }
     else if (is_non_complex_struct(type))
@@ -2527,7 +2535,7 @@ static int write_pointer_description_offsets(
                 *offset_in_buffer += padding;
             }
             written += write_pointer_description_offsets(
-                file, v->attrs, v->declspec.type, offset_in_memory, offset_in_buffer,
+                file, v->attrs, &v->declspec, offset_in_memory, offset_in_buffer,
                 typestring_offset);
         }
     }
@@ -2547,10 +2555,11 @@ static int write_pointer_description_offsets(
 }
 
 static int write_no_repeat_pointer_descriptions(
-    FILE *file, const attr_list_t *attrs, type_t *type,
+    FILE *file, const attr_list_t *attrs, const decl_spec_t *declspec,
     unsigned int *offset_in_memory, unsigned int *offset_in_buffer,
     unsigned int *typestring_offset)
 {
+    type_t *type = declspec->type;
     int written = 0;
 
     if (is_ptr(type) ||
@@ -2560,7 +2569,7 @@ static int write_no_repeat_pointer_descriptions(
         print_file(file, 2, "0x%02x, /* FC_PAD */\n", FC_PAD);
         *typestring_offset += 2;
 
-        return write_pointer_description_offsets(file, attrs, type,
+        return write_pointer_description_offsets(file, attrs, declspec,
                        offset_in_memory, offset_in_buffer, typestring_offset);
     }
 
@@ -2579,7 +2588,7 @@ static int write_no_repeat_pointer_descriptions(
                 *offset_in_buffer += padding;
             }
             written += write_no_repeat_pointer_descriptions(
-                file, v->attrs, v->declspec.type,
+                file, v->attrs, &v->declspec,
                 offset_in_memory, offset_in_buffer, typestring_offset);
         }
     }
@@ -2598,10 +2607,11 @@ static int write_no_repeat_pointer_descriptions(
 /* Note: if file is NULL return value is number of pointers to write, else
  * it is the number of type format characters written */
 static int write_fixed_array_pointer_descriptions(
-    FILE *file, const attr_list_t *attrs, type_t *type,
+    FILE *file, const attr_list_t *attrs, const decl_spec_t *declspec,
     unsigned int *offset_in_memory, unsigned int *offset_in_buffer,
     unsigned int *typestring_offset)
 {
+    type_t *type = declspec->type;
     int pointer_count = 0;
 
     if (type_get_type(type) == TYPE_ARRAY &&
@@ -2611,7 +2621,7 @@ static int write_fixed_array_pointer_descriptions(
         /* unfortunately, this needs to be done in two passes to avoid
          * writing out redundant FC_FIXED_REPEAT descriptions */
         pointer_count = write_pointer_description_offsets(
-            NULL, attrs, type_array_get_element_type(type), NULL, NULL, &temp);
+            NULL, attrs, type_array_get_element(type), NULL, NULL, &temp);
         if (pointer_count > 0)
         {
             unsigned int increment_size;
@@ -2629,7 +2639,7 @@ static int write_fixed_array_pointer_descriptions(
             *typestring_offset += 10;
 
             pointer_count = write_pointer_description_offsets(
-                file, attrs, type, &offset_of_array_pointer_mem,
+                file, attrs, declspec, &offset_of_array_pointer_mem,
                 &offset_of_array_pointer_buf, typestring_offset);
         }
     }
@@ -2648,7 +2658,7 @@ static int write_fixed_array_pointer_descriptions(
                 *offset_in_buffer += padding;
             }
             pointer_count += write_fixed_array_pointer_descriptions(
-                file, v->attrs, v->declspec.type, offset_in_memory, offset_in_buffer,
+                file, v->attrs, &v->declspec, offset_in_memory, offset_in_buffer,
                 typestring_offset);
         }
     }
@@ -2682,7 +2692,7 @@ static int write_conformant_array_pointer_descriptions(
         /* unfortunately, this needs to be done in two passes to avoid
          * writing out redundant FC_VARIABLE_REPEAT descriptions */
         pointer_count = write_pointer_description_offsets(
-            NULL, attrs, type_array_get_element_type(type), NULL, NULL, &temp);
+            NULL, attrs, type_array_get_element(type), NULL, NULL, &temp);
         if (pointer_count > 0)
         {
             unsigned int increment_size;
@@ -2702,7 +2712,7 @@ static int write_conformant_array_pointer_descriptions(
             *typestring_offset += 8;
 
             pointer_count = write_pointer_description_offsets(
-                file, attrs, type_array_get_element_type(type),
+                file, attrs, type_array_get_element(type),
                 &offset_of_array_pointer_mem, &offset_of_array_pointer_buf,
                 typestring_offset);
         }
@@ -2726,7 +2736,7 @@ static int write_varying_array_pointer_descriptions(
         /* unfortunately, this needs to be done in two passes to avoid
          * writing out redundant FC_VARIABLE_REPEAT descriptions */
         pointer_count = write_pointer_description_offsets(
-            NULL, attrs, type_array_get_element_type(type), NULL, NULL, &temp);
+            NULL, attrs, type_array_get_element(type), NULL, NULL, &temp);
         if (pointer_count > 0)
         {
             unsigned int increment_size;
@@ -2744,7 +2754,7 @@ static int write_varying_array_pointer_descriptions(
             *typestring_offset += 8;
 
             pointer_count = write_pointer_description_offsets(
-                file, attrs, type_array_get_element_type(type), offset_in_memory,
+                file, attrs, type_array_get_element(type), offset_in_memory,
                 offset_in_buffer, typestring_offset);
         }
     }
@@ -2789,9 +2799,10 @@ static int write_varying_array_pointer_descriptions(
     return pointer_count;
 }
 
-static void write_pointer_description(FILE *file, const attr_list_t *attrs, type_t *type,
+static void write_pointer_description(FILE *file, const attr_list_t *attrs, const decl_spec_t *declspec,
                                       unsigned int *typestring_offset)
 {
+    type_t *type = declspec->type;
     unsigned int offset_in_buffer;
     unsigned int offset_in_memory;
 
@@ -2802,7 +2813,7 @@ static void write_pointer_description(FILE *file, const attr_list_t *attrs, type
         offset_in_memory = 0;
         offset_in_buffer = 0;
         write_no_repeat_pointer_descriptions(
-            file, NULL, type,
+            file, NULL, declspec,
             &offset_in_memory, &offset_in_buffer, typestring_offset);
     }
 
@@ -2810,7 +2821,7 @@ static void write_pointer_description(FILE *file, const attr_list_t *attrs, type
     offset_in_memory = 0;
     offset_in_buffer = 0;
     write_fixed_array_pointer_descriptions(
-        file, NULL, type,
+        file, NULL, declspec,
         &offset_in_memory, &offset_in_buffer, typestring_offset);
 
     /* pass 3: search for pointers in conformant only arrays (but don't descend
@@ -2836,9 +2847,10 @@ static void write_pointer_description(FILE *file, const attr_list_t *attrs, type
 }
 
 static unsigned int write_string_tfs(FILE *file, const attr_list_t *attrs,
-                                     type_t *type, enum type_context context,
+                                     const decl_spec_t *declspec, enum type_context context,
                                      const char *name, unsigned int *typestring_offset)
 {
+    type_t *type = declspec->type;
     unsigned int start_offset;
     unsigned char rtype;
     type_t *elem_type;
@@ -2852,7 +2864,7 @@ static unsigned int write_string_tfs(FILE *file, const attr_list_t *attrs,
         int pointer_type = get_pointer_fc_context(type, attrs, context);
         if (!pointer_type)
             pointer_type = FC_RP;
-        print_start_tfs_comment(file, type, *typestring_offset);
+        print_start_tfs_comment(file, declspec, *typestring_offset);
         print_file(file, 2,"0x%x, 0x%x,\t/* %s%s */\n",
                    pointer_type, flag, string_of_type(pointer_type),
                    flag ? " [simple_pointer]" : "");
@@ -2871,7 +2883,7 @@ static unsigned int write_string_tfs(FILE *file, const attr_list_t *attrs,
         elem_type = type_pointer_get_ref_type(type);
 
     if (type_get_type(elem_type) == TYPE_POINTER && is_array(type))
-        return write_array_tfs(file, attrs, type, name, typestring_offset);
+        return write_array_tfs(file, attrs, declspec, name, typestring_offset);
 
     if (type_get_type(elem_type) != TYPE_BASIC)
     {
@@ -2945,9 +2957,10 @@ static unsigned int write_string_tfs(FILE *file, const attr_list_t *attrs,
     }
 }
 
-static unsigned int write_array_tfs(FILE *file, const attr_list_t *attrs, type_t *type,
+static unsigned int write_array_tfs(FILE *file, const attr_list_t *attrs, const decl_spec_t *declspec,
                                     const char *name, unsigned int *typestring_offset)
 {
+    type_t *type = declspec->type;
     const expr_t *length_is = type_array_get_variance(type);
     const expr_t *size_is = type_array_get_conformance(type);
     unsigned int align;
@@ -2960,7 +2973,7 @@ static unsigned int write_array_tfs(FILE *file, const attr_list_t *attrs, type_t
         : 0;
 
     if (!is_string_type(attrs, type_array_get_element_type(type)))
-        write_embedded_types(file, attrs, type_array_get_element_type(type), name, FALSE, typestring_offset);
+        write_embedded_types(file, attrs, type_array_get_element(type), name, FALSE, typestring_offset);
 
     size = type_memsize(is_conformant_array(type) ? type_array_get_element_type(type) : type);
     align = type_buffer_alignment(is_conformant_array(type) ? type_array_get_element_type(type) : type);
@@ -2968,7 +2981,7 @@ static unsigned int write_array_tfs(FILE *file, const attr_list_t *attrs, type_t
 
     start_offset = *typestring_offset;
     update_tfsoff(type, start_offset, file);
-    print_start_tfs_comment(file, type, start_offset);
+    print_start_tfs_comment(file, declspec, start_offset);
     print_file(file, 2, "0x%02x,\t/* %s */\n", fc, string_of_type(fc));
     print_file(file, 2, "0x%x,\t/* %d */\n", align - 1, align - 1);
     *typestring_offset += 2;
@@ -3023,7 +3036,7 @@ static unsigned int write_array_tfs(FILE *file, const attr_list_t *attrs, type_t
             print_file(file, 2, "0x%x,\t/* FC_PP */\n", FC_PP);
             print_file(file, 2, "0x%x,\t/* FC_PAD */\n", FC_PAD);
             *typestring_offset += 2;
-            write_pointer_description(file, is_string_type(attrs, type) ? attrs : NULL, type, typestring_offset);
+            write_pointer_description(file, is_string_type(attrs, type) ? attrs : NULL, declspec, typestring_offset);
             print_file(file, 2, "0x%x,\t/* FC_END */\n", FC_END);
             *typestring_offset += 1;
         }
@@ -3130,9 +3143,10 @@ static void write_struct_members(FILE *file, const type_t *type,
     write_end(file, typestring_offset);
 }
 
-static unsigned int write_struct_tfs(FILE *file, type_t *type,
+static unsigned int write_struct_tfs(FILE *file, const decl_spec_t *declspec,
                                      const char *name, unsigned int *tfsoff)
 {
+    type_t *type = declspec->type;
     const type_t *save_current_structure = current_structure;
     unsigned int total_size;
     const var_t *array;
@@ -3155,15 +3169,15 @@ static unsigned int write_struct_tfs(FILE *file, type_t *type,
               name, USHRT_MAX, total_size - USHRT_MAX);
 
     if (fields) LIST_FOR_EACH_ENTRY(f, fields, var_t, entry)
-        write_embedded_types(file, f->attrs, f->declspec.type, f->name, FALSE, tfsoff);
+        write_embedded_types(file, f->attrs, &f->declspec, f->name, FALSE, tfsoff);
 
     array = find_array_or_string_in_struct(type);
     if (array && !processed(array->declspec.type))
     {
         if(is_string_type(array->attrs, array->declspec.type))
-            write_string_tfs(file, array->attrs, array->declspec.type, TYPE_CONTEXT_CONTAINER, array->name, tfsoff);
+            write_string_tfs(file, array->attrs, &array->declspec, TYPE_CONTEXT_CONTAINER, array->name, tfsoff);
         else
-            write_array_tfs(file, array->attrs, array->declspec.type, array->name, tfsoff);
+            write_array_tfs(file, array->attrs, &array->declspec, array->name, tfsoff);
     }
 
     corroff = *tfsoff;
@@ -3171,7 +3185,7 @@ static unsigned int write_struct_tfs(FILE *file, type_t *type,
 
     start_offset = *tfsoff;
     update_tfsoff(type, start_offset, file);
-    print_start_tfs_comment(file, type, start_offset);
+    print_start_tfs_comment(file, declspec, start_offset);
     print_file(file, 2, "0x%x,\t/* %s */\n", fc, string_of_type(fc));
     print_file(file, 2, "0x%x,\t/* %d */\n", align - 1, align - 1);
     print_file(file, 2, "NdrFcShort(0x%hx),\t/* %d */\n", (unsigned short)total_size, total_size);
@@ -3210,7 +3224,7 @@ static unsigned int write_struct_tfs(FILE *file, type_t *type,
         print_file(file, 2, "0x%x,\t/* FC_PP */\n", FC_PP);
         print_file(file, 2, "0x%x,\t/* FC_PAD */\n", FC_PAD);
         *tfsoff += 2;
-        write_pointer_description(file, NULL, type, tfsoff);
+        write_pointer_description(file, NULL, declspec, tfsoff);
         print_file(file, 2, "0x%x,\t/* FC_END */\n", FC_END);
         *tfsoff += 1;
     }
@@ -3225,14 +3239,15 @@ static unsigned int write_struct_tfs(FILE *file, type_t *type,
         type->ptrdesc = *tfsoff;
         if (fields) LIST_FOR_EACH_ENTRY(f, fields, const var_t, entry)
         {
-            type_t *ft = f->declspec.type;
+            const decl_spec_t *fds = &f->declspec;
+            type_t *ft = fds->type;
             switch (typegen_detect_type(ft, f->attrs, TDT_IGNORE_STRINGS))
             {
             case TGT_POINTER:
                 if (is_string_type(f->attrs, ft))
-                    write_string_tfs(file, f->attrs, ft, TYPE_CONTEXT_CONTAINER, f->name, tfsoff);
+                    write_string_tfs(file, f->attrs, fds, TYPE_CONTEXT_CONTAINER, f->name, tfsoff);
                 else
-                    write_pointer_tfs(file, f->attrs, ft,
+                    write_pointer_tfs(file, f->attrs, fds,
                                       type_pointer_get_ref_type(ft)->typestring_offset,
                                       TYPE_CONTEXT_CONTAINER, tfsoff);
                 break;
@@ -3295,8 +3310,9 @@ static void write_branch_type(FILE *file, const type_t *t, unsigned int *tfsoff)
 }
 
 static unsigned int write_union_tfs(FILE *file, const attr_list_t *attrs,
-                                    type_t *type, unsigned int *tfsoff)
+                                    const decl_spec_t *declspec, unsigned int *tfsoff)
 {
+    type_t* type = declspec->type;
     unsigned int start_offset;
     unsigned int size;
     var_list_t *fields;
@@ -3322,12 +3338,12 @@ static unsigned int write_union_tfs(FILE *file, const attr_list_t *attrs,
         if (cases)
             nbranch += list_count(cases);
         if (f->declspec.type)
-            write_embedded_types(file, f->attrs, f->declspec.type, f->name, TRUE, tfsoff);
+            write_embedded_types(file, f->attrs, &f->declspec, f->name, TRUE, tfsoff);
     }
 
     start_offset = *tfsoff;
     update_tfsoff(type, start_offset, file);
-    print_start_tfs_comment(file, type, start_offset);
+    print_start_tfs_comment(file, declspec, start_offset);
     if (type_get_type(type) == TYPE_ENCAPSULATED_UNION)
     {
         const var_t *sv = type_union_get_switch_value(type);
@@ -3460,16 +3476,17 @@ static unsigned int write_union_tfs(FILE *file, const attr_list_t *attrs,
     return start_offset;
 }
 
-static unsigned int write_ip_tfs(FILE *file, const attr_list_t *attrs, type_t *type,
+static unsigned int write_ip_tfs(FILE *file, const attr_list_t *attrs, const decl_spec_t *declspec,
                                  unsigned int *typeformat_offset)
 {
     unsigned int i;
+    type_t *type = declspec->type;
     unsigned int start_offset = *typeformat_offset;
     expr_t *iid = get_attrp(attrs, ATTR_IIDIS);
 
     if (!iid && processed(type)) return type->typestring_offset;
 
-    print_start_tfs_comment(file, type, start_offset);
+    print_start_tfs_comment(file, declspec, start_offset);
     update_tfsoff(type, start_offset, file);
 
     if (iid)
@@ -3505,14 +3522,15 @@ static unsigned int write_ip_tfs(FILE *file, const attr_list_t *attrs, type_t *t
 
 static unsigned int write_contexthandle_tfs(FILE *file,
                                             const attr_list_t *attrs,
-                                            type_t *type,
+                                            const decl_spec_t *declspec,
                                             enum type_context context,
                                             unsigned int *typeformat_offset)
 {
+    type_t *type = declspec->type;
     unsigned int start_offset = *typeformat_offset;
     unsigned char flags = get_contexthandle_flags( current_iface, attrs, type, context == TYPE_CONTEXT_RETVAL );
 
-    print_start_tfs_comment(file, type, start_offset);
+    print_start_tfs_comment(file, declspec, start_offset);
 
     if (flags & 0x80)  /* via ptr */
     {
@@ -3580,21 +3598,22 @@ static unsigned int write_range_tfs(FILE *file, const attr_list_t *attrs,
 }
 
 static unsigned int write_type_tfs(FILE *file, const attr_list_t *attrs,
-                                   type_t *type, const char *name,
+                                   const decl_spec_t *declspec, const char *name,
                                    enum type_context context,
                                    unsigned int *typeformat_offset)
 {
     unsigned int offset;
+    type_t *type = declspec->type;
 
     switch (typegen_detect_type(type, attrs, TDT_ALL_TYPES))
     {
     case TGT_CTXT_HANDLE:
     case TGT_CTXT_HANDLE_POINTER:
-        return write_contexthandle_tfs(file, attrs, type, context, typeformat_offset);
+        return write_contexthandle_tfs(file, attrs, declspec, context, typeformat_offset);
     case TGT_USER_TYPE:
-        return write_user_tfs(file, type, typeformat_offset);
+        return write_user_tfs(file, declspec, typeformat_offset);
     case TGT_STRING:
-        return write_string_tfs(file, attrs, type, context, name, typeformat_offset);
+        return write_string_tfs(file, attrs, declspec, context, name, typeformat_offset);
     case TGT_ARRAY:
     {
         unsigned int off;
@@ -3602,7 +3621,7 @@ static unsigned int write_type_tfs(FILE *file, const attr_list_t *attrs,
         if ((context != TYPE_CONTEXT_CONTAINER &&
              context != TYPE_CONTEXT_CONTAINER_NO_POINTERS) ||
             !is_conformant_array(type) || type_array_is_decl_as_ptr(type))
-            off = write_array_tfs(file, attrs, type, name, typeformat_offset);
+            off = write_array_tfs(file, attrs, declspec, name, typeformat_offset);
         else
             off = 0;
         if (context != TYPE_CONTEXT_CONTAINER &&
@@ -3628,9 +3647,9 @@ static unsigned int write_type_tfs(FILE *file, const attr_list_t *attrs,
         return off;
     }
     case TGT_STRUCT:
-        return write_struct_tfs(file, type, name, typeformat_offset);
+        return write_struct_tfs(file, declspec, name, typeformat_offset);
     case TGT_UNION:
-        return write_union_tfs(file, attrs, type, typeformat_offset);
+        return write_union_tfs(file, attrs, declspec, typeformat_offset);
     case TGT_ENUM:
     case TGT_BASIC:
         /* nothing to do */
@@ -3643,11 +3662,11 @@ static unsigned int write_type_tfs(FILE *file, const attr_list_t *attrs,
         return write_range_tfs(file, attrs, type, range_list, typeformat_offset);
     }
     case TGT_IFACE_POINTER:
-        return write_ip_tfs(file, attrs, type, typeformat_offset);
+        return write_ip_tfs(file, attrs, declspec, typeformat_offset);
     case TGT_POINTER:
     {
         enum type_context ref_context;
-        type_t *ref = type_pointer_get_ref_type(type);
+        const decl_spec_t *ref = type_pointer_get_ref(type);
 
         if (context == TYPE_CONTEXT_TOPLEVELPARAM)
             ref_context = TYPE_CONTEXT_PARAM;
@@ -3656,10 +3675,10 @@ static unsigned int write_type_tfs(FILE *file, const attr_list_t *attrs,
         else
             ref_context = context;
 
-        if (is_string_type(attrs, ref))
+        if (is_string_type(attrs, ref->type))
         {
             if (context != TYPE_CONTEXT_CONTAINER_NO_POINTERS)
-                write_pointer_tfs(file, attrs, type, *typeformat_offset + 4, context, typeformat_offset);
+                write_pointer_tfs(file, attrs, declspec, *typeformat_offset + 4, context, typeformat_offset);
 
             offset = write_type_tfs(file, attrs, ref, name, ref_context, typeformat_offset);
             if (context == TYPE_CONTEXT_CONTAINER_NO_POINTERS)
@@ -3667,11 +3686,11 @@ static unsigned int write_type_tfs(FILE *file, const attr_list_t *attrs,
             return offset;
         }
 
-        offset = write_type_tfs( file, attrs, type_pointer_get_ref_type(type), name,
+        offset = write_type_tfs( file, attrs, type_pointer_get_ref(type), name,
                                  ref_context, typeformat_offset);
         if (context == TYPE_CONTEXT_CONTAINER_NO_POINTERS)
             return 0;
-        return write_pointer_tfs(file, attrs, type, offset, context, typeformat_offset);
+        return write_pointer_tfs(file, attrs, declspec, offset, context, typeformat_offset);
     }
     case TGT_INVALID:
         break;
@@ -3680,10 +3699,10 @@ static unsigned int write_type_tfs(FILE *file, const attr_list_t *attrs,
     return 0;
 }
 
-static int write_embedded_types(FILE *file, const attr_list_t *attrs, type_t *type,
+static int write_embedded_types(FILE *file, const attr_list_t *attrs, const decl_spec_t *declspec,
                                 const char *name, int write_ptr, unsigned int *tfsoff)
 {
-    return write_type_tfs(file, attrs, type, name, write_ptr ? TYPE_CONTEXT_CONTAINER : TYPE_CONTEXT_CONTAINER_NO_POINTERS, tfsoff);
+    return write_type_tfs(file, attrs, declspec, name, write_ptr ? TYPE_CONTEXT_CONTAINER : TYPE_CONTEXT_CONTAINER_NO_POINTERS, tfsoff);
 }
 
 static void process_tfs_iface(type_t *iface, FILE *file, int indent, unsigned int *offset)
@@ -3710,12 +3729,12 @@ static void process_tfs_iface(type_t *iface, FILE *file, int indent, unsigned in
 
             var = type_function_get_retval(func->declspec.type);
             if (!is_void(var->declspec.type))
-                var->typestring_offset = write_type_tfs( file, var->attrs, var->declspec.type, func->name,
+                var->typestring_offset = write_type_tfs( file, var->attrs, &var->declspec, func->name,
                                                          TYPE_CONTEXT_RETVAL, offset);
 
             if (type_function_get_args(func->declspec.type))
                 LIST_FOR_EACH_ENTRY( var, type_function_get_args(func->declspec.type), var_t, entry )
-                    var->typestring_offset = write_type_tfs( file, var->attrs, var->declspec.type, var->name,
+                    var->typestring_offset = write_type_tfs( file, var->attrs, &var->declspec, var->name,
                                                              TYPE_CONTEXT_TOPLEVELPARAM, offset );
             break;
 
@@ -3727,9 +3746,12 @@ static void process_tfs_iface(type_t *iface, FILE *file, int indent, unsigned in
             {
                 if (is_attr(type_entry->type->attrs, ATTR_ENCODE)
                     || is_attr(type_entry->type->attrs, ATTR_DECODE))
+                {
+                    decl_spec_t ds;
                     type_entry->type->typestring_offset = write_type_tfs( file,
-                            type_entry->type->attrs, type_entry->type, type_entry->type->name,
+                            type_entry->type->attrs, init_declspec(&ds, type_entry->type), type_entry->type->name,
                             TYPE_CONTEXT_CONTAINER, offset);
+                }
             }
             break;
         }
@@ -3976,7 +3998,8 @@ void print_phase_basetype(FILE *file, int indent, const char *local_var_prefix,
                           enum remoting_phase phase, enum pass pass, const var_t *var,
                           const char *varname)
 {
-    type_t *type = var->declspec.type;
+    const decl_spec_t *declspec = &var->declspec;
+    type_t *type = declspec->type;
     unsigned int alignment = 0;
 
     /* no work to do for other phases, buffer sizing is done elsewhere */
@@ -4007,8 +4030,8 @@ void print_phase_basetype(FILE *file, int indent, const char *local_var_prefix,
     }
     else
     {
-        const type_t *ref = is_ptr(type) ? type_pointer_get_ref_type(type) : type;
-        switch (get_basic_fc(ref))
+        const decl_spec_t *ref = is_ptr(type) ? type_pointer_get_ref(type) : declspec;
+        switch (get_basic_fc(ref->type))
         {
         case FC_BYTE:
         case FC_CHAR:
@@ -4045,7 +4068,7 @@ void print_phase_basetype(FILE *file, int indent, const char *local_var_prefix,
 
         default:
             error("print_phase_basetype: Unsupported type: %s (0x%02x, ptr_level: 0)\n",
-                  var->name, get_basic_fc(ref));
+                  var->name, get_basic_fc(ref->type));
         }
 
         if (phase == PHASE_MARSHAL && alignment > 1)
@@ -4056,7 +4079,7 @@ void print_phase_basetype(FILE *file, int indent, const char *local_var_prefix,
         if (phase == PHASE_MARSHAL)
         {
             print_file(file, indent, "*(");
-            write_type_decl(file, is_ptr(type) ? type_pointer_get_ref_type(type) : type, NULL);
+            write_declspec_decl(file, is_ptr(type) ? type_pointer_get_ref(type) : declspec, NULL);
             if (is_ptr(type))
                 fprintf(file, " *)__frame->_StubMsg.Buffer = *");
             else
@@ -4067,7 +4090,7 @@ void print_phase_basetype(FILE *file, int indent, const char *local_var_prefix,
         else if (phase == PHASE_UNMARSHAL)
         {
             print_file(file, indent, "if (__frame->_StubMsg.Buffer + sizeof(");
-            write_type_decl(file, is_ptr(type) ? type_pointer_get_ref_type(type) : type, NULL);
+            write_declspec_decl(file, is_ptr(type) ? type_pointer_get_ref(type) : declspec, NULL);
             fprintf(file, ") > __frame->_StubMsg.BufferEnd)\n");
             print_file(file, indent, "{\n");
             print_file(file, indent + 1, "RpcRaiseException(RPC_X_BAD_STUB_DATA);\n");
@@ -4079,12 +4102,12 @@ void print_phase_basetype(FILE *file, int indent, const char *local_var_prefix,
                 fprintf(file, " = (");
             else
                 fprintf(file, " = *(");
-            write_type_decl(file, is_ptr(type) ? type_pointer_get_ref_type(type) : type, NULL);
+            write_declspec_decl(file, is_ptr(type) ? type_pointer_get_ref(type) : declspec, NULL);
             fprintf(file, " *)__frame->_StubMsg.Buffer;\n");
         }
 
         print_file(file, indent, "__frame->_StubMsg.Buffer += sizeof(");
-        write_type_decl(file, is_ptr(type) ? type_pointer_get_ref_type(type) : type, NULL);
+        write_declspec_decl(file, is_ptr(type) ? type_pointer_get_ref(type) : declspec, NULL);
         fprintf(file, ");\n");
     }
 }
@@ -4389,9 +4412,9 @@ static void write_remoting_arg(FILE *file, int indent, const var_t *func, const
             range_max = LIST_ENTRY(list_next(range_list, list_head(range_list)), const expr_t, entry);
 
             print_file(file, indent, "if ((%s%s < (", local_var_prefix, var->name);
-            write_type_decl(file, var->declspec.type, NULL);
+            write_declspec_decl(file, &var->declspec, NULL);
             fprintf(file, ")0x%x) || (%s%s > (", range_min->cval, local_var_prefix, var->name);
-            write_type_decl(file, var->declspec.type, NULL);
+            write_declspec_decl(file, &var->declspec, NULL);
             fprintf(file, ")0x%x))\n", range_max->cval);
             print_file(file, indent, "{\n");
             print_file(file, indent+1, "RpcRaiseException(RPC_S_INVALID_BOUND);\n");
@@ -4616,7 +4639,7 @@ void declare_stub_args( FILE *file, int indent, const var_t *func )
         else
         {
             print_file(file, indent, "%s", "");
-            write_type_decl(file, var->declspec.type, var->name);
+            write_declspec_decl(file, &var->declspec, var->name);
             fprintf(file, ";\n");
         }
     }
@@ -4637,21 +4660,21 @@ void declare_stub_args( FILE *file, int indent, const var_t *func )
         {
             if (!in_attr && !is_conformant_array(var->declspec.type))
             {
-                type_t *type_to_print;
+                const decl_spec_t *declspec_to_print;
                 char name[16];
                 print_file(file, indent, "%s", "");
                 if (type_get_type(var->declspec.type) == TYPE_ARRAY &&
                     !type_array_is_decl_as_ptr(var->declspec.type))
-                    type_to_print = var->declspec.type;
+                    declspec_to_print = &var->declspec;
                 else
-                    type_to_print = type_pointer_get_ref_type(var->declspec.type);
+                    declspec_to_print = type_pointer_get_ref(var->declspec.type);
                 sprintf(name, "_W%u", i++);
-                write_type_decl(file, type_to_print, name);
+                write_declspec_decl(file, declspec_to_print, name);
                 fprintf(file, ";\n");
             }
 
             print_file(file, indent, "%s", "");
-            write_type_decl_left(file, var->declspec.type);
+            write_declspec_decl_left(file, &var->declspec);
             fprintf(file, " ");
             if (type_get_type(var->declspec.type) == TYPE_ARRAY &&
                 !type_array_is_decl_as_ptr(var->declspec.type)) {
@@ -4804,7 +4827,7 @@ void write_func_param_struct( FILE *file, const type_t *iface, const type_t *fun
     if (args) LIST_FOR_EACH_ENTRY( arg, args, const var_t, entry )
     {
         print_file(file, 2, "%s", "");
-        write_type_left( file, (type_t *)arg->declspec.type, NAME_DEFAULT, TRUE );
+        write_declspec_left( file, &arg->declspec, NAME_DEFAULT, TRUE );
         if (needs_space_after( arg->declspec.type )) fputc( ' ', file );
         if (is_array( arg->declspec.type ) && !type_array_is_decl_as_ptr( arg->declspec.type )) fputc( '*', file );
 
@@ -4821,7 +4844,7 @@ void write_func_param_struct( FILE *file, const type_t *iface, const type_t *fun
     if (add_retval && !is_void( retval->declspec.type ))
     {
         print_file(file, 2, "%s", "");
-        write_type_decl( file, retval->declspec.type, retval->name );
+        write_declspec_decl( file, &retval->declspec, retval->name );
         if (is_array( retval->declspec.type ) || is_ptr( retval->declspec.type ) ||
             type_memsize( retval->declspec.type ) == pointer_size)
             fprintf( file, ";\n" );
@@ -4868,10 +4891,11 @@ int write_expr_eval_routines(FILE *file, const char *iface)
         }
         else
         {
+            decl_spec_t declspec;
             print_file(file, 1, "%s", "");
-            write_type_left(file, (type_t *)eval->cont_type, NAME_DEFAULT, TRUE);
+            write_declspec_left(file, init_declspec(&declspec, (type_t*)eval->cont_type), NAME_DEFAULT, TRUE);
             fprintf(file, " *%s = (", var_name);
-            write_type_left(file, (type_t *)eval->cont_type, NAME_DEFAULT, TRUE);
+            write_declspec_left(file, init_declspec(&declspec, (type_t*)eval->cont_type), NAME_DEFAULT, TRUE);
             fprintf(file, " *)(pStubMsg->StackTop - %u);\n", eval->baseoff);
         }
         print_file(file, 1, "pStubMsg->Offset = 0;\n"); /* FIXME */
@@ -4965,7 +4989,8 @@ error:
 void write_client_call_routine( FILE *file, const type_t *iface, const var_t *func,
                                 const char *prefix, unsigned int proc_offset )
 {
-    type_t *rettype = type_function_get_rettype( func->declspec.type );
+    const decl_spec_t *retdeclspec = type_function_get_retdeclspec(func->declspec.type);
+    type_t *rettype = retdeclspec->type;
     int has_ret = !is_void( rettype );
     const var_list_t *args = type_function_get_args( func->declspec.type );
     const var_t *arg;
@@ -5015,7 +5040,7 @@ void write_client_call_routine( FILE *file, const type_t *iface, const var_t *fu
     if (has_ret)
     {
         print_file( file, 1, "return (" );
-        write_type_decl_left(file, rettype);
+        write_declspec_decl_left(file, retdeclspec);
         fprintf( file, ")%s;\n", pointer_size == 8 ? "_RetVal.Simple" : "*(LONG_PTR *)&_RetVal" );
     }
     print_file( file, 0, "}\n\n");
-- 
2.17.1




More information about the wine-devel mailing list