Reactos
at master 540 lines 25 kB view raw
1/* 2 * Copyright 2002 Ove Kaaven 3 * Copyright 2006-2008 Robert Shearman 4 * 5 * This library is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU Lesser General Public 7 * License as published by the Free Software Foundation; either 8 * version 2.1 of the License, or (at your option) any later version. 9 * 10 * This library is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * Lesser General Public License for more details. 14 * 15 * You should have received a copy of the GNU Lesser General Public 16 * License along with this library; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 18 */ 19 20#include "config.h" 21 22#include "widl.h" 23#include "typetree.h" 24 25#include "parser.tab.h" 26 27attr_t *attr_int( struct location where, enum attr_type attr_type, unsigned int val ) 28{ 29 attr_t *a = xmalloc( sizeof(attr_t) ); 30 a->where = where; 31 a->type = attr_type; 32 a->u.ival = val; 33 return a; 34} 35 36attr_t *attr_ptr( struct location where, enum attr_type attr_type, void *val ) 37{ 38 attr_t *a = xmalloc( sizeof(attr_t) ); 39 a->where = where; 40 a->type = attr_type; 41 a->u.pval = val; 42 return a; 43} 44 45int is_attr( const attr_list_t *list, enum attr_type attr_type ) 46{ 47 const attr_t *attr; 48 if (!list) return 0; 49 LIST_FOR_EACH_ENTRY( attr, list, const attr_t, entry ) 50 if (attr->type == attr_type) return 1; 51 return 0; 52} 53 54int is_ptrchain_attr( const var_t *var, enum attr_type attr_type ) 55{ 56 type_t *type = var->declspec.type; 57 if (is_attr( var->attrs, attr_type )) return 1; 58 for (;;) 59 { 60 if (is_attr( type->attrs, attr_type )) return 1; 61 else if (type_is_alias( type )) type = type_alias_get_aliasee_type( type ); 62 else if (type_is_ptr( type )) type = type_pointer_get_ref_type( type ); 63 else return 0; 64 } 65} 66 67int is_aliaschain_attr( const type_t *type, enum attr_type attr_type ) 68{ 69 const type_t *t = type; 70 for (;;) 71 { 72 if (is_attr( t->attrs, attr_type )) return 1; 73 else if (type_is_alias( t )) t = type_alias_get_aliasee_type( t ); 74 else return 0; 75 } 76} 77 78unsigned int get_attrv( const attr_list_t *list, enum attr_type attr_type ) 79{ 80 const attr_t *attr; 81 if (!list) return 0; 82 LIST_FOR_EACH_ENTRY( attr, list, const attr_t, entry ) 83 if (attr->type == attr_type) return attr->u.ival; 84 return 0; 85} 86 87void *get_attrp( const attr_list_t *list, enum attr_type attr_type ) 88{ 89 const attr_t *attr; 90 if (!list) return NULL; 91 LIST_FOR_EACH_ENTRY( attr, list, const attr_t, entry ) 92 if (attr->type == attr_type) return attr->u.pval; 93 return NULL; 94} 95 96void *get_aliaschain_attrp( const type_t *type, enum attr_type attr_type ) 97{ 98 for (;;) 99 { 100 if (is_attr( type->attrs, attr_type )) return get_attrp( type->attrs, attr_type ); 101 if (!type_is_alias( type )) return NULL; 102 type = type_alias_get_aliasee_type( type ); 103 } 104} 105 106struct allowed_attr 107{ 108 unsigned int dce_compatible : 1; 109 unsigned int acf : 1; 110 unsigned int multiple : 1; 111 112 unsigned int on_interface : 1; 113 unsigned int on_function : 1; 114 unsigned int on_arg : 1; 115 unsigned int on_type : 1; 116 unsigned int on_enum : 1; 117 unsigned int on_enum_member : 1; 118 unsigned int on_struct : 2; 119 unsigned int on_union : 1; 120 unsigned int on_field : 1; 121 unsigned int on_library : 1; 122 unsigned int on_dispinterface : 1; 123 unsigned int on_module : 1; 124 unsigned int on_coclass : 1; 125 unsigned int on_apicontract : 1; 126 unsigned int on_runtimeclass : 1; 127 const char *display_name; 128}; 129 130struct allowed_attr allowed_attr[] = 131{ 132 /* attr { D ACF M I Fn ARG T En Enm St Un Fi L DI M C AC R <display name> } */ 133 /* ATTR_ACTIVATABLE */ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "activatable" }, 134 /* ATTR_AGGREGATABLE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, "aggregatable" }, 135 /* ATTR_ALLOCATE */ { 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "allocate" }, 136 /* ATTR_ANNOTATION */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "annotation" }, 137 /* ATTR_APPOBJECT */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, "appobject" }, 138 /* ATTR_ASYNC */ { 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "async" }, 139 /* ATTR_ASYNCUUID */ { 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, "async_uuid" }, 140 /* ATTR_AUTO_HANDLE */ { 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "auto_handle" }, 141 /* ATTR_BINDABLE */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "bindable" }, 142 /* ATTR_BROADCAST */ { 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "broadcast" }, 143 /* ATTR_CALLAS */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "call_as" }, 144 /* ATTR_CALLCONV */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL }, 145 /* ATTR_CASE */ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "case" }, 146 /* ATTR_CODE */ { 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "code" }, 147 /* ATTR_COMMSTATUS */ { 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "comm_status" }, 148 /* ATTR_COMPOSABLE */ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "composable" }, 149 /* ATTR_CONTEXTHANDLE */ { 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "context_handle" }, 150 /* ATTR_CONTRACT */ { 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, "contract" }, 151 /* ATTR_CONTRACTVERSION */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, "contractversion" }, 152 /* ATTR_CONTROL */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, "control" }, 153 /* ATTR_CUSTOM */ { 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, "custom" }, 154 /* ATTR_DECODE */ { 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "decode" }, 155 /* ATTR_DEFAULT */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, "default" }, 156 /* ATTR_DEFAULT_OVERLOAD */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "default_overload" }, 157 /* ATTR_DEFAULTBIND */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "defaultbind" }, 158 /* ATTR_DEFAULTCOLLELEM */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "defaultcollelem" }, 159 /* ATTR_DEFAULTVALUE */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "defaultvalue" }, 160 /* ATTR_DEFAULTVTABLE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, "defaultvtable" }, 161 /* ATTR_DEPRECATED */ { 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "deprecated" }, 162 /* ATTR_DISABLECONSISTENCYCHECK */{ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "disable_consistency_check" }, 163 /* ATTR_DISPINTERFACE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, NULL }, 164 /* ATTR_DISPLAYBIND */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "displaybind" }, 165 /* ATTR_DLLNAME */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, "dllname" }, 166 /* ATTR_DUAL */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "dual" }, 167 /* ATTR_ENABLEALLOCATE */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "enable_allocate" }, 168 /* ATTR_ENCODE */ { 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "encode" }, 169 /* ATTR_ENDPOINT */ { 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "endpoint" }, 170 /* ATTR_ENTRY */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "entry" }, 171 /* ATTR_EVENTADD */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "eventadd" }, 172 /* ATTR_EVENTREMOVE */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "eventremove" }, 173 /* ATTR_EXCLUSIVETO */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "exclusive_to" }, 174 /* ATTR_EXPLICIT_HANDLE */ { 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "explicit_handle" }, 175 /* ATTR_FAULTSTATUS */ { 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "fault_status" }, 176 /* ATTR_FLAGS */ { 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "flags" }, 177 /* ATTR_FORCEALLOCATE */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "force_allocate" }, 178 /* ATTR_HANDLE */ { 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "handle" }, 179 /* ATTR_HELPCONTEXT */ { 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, "helpcontext" }, 180 /* ATTR_HELPFILE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, "helpfile" }, 181 /* ATTR_HELPSTRING */ { 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, "helpstring" }, 182 /* ATTR_HELPSTRINGCONTEXT */ { 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, "helpstringcontext" }, 183 /* ATTR_HELPSTRINGDLL */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, "helpstringdll" }, 184 /* ATTR_HIDDEN */ { 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, "hidden" }, 185 /* ATTR_ID */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, "id" }, 186 /* ATTR_IDEMPOTENT */ { 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "idempotent" }, 187 /* ATTR_IGNORE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "ignore" }, 188 /* ATTR_IIDIS */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "iid_is" }, 189 /* ATTR_IMMEDIATEBIND */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "immediatebind" }, 190 /* ATTR_IMPLICIT_HANDLE */ { 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "implicit_handle" }, 191 /* ATTR_IN */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "in" }, 192 /* ATTR_INPUTSYNC */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "inputsync" }, 193 /* ATTR_LENGTHIS */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "length_is" }, 194 /* ATTR_LIBLCID */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, "lcid" }, 195 /* ATTR_LICENSED */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, "licensed" }, 196 /* ATTR_LOCAL */ { 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "local" }, 197 /* ATTR_MARSHALING_BEHAVIOR */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "marshaling_behavior" }, 198 /* ATTR_MAYBE */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "maybe" }, 199 /* ATTR_MESSAGE */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "message" }, 200 /* ATTR_NOCODE */ { 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "nocode" }, 201 /* ATTR_NONBROWSABLE */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "nonbrowsable" }, 202 /* ATTR_NONCREATABLE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, "noncreatable" }, 203 /* ATTR_NONEXTENSIBLE */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "nonextensible" }, 204 /* ATTR_NOTIFY */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "notify" }, 205 /* ATTR_NOTIFYFLAG */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "notify_flag" }, 206 /* ATTR_OBJECT */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "object" }, 207 /* ATTR_ODL */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, "odl" }, 208 /* ATTR_OLEAUTOMATION */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "oleautomation" }, 209 /* ATTR_OPTIMIZE */ { 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "optimize" }, 210 /* ATTR_OPTIONAL */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "optional" }, 211 /* ATTR_OUT */ { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "out" }, 212 /* ATTR_OVERLOAD */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "overload" }, 213 /* ATTR_PARAMLCID */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "lcid" }, 214 /* ATTR_PARTIALIGNORE */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "partial_ignore" }, 215 /* ATTR_POINTERDEFAULT */ { 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "pointer_default" }, 216 /* ATTR_POINTERTYPE */ { 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "ref, unique or ptr" }, 217 /* ATTR_PROGID */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, "progid" }, 218 /* ATTR_PROPGET */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "propget" }, 219 /* ATTR_PROPPUT */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "propput" }, 220 /* ATTR_PROPPUTREF */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "propputref" }, 221 /* ATTR_PROTECTED */ { 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "protected" }, 222 /* ATTR_PROXY */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "proxy" }, 223 /* ATTR_PUBLIC */ { 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "public" }, 224 /* ATTR_RANGE */ { 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "range" }, 225 /* ATTR_READONLY */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "readonly" }, 226 /* ATTR_REPRESENTAS */ { 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "represent_as" }, 227 /* ATTR_REQUESTEDIT */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "requestedit" }, 228 /* ATTR_RESTRICTED */ { 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, "restricted" }, 229 /* ATTR_RETVAL */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "retval" }, 230 /* ATTR_SIZEIS */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "size_is" }, 231 /* ATTR_SOURCE */ { 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, "source" }, 232 /* ATTR_STATIC */ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "static" }, 233 /* ATTR_STRICTCONTEXTHANDLE */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "strict_context_handle" }, 234 /* ATTR_STRING */ { 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "string" }, 235 /* ATTR_SWITCHIS */ { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "switch_is" }, 236 /* ATTR_SWITCHTYPE */ { 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "switch_type" }, 237 /* ATTR_THREADING */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, "threading" }, 238 /* ATTR_TRANSMITAS */ { 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "transmit_as" }, 239 /* ATTR_UIDEFAULT */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "uidefault" }, 240 /* ATTR_USESGETLASTERROR */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "usesgetlasterror" }, 241 /* ATTR_USERMARSHAL */ { 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "user_marshal" }, 242 /* ATTR_UUID */ { 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, "uuid" }, 243 /* ATTR_V1ENUM */ { 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "v1_enum" }, 244 /* ATTR_VARARG */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "vararg" }, 245 /* ATTR_VERSION */ { 1, 0, 0, 1, 0, 0, 1, 1, 0, 2, 0, 0, 1, 0, 1, 1, 0, 1, "version" }, 246 /* ATTR_VIPROGID */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, "vi_progid" }, 247 /* ATTR_WIREMARSHAL */ { 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "wire_marshal" }, 248}; 249 250static const char *get_attr_display_name( enum attr_type attr_type ) 251{ 252 return allowed_attr[attr_type].display_name; 253} 254 255attr_list_t *append_attr( attr_list_t *list, attr_t *attr ) 256{ 257 attr_t *attr_existing; 258 if (!attr) return list; 259 if (!list) 260 { 261 list = xmalloc( sizeof(*list) ); 262 list_init( list ); 263 } 264 if (!allowed_attr[attr->type].multiple) 265 { 266 LIST_FOR_EACH_ENTRY( attr_existing, list, attr_t, entry ) 267 { 268 if (attr_existing->type != attr->type) continue; 269 warning_at( &attr->where, "duplicate attribute %s\n", get_attr_display_name( attr->type ) ); 270 /* use the last attribute, like MIDL does */ 271 list_remove( &attr_existing->entry ); 272 break; 273 } 274 } 275 list_add_tail( list, &attr->entry ); 276 return list; 277} 278 279attr_list_t *append_attr_list( attr_list_t *new_list, attr_list_t *old_list ) 280{ 281 struct list *entry; 282 283 if (!old_list) return new_list; 284 285 while ((entry = list_head( old_list ))) 286 { 287 attr_t *attr = LIST_ENTRY( entry, attr_t, entry ); 288 list_remove( entry ); 289 new_list = append_attr( new_list, attr ); 290 } 291 return new_list; 292} 293 294attr_list_t *append_attribs( attr_list_t *l1, attr_list_t *l2 ) 295{ 296 if (!l2) return l1; 297 if (!l1 || l1 == l2) return l2; 298 list_move_tail( l1, l2 ); 299 return l1; 300} 301 302attr_list_t *map_attrs( const attr_list_t *list, map_attrs_filter_t filter ) 303{ 304 attr_list_t *new_list; 305 const attr_t *attr; 306 attr_t *new_attr; 307 308 if (!list) return NULL; 309 310 new_list = xmalloc( sizeof(*list) ); 311 list_init( new_list ); 312 LIST_FOR_EACH_ENTRY( attr, list, const attr_t, entry ) 313 { 314 if (filter && !filter( new_list, attr )) continue; 315 new_attr = xmalloc( sizeof(*new_attr) ); 316 *new_attr = *attr; 317 list_add_tail( new_list, &new_attr->entry ); 318 } 319 return new_list; 320} 321 322attr_list_t *move_attr( attr_list_t *dst, attr_list_t *src, enum attr_type type ) 323{ 324 attr_t *attr; 325 if (!src) return dst; 326 LIST_FOR_EACH_ENTRY( attr, src, attr_t, entry ) 327 { 328 if (attr->type == type) 329 { 330 list_remove( &attr->entry ); 331 return append_attr( dst, attr ); 332 } 333 } 334 return dst; 335} 336 337attr_list_t *check_apicontract_attrs( const char *name, attr_list_t *attrs ) 338{ 339 const attr_t *attr; 340 if (!attrs) return NULL; 341 LIST_FOR_EACH_ENTRY( attr, attrs, const attr_t, entry ) 342 { 343 if (!allowed_attr[attr->type].on_apicontract) 344 error_at( &attr->where, "inapplicable attribute %s for apicontract %s\n", 345 allowed_attr[attr->type].display_name, name ); 346 } 347 return attrs; 348} 349 350attr_list_t *check_coclass_attrs( const char *name, attr_list_t *attrs ) 351{ 352 const attr_t *attr; 353 if (!attrs) return NULL; 354 LIST_FOR_EACH_ENTRY( attr, attrs, const attr_t, entry ) 355 { 356 if (!allowed_attr[attr->type].on_coclass) 357 error_at( &attr->where, "inapplicable attribute %s for coclass %s\n", 358 allowed_attr[attr->type].display_name, name ); 359 } 360 return attrs; 361} 362 363attr_list_t *check_dispiface_attrs( const char *name, attr_list_t *attrs ) 364{ 365 const attr_t *attr; 366 if (!attrs) return NULL; 367 LIST_FOR_EACH_ENTRY( attr, attrs, const attr_t, entry ) 368 { 369 if (!allowed_attr[attr->type].on_dispinterface) 370 error_at( &attr->where, "inapplicable attribute %s for dispinterface %s\n", 371 allowed_attr[attr->type].display_name, name ); 372 } 373 return attrs; 374} 375 376attr_list_t *check_enum_attrs( attr_list_t *attrs ) 377{ 378 const attr_t *attr; 379 if (!attrs) return NULL; 380 LIST_FOR_EACH_ENTRY( attr, attrs, const attr_t, entry ) 381 { 382 if (!allowed_attr[attr->type].on_enum) 383 error_at( &attr->where, "inapplicable attribute %s for enum\n", 384 allowed_attr[attr->type].display_name ); 385 } 386 return attrs; 387} 388 389attr_list_t *check_enum_member_attrs( attr_list_t *attrs ) 390{ 391 const attr_t *attr; 392 if (!attrs) return NULL; 393 LIST_FOR_EACH_ENTRY( attr, attrs, const attr_t, entry ) 394 { 395 if (!allowed_attr[attr->type].on_enum_member) 396 error_at( &attr->where, "inapplicable attribute %s for enum member\n", 397 allowed_attr[attr->type].display_name ); 398 } 399 return attrs; 400} 401 402attr_list_t *check_field_attrs( const char *name, attr_list_t *attrs ) 403{ 404 const attr_t *attr; 405 if (!attrs) return NULL; 406 LIST_FOR_EACH_ENTRY( attr, attrs, const attr_t, entry ) 407 { 408 if (!allowed_attr[attr->type].on_field) 409 error_at( &attr->where, "inapplicable attribute %s for field %s\n", 410 allowed_attr[attr->type].display_name, name ); 411 } 412 return attrs; 413} 414 415attr_list_t *check_function_attrs( const char *name, attr_list_t *attrs ) 416{ 417 const attr_t *attr; 418 if (!attrs) return NULL; 419 LIST_FOR_EACH_ENTRY( attr, attrs, const attr_t, entry ) 420 { 421 if (!allowed_attr[attr->type].on_function) 422 error_at( &attr->where, "inapplicable attribute %s for function %s\n", 423 allowed_attr[attr->type].display_name, name ); 424 } 425 return attrs; 426} 427 428attr_list_t *check_interface_attrs( const char *name, attr_list_t *attrs ) 429{ 430 const attr_t *attr; 431 if (!attrs) return NULL; 432 LIST_FOR_EACH_ENTRY( attr, attrs, const attr_t, entry ) 433 { 434 if (!allowed_attr[attr->type].on_interface) 435 error_at( &attr->where, "inapplicable attribute %s for interface %s\n", 436 allowed_attr[attr->type].display_name, name ); 437 if (attr->type == ATTR_IMPLICIT_HANDLE) 438 { 439 const var_t *var = attr->u.pval; 440 if (type_get_type( var->declspec.type ) == TYPE_BASIC && 441 type_basic_get_type( var->declspec.type ) == TYPE_BASIC_HANDLE) 442 continue; 443 if (is_aliaschain_attr( var->declspec.type, ATTR_HANDLE )) continue; 444 error_at( &attr->where, "attribute %s requires a handle type in interface %s\n", 445 allowed_attr[attr->type].display_name, name ); 446 } 447 } 448 return attrs; 449} 450 451attr_list_t *check_library_attrs( const char *name, attr_list_t *attrs ) 452{ 453 const attr_t *attr; 454 if (!attrs) return NULL; 455 LIST_FOR_EACH_ENTRY( attr, attrs, const attr_t, entry ) 456 { 457 if (!allowed_attr[attr->type].on_library) 458 error_at( &attr->where, "inapplicable attribute %s for library %s\n", 459 allowed_attr[attr->type].display_name, name ); 460 } 461 return attrs; 462} 463 464attr_list_t *check_module_attrs( const char *name, attr_list_t *attrs ) 465{ 466 const attr_t *attr; 467 if (!attrs) return NULL; 468 LIST_FOR_EACH_ENTRY( attr, attrs, const attr_t, entry ) 469 { 470 if (!allowed_attr[attr->type].on_module) 471 error_at( &attr->where, "inapplicable attribute %s for module %s\n", 472 allowed_attr[attr->type].display_name, name ); 473 } 474 return attrs; 475} 476 477attr_list_t *check_runtimeclass_attrs( const char *name, attr_list_t *attrs ) 478{ 479 const attr_t *attr; 480 if (!attrs) return NULL; 481 LIST_FOR_EACH_ENTRY( attr, attrs, const attr_t, entry ) 482 { 483 if (!allowed_attr[attr->type].on_runtimeclass) 484 error_at( &attr->where, "inapplicable attribute %s for runtimeclass %s\n", 485 allowed_attr[attr->type].display_name, name ); 486 } 487 return attrs; 488} 489 490attr_list_t *check_struct_attrs( attr_list_t *attrs ) 491{ 492 int mask = winrt_mode ? 3 : 1; 493 const attr_t *attr; 494 if (!attrs) return NULL; 495 LIST_FOR_EACH_ENTRY( attr, attrs, const attr_t, entry ) 496 { 497 if (!(allowed_attr[attr->type].on_struct & mask)) 498 error_at( &attr->where, "inapplicable attribute %s for struct\n", 499 allowed_attr[attr->type].display_name ); 500 } 501 return attrs; 502} 503 504attr_list_t *check_typedef_attrs( attr_list_t *attrs ) 505{ 506 const attr_t *attr; 507 if (!attrs) return NULL; 508 LIST_FOR_EACH_ENTRY( attr, attrs, const attr_t, entry ) 509 { 510 if (!allowed_attr[attr->type].on_type) 511 error_at( &attr->where, "inapplicable attribute %s for typedef\n", 512 allowed_attr[attr->type].display_name ); 513 } 514 return attrs; 515} 516 517attr_list_t *check_union_attrs( attr_list_t *attrs ) 518{ 519 const attr_t *attr; 520 if (!attrs) return NULL; 521 LIST_FOR_EACH_ENTRY( attr, attrs, const attr_t, entry ) 522 { 523 if (!allowed_attr[attr->type].on_union) 524 error_at( &attr->where, "inapplicable attribute %s for union\n", 525 allowed_attr[attr->type].display_name ); 526 } 527 return attrs; 528} 529 530void check_arg_attrs( const var_t *arg ) 531{ 532 const attr_t *attr; 533 if (!arg->attrs) return; 534 LIST_FOR_EACH_ENTRY( attr, arg->attrs, const attr_t, entry ) 535 { 536 if (!allowed_attr[attr->type].on_arg) 537 error_at( &attr->where, "inapplicable attribute %s for argument %s\n", 538 allowed_attr[attr->type].display_name, arg->name ); 539 } 540}