mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-03 01:01:44 +00:00
widl: Move attribute related functions to attribute.c.
This commit is contained in:
parent
f79ae4a95c
commit
f36fbb3788
|
@ -2,6 +2,7 @@ PROGRAMS = widl
|
|||
PARENTSRC = ../wrc
|
||||
|
||||
C_SRCS = \
|
||||
attribute.c \
|
||||
client.c \
|
||||
expr.c \
|
||||
hash.c \
|
||||
|
|
556
tools/widl/attribute.c
Normal file
556
tools/widl/attribute.c
Normal file
|
@ -0,0 +1,556 @@
|
|||
/*
|
||||
* Copyright 2002 Ove Kaaven
|
||||
* Copyright 2006-2008 Robert Shearman
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "widl.h"
|
||||
#include "typetree.h"
|
||||
|
||||
#include "parser.tab.h"
|
||||
|
||||
attr_t *make_attr( enum attr_type attr_type )
|
||||
{
|
||||
attr_t *a = xmalloc( sizeof(attr_t) );
|
||||
a->type = attr_type;
|
||||
a->u.ival = 0;
|
||||
return a;
|
||||
}
|
||||
|
||||
attr_t *make_attrv( enum attr_type attr_type, unsigned int val )
|
||||
{
|
||||
attr_t *a = xmalloc( sizeof(attr_t) );
|
||||
a->type = attr_type;
|
||||
a->u.ival = val;
|
||||
return a;
|
||||
}
|
||||
|
||||
attr_t *make_attrp( enum attr_type attr_type, void *val )
|
||||
{
|
||||
attr_t *a = xmalloc( sizeof(attr_t) );
|
||||
a->type = attr_type;
|
||||
a->u.pval = val;
|
||||
return a;
|
||||
}
|
||||
|
||||
attr_t *make_custom_attr( struct uuid *id, expr_t *pval )
|
||||
{
|
||||
attr_t *a = xmalloc( sizeof(attr_t) );
|
||||
attr_custdata_t *cstdata = xmalloc( sizeof(attr_custdata_t) );
|
||||
a->type = ATTR_CUSTOM;
|
||||
cstdata->id = *id;
|
||||
cstdata->pval = pval;
|
||||
a->u.pval = cstdata;
|
||||
return a;
|
||||
}
|
||||
|
||||
int is_attr( const attr_list_t *list, enum attr_type attr_type )
|
||||
{
|
||||
const attr_t *attr;
|
||||
if (!list) return 0;
|
||||
LIST_FOR_EACH_ENTRY( attr, list, const attr_t, entry )
|
||||
if (attr->type == attr_type) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int is_ptrchain_attr( const var_t *var, enum attr_type attr_type )
|
||||
{
|
||||
type_t *type = var->declspec.type;
|
||||
if (is_attr( var->attrs, attr_type )) return 1;
|
||||
for (;;)
|
||||
{
|
||||
if (is_attr( type->attrs, attr_type )) return 1;
|
||||
else if (type_is_alias( type )) type = type_alias_get_aliasee_type( type );
|
||||
else if (type_is_ptr( type )) type = type_pointer_get_ref_type( type );
|
||||
else return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int is_aliaschain_attr( const type_t *type, enum attr_type attr_type )
|
||||
{
|
||||
const type_t *t = type;
|
||||
for (;;)
|
||||
{
|
||||
if (is_attr( t->attrs, attr_type )) return 1;
|
||||
else if (type_is_alias( t )) t = type_alias_get_aliasee_type( t );
|
||||
else return 0;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int get_attrv( const attr_list_t *list, enum attr_type attr_type )
|
||||
{
|
||||
const attr_t *attr;
|
||||
if (!list) return 0;
|
||||
LIST_FOR_EACH_ENTRY( attr, list, const attr_t, entry )
|
||||
if (attr->type == attr_type) return attr->u.ival;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *get_attrp( const attr_list_t *list, enum attr_type attr_type )
|
||||
{
|
||||
const attr_t *attr;
|
||||
if (!list) return NULL;
|
||||
LIST_FOR_EACH_ENTRY( attr, list, const attr_t, entry )
|
||||
if (attr->type == attr_type) return attr->u.pval;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *get_aliaschain_attrp( const type_t *type, enum attr_type attr_type )
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
if (is_attr( type->attrs, attr_type )) return get_attrp( type->attrs, attr_type );
|
||||
if (!type_is_alias( type )) return NULL;
|
||||
type = type_alias_get_aliasee_type( type );
|
||||
}
|
||||
}
|
||||
|
||||
struct allowed_attr
|
||||
{
|
||||
unsigned int dce_compatible : 1;
|
||||
unsigned int acf : 1;
|
||||
unsigned int multiple : 1;
|
||||
|
||||
unsigned int on_interface : 1;
|
||||
unsigned int on_function : 1;
|
||||
unsigned int on_arg : 1;
|
||||
unsigned int on_type : 1;
|
||||
unsigned int on_enum : 1;
|
||||
unsigned int on_enum_member : 1;
|
||||
unsigned int on_struct : 2;
|
||||
unsigned int on_union : 1;
|
||||
unsigned int on_field : 1;
|
||||
unsigned int on_library : 1;
|
||||
unsigned int on_dispinterface : 1;
|
||||
unsigned int on_module : 1;
|
||||
unsigned int on_coclass : 1;
|
||||
unsigned int on_apicontract : 1;
|
||||
unsigned int on_runtimeclass : 1;
|
||||
const char *display_name;
|
||||
};
|
||||
|
||||
struct allowed_attr allowed_attr[] =
|
||||
{
|
||||
/* attr { D ACF M I Fn ARG T En Enm St Un Fi L DI M C AC R <display name> } */
|
||||
/* ATTR_ACTIVATABLE */ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "activatable" },
|
||||
/* ATTR_AGGREGATABLE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, "aggregatable" },
|
||||
/* ATTR_ALLOCATE */ { 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "allocate" },
|
||||
/* ATTR_ANNOTATION */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "annotation" },
|
||||
/* ATTR_APPOBJECT */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, "appobject" },
|
||||
/* ATTR_ASYNC */ { 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "async" },
|
||||
/* ATTR_ASYNCUUID */ { 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, "async_uuid" },
|
||||
/* ATTR_AUTO_HANDLE */ { 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "auto_handle" },
|
||||
/* ATTR_BINDABLE */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "bindable" },
|
||||
/* ATTR_BROADCAST */ { 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "broadcast" },
|
||||
/* ATTR_CALLAS */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "call_as" },
|
||||
/* ATTR_CALLCONV */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL },
|
||||
/* ATTR_CASE */ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "case" },
|
||||
/* ATTR_CODE */ { 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "code" },
|
||||
/* ATTR_COMMSTATUS */ { 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "comm_status" },
|
||||
/* ATTR_CONTEXTHANDLE */ { 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "context_handle" },
|
||||
/* ATTR_CONTRACT */ { 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, "contract" },
|
||||
/* ATTR_CONTRACTVERSION */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, "contractversion" },
|
||||
/* ATTR_CONTROL */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, "control" },
|
||||
/* ATTR_CUSTOM */ { 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, "custom" },
|
||||
/* ATTR_DECODE */ { 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "decode" },
|
||||
/* ATTR_DEFAULT */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, "default" },
|
||||
/* ATTR_DEFAULTBIND */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "defaultbind" },
|
||||
/* ATTR_DEFAULTCOLLELEM */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "defaultcollelem" },
|
||||
/* ATTR_DEFAULTVALUE */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "defaultvalue" },
|
||||
/* ATTR_DEFAULTVTABLE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, "defaultvtable" },
|
||||
/* ATTR_DISABLECONSISTENCYCHECK */{ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "disable_consistency_check" },
|
||||
/* ATTR_DISPINTERFACE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, NULL },
|
||||
/* ATTR_DISPLAYBIND */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "displaybind" },
|
||||
/* ATTR_DLLNAME */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, "dllname" },
|
||||
/* ATTR_DUAL */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "dual" },
|
||||
/* ATTR_ENABLEALLOCATE */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "enable_allocate" },
|
||||
/* ATTR_ENCODE */ { 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "encode" },
|
||||
/* ATTR_ENDPOINT */ { 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "endpoint" },
|
||||
/* ATTR_ENTRY */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "entry" },
|
||||
/* ATTR_EVENTADD */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "eventadd" },
|
||||
/* ATTR_EVENTREMOVE */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "eventremove" },
|
||||
/* ATTR_EXCLUSIVETO */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "exclusive_to" },
|
||||
/* ATTR_EXPLICIT_HANDLE */ { 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "explicit_handle" },
|
||||
/* ATTR_FAULTSTATUS */ { 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "fault_status" },
|
||||
/* ATTR_FLAGS */ { 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "flags" },
|
||||
/* ATTR_FORCEALLOCATE */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "force_allocate" },
|
||||
/* ATTR_HANDLE */ { 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "handle" },
|
||||
/* ATTR_HELPCONTEXT */ { 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, "helpcontext" },
|
||||
/* ATTR_HELPFILE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, "helpfile" },
|
||||
/* ATTR_HELPSTRING */ { 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, "helpstring" },
|
||||
/* ATTR_HELPSTRINGCONTEXT */ { 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, "helpstringcontext" },
|
||||
/* ATTR_HELPSTRINGDLL */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, "helpstringdll" },
|
||||
/* ATTR_HIDDEN */ { 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, "hidden" },
|
||||
/* ATTR_ID */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, "id" },
|
||||
/* ATTR_IDEMPOTENT */ { 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "idempotent" },
|
||||
/* ATTR_IGNORE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "ignore" },
|
||||
/* ATTR_IIDIS */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "iid_is" },
|
||||
/* ATTR_IMMEDIATEBIND */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "immediatebind" },
|
||||
/* ATTR_IMPLICIT_HANDLE */ { 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "implicit_handle" },
|
||||
/* ATTR_IN */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "in" },
|
||||
/* ATTR_INPUTSYNC */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "inputsync" },
|
||||
/* ATTR_LENGTHIS */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "length_is" },
|
||||
/* ATTR_LIBLCID */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, "lcid" },
|
||||
/* ATTR_LICENSED */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, "licensed" },
|
||||
/* ATTR_LOCAL */ { 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "local" },
|
||||
/* ATTR_MARSHALING_BEHAVIOR */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "marshaling_behavior" },
|
||||
/* ATTR_MAYBE */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "maybe" },
|
||||
/* ATTR_MESSAGE */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "message" },
|
||||
/* ATTR_NOCODE */ { 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "nocode" },
|
||||
/* ATTR_NONBROWSABLE */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "nonbrowsable" },
|
||||
/* ATTR_NONCREATABLE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, "noncreatable" },
|
||||
/* ATTR_NONEXTENSIBLE */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "nonextensible" },
|
||||
/* ATTR_NOTIFY */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "notify" },
|
||||
/* ATTR_NOTIFYFLAG */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "notify_flag" },
|
||||
/* ATTR_OBJECT */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "object" },
|
||||
/* ATTR_ODL */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, "odl" },
|
||||
/* ATTR_OLEAUTOMATION */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "oleautomation" },
|
||||
/* ATTR_OPTIMIZE */ { 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "optimize" },
|
||||
/* ATTR_OPTIONAL */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "optional" },
|
||||
/* ATTR_OUT */ { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "out" },
|
||||
/* ATTR_OVERLOAD */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "overload" },
|
||||
/* ATTR_PARAMLCID */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "lcid" },
|
||||
/* ATTR_PARTIALIGNORE */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "partial_ignore" },
|
||||
/* ATTR_POINTERDEFAULT */ { 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "pointer_default" },
|
||||
/* ATTR_POINTERTYPE */ { 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "ref, unique or ptr" },
|
||||
/* ATTR_PROGID */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, "progid" },
|
||||
/* ATTR_PROPGET */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "propget" },
|
||||
/* ATTR_PROPPUT */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "propput" },
|
||||
/* ATTR_PROPPUTREF */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "propputref" },
|
||||
/* ATTR_PROXY */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "proxy" },
|
||||
/* ATTR_PUBLIC */ { 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "public" },
|
||||
/* ATTR_RANGE */ { 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "range" },
|
||||
/* ATTR_READONLY */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "readonly" },
|
||||
/* ATTR_REPRESENTAS */ { 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "represent_as" },
|
||||
/* ATTR_REQUESTEDIT */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "requestedit" },
|
||||
/* ATTR_RESTRICTED */ { 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, "restricted" },
|
||||
/* ATTR_RETVAL */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "retval" },
|
||||
/* ATTR_SIZEIS */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "size_is" },
|
||||
/* ATTR_SOURCE */ { 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, "source" },
|
||||
/* ATTR_STATIC */ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "static" },
|
||||
/* ATTR_STRICTCONTEXTHANDLE */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "strict_context_handle" },
|
||||
/* ATTR_STRING */ { 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "string" },
|
||||
/* ATTR_SWITCHIS */ { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "switch_is" },
|
||||
/* ATTR_SWITCHTYPE */ { 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "switch_type" },
|
||||
/* ATTR_THREADING */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, "threading" },
|
||||
/* ATTR_TRANSMITAS */ { 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "transmit_as" },
|
||||
/* ATTR_UIDEFAULT */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "uidefault" },
|
||||
/* ATTR_USESGETLASTERROR */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "usesgetlasterror" },
|
||||
/* ATTR_USERMARSHAL */ { 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "user_marshal" },
|
||||
/* ATTR_UUID */ { 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, "uuid" },
|
||||
/* ATTR_V1ENUM */ { 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "v1_enum" },
|
||||
/* ATTR_VARARG */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "vararg" },
|
||||
/* ATTR_VERSION */ { 1, 0, 0, 1, 0, 0, 1, 1, 0, 2, 0, 0, 1, 0, 1, 1, 0, 1, "version" },
|
||||
/* ATTR_VIPROGID */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, "vi_progid" },
|
||||
/* ATTR_WIREMARSHAL */ { 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "wire_marshal" },
|
||||
};
|
||||
|
||||
static const char *get_attr_display_name( enum attr_type attr_type )
|
||||
{
|
||||
return allowed_attr[attr_type].display_name;
|
||||
}
|
||||
|
||||
attr_list_t *append_attr( attr_list_t *list, attr_t *attr )
|
||||
{
|
||||
attr_t *attr_existing;
|
||||
if (!attr) return list;
|
||||
if (!list)
|
||||
{
|
||||
list = xmalloc( sizeof(*list) );
|
||||
list_init( list );
|
||||
}
|
||||
if (!allowed_attr[attr->type].multiple)
|
||||
{
|
||||
LIST_FOR_EACH_ENTRY( attr_existing, list, attr_t, entry )
|
||||
if (attr_existing->type == attr->type)
|
||||
{
|
||||
char buffer[1024];
|
||||
snprintf( buffer, sizeof(buffer), "duplicate attribute %s\n",
|
||||
get_attr_display_name( attr->type ) );
|
||||
parser_warning( NULL, buffer );
|
||||
/* use the last attribute, like MIDL does */
|
||||
list_remove( &attr_existing->entry );
|
||||
break;
|
||||
}
|
||||
}
|
||||
list_add_tail( list, &attr->entry );
|
||||
return list;
|
||||
}
|
||||
|
||||
attr_list_t *append_attr_list( attr_list_t *new_list, attr_list_t *old_list )
|
||||
{
|
||||
struct list *entry;
|
||||
|
||||
if (!old_list) return new_list;
|
||||
|
||||
while ((entry = list_head( old_list )))
|
||||
{
|
||||
attr_t *attr = LIST_ENTRY( entry, attr_t, entry );
|
||||
list_remove( entry );
|
||||
new_list = append_attr( new_list, attr );
|
||||
}
|
||||
return new_list;
|
||||
}
|
||||
|
||||
attr_list_t *append_attribs( attr_list_t *l1, attr_list_t *l2 )
|
||||
{
|
||||
if (!l2) return l1;
|
||||
if (!l1 || l1 == l2) return l2;
|
||||
list_move_tail( l1, l2 );
|
||||
return l1;
|
||||
}
|
||||
|
||||
attr_list_t *map_attrs( const attr_list_t *list, map_attrs_filter_t filter )
|
||||
{
|
||||
attr_list_t *new_list;
|
||||
const attr_t *attr;
|
||||
attr_t *new_attr;
|
||||
|
||||
if (!list) return NULL;
|
||||
|
||||
new_list = xmalloc( sizeof(*list) );
|
||||
list_init( new_list );
|
||||
LIST_FOR_EACH_ENTRY( attr, list, const attr_t, entry )
|
||||
{
|
||||
if (filter && !filter( new_list, attr )) continue;
|
||||
new_attr = xmalloc( sizeof(*new_attr) );
|
||||
*new_attr = *attr;
|
||||
list_add_tail( new_list, &new_attr->entry );
|
||||
}
|
||||
return new_list;
|
||||
}
|
||||
|
||||
attr_list_t *move_attr( attr_list_t *dst, attr_list_t *src, enum attr_type type )
|
||||
{
|
||||
attr_t *attr;
|
||||
if (!src) return dst;
|
||||
LIST_FOR_EACH_ENTRY( attr, src, attr_t, entry )
|
||||
{
|
||||
if (attr->type == type)
|
||||
{
|
||||
list_remove( &attr->entry );
|
||||
return append_attr( dst, attr );
|
||||
}
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
|
||||
attr_list_t *check_apicontract_attrs( const char *name, attr_list_t *attrs )
|
||||
{
|
||||
const attr_t *attr;
|
||||
if (!attrs) return NULL;
|
||||
LIST_FOR_EACH_ENTRY( attr, attrs, const attr_t, entry )
|
||||
{
|
||||
if (!allowed_attr[attr->type].on_apicontract)
|
||||
error_loc( "inapplicable attribute %s for apicontract %s\n",
|
||||
allowed_attr[attr->type].display_name, name );
|
||||
}
|
||||
return attrs;
|
||||
}
|
||||
|
||||
attr_list_t *check_coclass_attrs( const char *name, attr_list_t *attrs )
|
||||
{
|
||||
const attr_t *attr;
|
||||
if (!attrs) return NULL;
|
||||
LIST_FOR_EACH_ENTRY( attr, attrs, const attr_t, entry )
|
||||
{
|
||||
if (!allowed_attr[attr->type].on_coclass)
|
||||
error_loc( "inapplicable attribute %s for coclass %s\n",
|
||||
allowed_attr[attr->type].display_name, name );
|
||||
}
|
||||
return attrs;
|
||||
}
|
||||
|
||||
attr_list_t *check_dispiface_attrs( const char *name, attr_list_t *attrs )
|
||||
{
|
||||
const attr_t *attr;
|
||||
if (!attrs) return NULL;
|
||||
LIST_FOR_EACH_ENTRY( attr, attrs, const attr_t, entry )
|
||||
{
|
||||
if (!allowed_attr[attr->type].on_dispinterface)
|
||||
error_loc( "inapplicable attribute %s for dispinterface %s\n",
|
||||
allowed_attr[attr->type].display_name, name );
|
||||
}
|
||||
return attrs;
|
||||
}
|
||||
|
||||
attr_list_t *check_enum_attrs( attr_list_t *attrs )
|
||||
{
|
||||
const attr_t *attr;
|
||||
if (!attrs) return NULL;
|
||||
LIST_FOR_EACH_ENTRY( attr, attrs, const attr_t, entry )
|
||||
{
|
||||
if (!allowed_attr[attr->type].on_enum)
|
||||
error_loc( "inapplicable attribute %s for enum\n",
|
||||
allowed_attr[attr->type].display_name );
|
||||
}
|
||||
return attrs;
|
||||
}
|
||||
|
||||
attr_list_t *check_enum_member_attrs( attr_list_t *attrs )
|
||||
{
|
||||
const attr_t *attr;
|
||||
if (!attrs) return NULL;
|
||||
LIST_FOR_EACH_ENTRY( attr, attrs, const attr_t, entry )
|
||||
{
|
||||
if (!allowed_attr[attr->type].on_enum_member)
|
||||
error_loc( "inapplicable attribute %s for enum member\n",
|
||||
allowed_attr[attr->type].display_name );
|
||||
}
|
||||
return attrs;
|
||||
}
|
||||
|
||||
attr_list_t *check_field_attrs( const char *name, attr_list_t *attrs )
|
||||
{
|
||||
const attr_t *attr;
|
||||
if (!attrs) return NULL;
|
||||
LIST_FOR_EACH_ENTRY( attr, attrs, const attr_t, entry )
|
||||
{
|
||||
if (!allowed_attr[attr->type].on_field)
|
||||
error_loc( "inapplicable attribute %s for field %s\n",
|
||||
allowed_attr[attr->type].display_name, name );
|
||||
}
|
||||
return attrs;
|
||||
}
|
||||
|
||||
attr_list_t *check_function_attrs( const char *name, attr_list_t *attrs )
|
||||
{
|
||||
const attr_t *attr;
|
||||
if (!attrs) return NULL;
|
||||
LIST_FOR_EACH_ENTRY( attr, attrs, const attr_t, entry )
|
||||
{
|
||||
if (!allowed_attr[attr->type].on_function)
|
||||
error_loc( "inapplicable attribute %s for function %s\n",
|
||||
allowed_attr[attr->type].display_name, name );
|
||||
}
|
||||
return attrs;
|
||||
}
|
||||
|
||||
attr_list_t *check_interface_attrs( const char *name, attr_list_t *attrs )
|
||||
{
|
||||
const attr_t *attr;
|
||||
if (!attrs) return NULL;
|
||||
LIST_FOR_EACH_ENTRY( attr, attrs, const attr_t, entry )
|
||||
{
|
||||
if (!allowed_attr[attr->type].on_interface)
|
||||
error_loc( "inapplicable attribute %s for interface %s\n",
|
||||
allowed_attr[attr->type].display_name, name );
|
||||
if (attr->type == ATTR_IMPLICIT_HANDLE)
|
||||
{
|
||||
const var_t *var = attr->u.pval;
|
||||
if (type_get_type( var->declspec.type ) == TYPE_BASIC &&
|
||||
type_basic_get_type( var->declspec.type ) == TYPE_BASIC_HANDLE)
|
||||
continue;
|
||||
if (is_aliaschain_attr( var->declspec.type, ATTR_HANDLE )) continue;
|
||||
error_loc( "attribute %s requires a handle type in interface %s\n",
|
||||
allowed_attr[attr->type].display_name, name );
|
||||
}
|
||||
}
|
||||
return attrs;
|
||||
}
|
||||
|
||||
attr_list_t *check_library_attrs( const char *name, attr_list_t *attrs )
|
||||
{
|
||||
const attr_t *attr;
|
||||
if (!attrs) return NULL;
|
||||
LIST_FOR_EACH_ENTRY( attr, attrs, const attr_t, entry )
|
||||
{
|
||||
if (!allowed_attr[attr->type].on_library)
|
||||
error_loc( "inapplicable attribute %s for library %s\n",
|
||||
allowed_attr[attr->type].display_name, name );
|
||||
}
|
||||
return attrs;
|
||||
}
|
||||
|
||||
attr_list_t *check_module_attrs( const char *name, attr_list_t *attrs )
|
||||
{
|
||||
const attr_t *attr;
|
||||
if (!attrs) return NULL;
|
||||
LIST_FOR_EACH_ENTRY( attr, attrs, const attr_t, entry )
|
||||
{
|
||||
if (!allowed_attr[attr->type].on_module)
|
||||
error_loc( "inapplicable attribute %s for module %s\n",
|
||||
allowed_attr[attr->type].display_name, name );
|
||||
}
|
||||
return attrs;
|
||||
}
|
||||
|
||||
attr_list_t *check_runtimeclass_attrs( const char *name, attr_list_t *attrs )
|
||||
{
|
||||
const attr_t *attr;
|
||||
if (!attrs) return NULL;
|
||||
LIST_FOR_EACH_ENTRY( attr, attrs, const attr_t, entry )
|
||||
{
|
||||
if (!allowed_attr[attr->type].on_runtimeclass)
|
||||
error_loc( "inapplicable attribute %s for runtimeclass %s\n",
|
||||
allowed_attr[attr->type].display_name, name );
|
||||
}
|
||||
return attrs;
|
||||
}
|
||||
|
||||
attr_list_t *check_struct_attrs( attr_list_t *attrs )
|
||||
{
|
||||
int mask = winrt_mode ? 3 : 1;
|
||||
const attr_t *attr;
|
||||
if (!attrs) return NULL;
|
||||
LIST_FOR_EACH_ENTRY( attr, attrs, const attr_t, entry )
|
||||
{
|
||||
if (!(allowed_attr[attr->type].on_struct & mask))
|
||||
error_loc( "inapplicable attribute %s for struct\n",
|
||||
allowed_attr[attr->type].display_name );
|
||||
}
|
||||
return attrs;
|
||||
}
|
||||
|
||||
attr_list_t *check_typedef_attrs( attr_list_t *attrs )
|
||||
{
|
||||
const attr_t *attr;
|
||||
if (!attrs) return NULL;
|
||||
LIST_FOR_EACH_ENTRY( attr, attrs, const attr_t, entry )
|
||||
{
|
||||
if (!allowed_attr[attr->type].on_type)
|
||||
error_loc( "inapplicable attribute %s for typedef\n",
|
||||
allowed_attr[attr->type].display_name );
|
||||
}
|
||||
return attrs;
|
||||
}
|
||||
|
||||
attr_list_t *check_union_attrs( attr_list_t *attrs )
|
||||
{
|
||||
const attr_t *attr;
|
||||
if (!attrs) return NULL;
|
||||
LIST_FOR_EACH_ENTRY( attr, attrs, const attr_t, entry )
|
||||
{
|
||||
if (!allowed_attr[attr->type].on_union)
|
||||
error_loc( "inapplicable attribute %s for union\n",
|
||||
allowed_attr[attr->type].display_name );
|
||||
}
|
||||
return attrs;
|
||||
}
|
||||
|
||||
void check_arg_attrs( const var_t *arg )
|
||||
{
|
||||
const attr_t *attr;
|
||||
if (!arg->attrs) return;
|
||||
LIST_FOR_EACH_ENTRY( attr, arg->attrs, const attr_t, entry )
|
||||
{
|
||||
if (!allowed_attr[attr->type].on_arg)
|
||||
error_loc( "inapplicable attribute %s for argument %s\n",
|
||||
allowed_attr[attr->type].display_name, arg->name );
|
||||
}
|
||||
}
|
|
@ -65,63 +65,6 @@ static void write_line(FILE *f, int delta, const char *fmt, ...)
|
|||
fprintf(f, "\n");
|
||||
}
|
||||
|
||||
int is_ptrchain_attr(const var_t *var, enum attr_type t)
|
||||
{
|
||||
if (is_attr(var->attrs, t))
|
||||
return 1;
|
||||
else
|
||||
{
|
||||
type_t *type = var->declspec.type;
|
||||
for (;;)
|
||||
{
|
||||
if (is_attr(type->attrs, t))
|
||||
return 1;
|
||||
else if (type_is_alias(type))
|
||||
type = type_alias_get_aliasee_type(type);
|
||||
else if (is_ptr(type))
|
||||
type = type_pointer_get_ref_type(type);
|
||||
else return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int is_aliaschain_attr(const type_t *type, enum attr_type attr)
|
||||
{
|
||||
const type_t *t = type;
|
||||
for (;;)
|
||||
{
|
||||
if (is_attr(t->attrs, attr))
|
||||
return 1;
|
||||
else if (type_is_alias(t))
|
||||
t = type_alias_get_aliasee_type(t);
|
||||
else return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int is_attr(const attr_list_t *list, enum attr_type t)
|
||||
{
|
||||
const attr_t *attr;
|
||||
if (list) LIST_FOR_EACH_ENTRY( attr, list, const attr_t, entry )
|
||||
if (attr->type == t) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *get_attrp(const attr_list_t *list, enum attr_type t)
|
||||
{
|
||||
const attr_t *attr;
|
||||
if (list) LIST_FOR_EACH_ENTRY( attr, list, const attr_t, entry )
|
||||
if (attr->type == t) return attr->u.pval;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
unsigned int get_attrv(const attr_list_t *list, enum attr_type t)
|
||||
{
|
||||
const attr_t *attr;
|
||||
if (list) LIST_FOR_EACH_ENTRY( attr, list, const attr_t, entry )
|
||||
if (attr->type == t) return attr->u.ival;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char *format_parameterized_type_args(const type_t *type, const char *prefix, const char *suffix)
|
||||
{
|
||||
typeref_list_t *params;
|
||||
|
|
|
@ -23,10 +23,6 @@
|
|||
|
||||
#include "typetree.h"
|
||||
|
||||
extern int is_ptrchain_attr(const var_t *var, enum attr_type t);
|
||||
extern int is_aliaschain_attr(const type_t *var, 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_type_left(FILE *h, const decl_spec_t *ds, enum name_type name_type, int declonly, int write_callconv);
|
||||
extern void write_type_right(FILE *h, type_t *t, int is_field);
|
||||
|
|
|
@ -45,12 +45,8 @@ struct _import_t
|
|||
};
|
||||
|
||||
static str_list_t *append_str(str_list_t *list, char *str);
|
||||
static attr_list_t *append_attr_list(attr_list_t *new_list, attr_list_t *old_list);
|
||||
static decl_spec_t *make_decl_spec(type_t *type, decl_spec_t *left, decl_spec_t *right,
|
||||
enum storage_class stgclass, enum type_qualifier qual, enum function_specifier func_specifier);
|
||||
static attr_t *make_attr(enum attr_type type);
|
||||
static attr_t *make_attrv(enum attr_type type, unsigned int val);
|
||||
static attr_t *make_custom_attr(struct uuid *id, expr_t *pval);
|
||||
static expr_list_t *append_expr(expr_list_t *list, expr_t *expr);
|
||||
static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, declarator_t *decl, int top);
|
||||
static var_list_t *set_var_types(attr_list_t *attrs, decl_spec_t *decl_spec, declarator_list_t *decls);
|
||||
|
@ -76,18 +72,8 @@ static void push_parameters_namespace(const char *name);
|
|||
static void pop_parameters_namespace(const char *name);
|
||||
|
||||
static statement_list_t *append_parameterized_type_stmts(statement_list_t *stmts);
|
||||
static void check_arg_attrs(const var_t *arg);
|
||||
static void check_statements(const statement_list_t *stmts, int is_inside_library);
|
||||
static void check_all_user_types(const statement_list_t *stmts);
|
||||
static attr_list_t *check_function_attrs(const char *name, attr_list_t *attrs);
|
||||
static attr_list_t *check_typedef_attrs(attr_list_t *attrs);
|
||||
static attr_list_t *check_enum_attrs(attr_list_t *attrs);
|
||||
static attr_list_t *check_enum_member_attrs(attr_list_t *attrs);
|
||||
static attr_list_t *check_struct_attrs(attr_list_t *attrs);
|
||||
static attr_list_t *check_union_attrs(attr_list_t *attrs);
|
||||
static attr_list_t *check_field_attrs(const char *name, attr_list_t *attrs);
|
||||
static attr_list_t *check_library_attrs(const char *name, attr_list_t *attrs);
|
||||
const char *get_attr_display_name(enum attr_type type);
|
||||
static void add_explicit_handle_if_necessary(const type_t *iface, var_t *func);
|
||||
|
||||
static void check_async_uuid(type_t *iface);
|
||||
|
@ -107,7 +93,6 @@ static statement_t *make_statement_parameterized_type(type_t *type, typeref_list
|
|||
static statement_t *make_statement_delegate(type_t *ret, var_list_t *args);
|
||||
static statement_list_t *append_statement(statement_list_t *list, statement_t *stmt);
|
||||
static statement_list_t *append_statements(statement_list_t *, statement_list_t *);
|
||||
static attr_list_t *append_attribs(attr_list_t *, attr_list_t *);
|
||||
|
||||
static struct namespace global_namespace = {
|
||||
NULL, NULL, LIST_INIT(global_namespace.entry), LIST_INIT(global_namespace.children)
|
||||
|
@ -1450,55 +1435,6 @@ static str_list_t *append_str(str_list_t *list, char *str)
|
|||
return list;
|
||||
}
|
||||
|
||||
static attr_list_t *move_attr(attr_list_t *dst, attr_list_t *src, enum attr_type type)
|
||||
{
|
||||
attr_t *attr;
|
||||
if (!src) return dst;
|
||||
LIST_FOR_EACH_ENTRY(attr, src, attr_t, entry)
|
||||
if (attr->type == type)
|
||||
{
|
||||
list_remove(&attr->entry);
|
||||
return append_attr(dst, attr);
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
|
||||
static attr_list_t *append_attr_list(attr_list_t *new_list, attr_list_t *old_list)
|
||||
{
|
||||
struct list *entry;
|
||||
|
||||
if (!old_list) return new_list;
|
||||
|
||||
while ((entry = list_head(old_list)))
|
||||
{
|
||||
attr_t *attr = LIST_ENTRY(entry, attr_t, entry);
|
||||
list_remove(entry);
|
||||
new_list = append_attr(new_list, attr);
|
||||
}
|
||||
return new_list;
|
||||
}
|
||||
|
||||
typedef int (*map_attrs_filter_t)(attr_list_t*,const attr_t*);
|
||||
|
||||
static attr_list_t *map_attrs(const attr_list_t *list, map_attrs_filter_t filter)
|
||||
{
|
||||
attr_list_t *new_list;
|
||||
const attr_t *attr;
|
||||
attr_t *new_attr;
|
||||
|
||||
if (!list) return NULL;
|
||||
|
||||
new_list = xmalloc( sizeof(*list) );
|
||||
list_init( new_list );
|
||||
LIST_FOR_EACH_ENTRY(attr, list, const attr_t, entry)
|
||||
{
|
||||
if (filter && !filter(new_list, attr)) continue;
|
||||
new_attr = xmalloc(sizeof(*new_attr));
|
||||
*new_attr = *attr;
|
||||
list_add_tail(new_list, &new_attr->entry);
|
||||
}
|
||||
return new_list;
|
||||
}
|
||||
|
||||
static decl_spec_t *make_decl_spec(type_t *type, decl_spec_t *left, decl_spec_t *right,
|
||||
enum storage_class stgclass, enum type_qualifier qual, enum function_specifier func_specifier)
|
||||
|
@ -1546,41 +1482,6 @@ static decl_spec_t *make_decl_spec(type_t *type, decl_spec_t *left, decl_spec_t
|
|||
return declspec;
|
||||
}
|
||||
|
||||
static attr_t *make_attr(enum attr_type type)
|
||||
{
|
||||
attr_t *a = xmalloc(sizeof(attr_t));
|
||||
a->type = type;
|
||||
a->u.ival = 0;
|
||||
return a;
|
||||
}
|
||||
|
||||
static attr_t *make_attrv(enum attr_type type, unsigned int val)
|
||||
{
|
||||
attr_t *a = xmalloc(sizeof(attr_t));
|
||||
a->type = type;
|
||||
a->u.ival = val;
|
||||
return a;
|
||||
}
|
||||
|
||||
attr_t *make_attrp(enum attr_type type, void *val)
|
||||
{
|
||||
attr_t *a = xmalloc(sizeof(attr_t));
|
||||
a->type = type;
|
||||
a->u.pval = val;
|
||||
return a;
|
||||
}
|
||||
|
||||
static attr_t *make_custom_attr(struct uuid *id, expr_t *pval)
|
||||
{
|
||||
attr_t *a = xmalloc(sizeof(attr_t));
|
||||
attr_custdata_t *cstdata = xmalloc(sizeof(attr_custdata_t));
|
||||
a->type = ATTR_CUSTOM;
|
||||
cstdata->id = *id;
|
||||
cstdata->pval = pval;
|
||||
a->u.pval = cstdata;
|
||||
return a;
|
||||
}
|
||||
|
||||
static expr_list_t *append_expr(expr_list_t *list, expr_t *expr)
|
||||
{
|
||||
if (!expr) return list;
|
||||
|
@ -2340,380 +2241,6 @@ char *gen_name(void)
|
|||
return strmake("__WIDL_%s_generated_name_%08lX", file_id, n++);
|
||||
}
|
||||
|
||||
struct allowed_attr
|
||||
{
|
||||
unsigned int dce_compatible : 1;
|
||||
unsigned int acf : 1;
|
||||
unsigned int multiple : 1;
|
||||
|
||||
unsigned int on_interface : 1;
|
||||
unsigned int on_function : 1;
|
||||
unsigned int on_arg : 1;
|
||||
unsigned int on_type : 1;
|
||||
unsigned int on_enum : 1;
|
||||
unsigned int on_enum_member : 1;
|
||||
unsigned int on_struct : 2;
|
||||
unsigned int on_union : 1;
|
||||
unsigned int on_field : 1;
|
||||
unsigned int on_library : 1;
|
||||
unsigned int on_dispinterface : 1;
|
||||
unsigned int on_module : 1;
|
||||
unsigned int on_coclass : 1;
|
||||
unsigned int on_apicontract : 1;
|
||||
unsigned int on_runtimeclass : 1;
|
||||
const char *display_name;
|
||||
};
|
||||
|
||||
struct allowed_attr allowed_attr[] =
|
||||
{
|
||||
/* attr { D ACF M I Fn ARG T En Enm St Un Fi L DI M C AC R <display name> } */
|
||||
/* ATTR_ACTIVATABLE */ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "activatable" },
|
||||
/* ATTR_AGGREGATABLE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, "aggregatable" },
|
||||
/* ATTR_ALLOCATE */ { 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "allocate" },
|
||||
/* ATTR_ANNOTATION */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "annotation" },
|
||||
/* ATTR_APPOBJECT */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, "appobject" },
|
||||
/* ATTR_ASYNC */ { 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "async" },
|
||||
/* ATTR_ASYNCUUID */ { 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, "async_uuid" },
|
||||
/* ATTR_AUTO_HANDLE */ { 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "auto_handle" },
|
||||
/* ATTR_BINDABLE */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "bindable" },
|
||||
/* ATTR_BROADCAST */ { 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "broadcast" },
|
||||
/* ATTR_CALLAS */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "call_as" },
|
||||
/* ATTR_CALLCONV */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL },
|
||||
/* ATTR_CASE */ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "case" },
|
||||
/* ATTR_CODE */ { 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "code" },
|
||||
/* ATTR_COMMSTATUS */ { 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "comm_status" },
|
||||
/* ATTR_CONTEXTHANDLE */ { 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "context_handle" },
|
||||
/* ATTR_CONTRACT */ { 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, "contract" },
|
||||
/* ATTR_CONTRACTVERSION */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, "contractversion" },
|
||||
/* ATTR_CONTROL */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, "control" },
|
||||
/* ATTR_CUSTOM */ { 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, "custom" },
|
||||
/* ATTR_DECODE */ { 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "decode" },
|
||||
/* ATTR_DEFAULT */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, "default" },
|
||||
/* ATTR_DEFAULTBIND */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "defaultbind" },
|
||||
/* ATTR_DEFAULTCOLLELEM */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "defaultcollelem" },
|
||||
/* ATTR_DEFAULTVALUE */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "defaultvalue" },
|
||||
/* ATTR_DEFAULTVTABLE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, "defaultvtable" },
|
||||
/* ATTR_DISABLECONSISTENCYCHECK */{ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "disable_consistency_check" },
|
||||
/* ATTR_DISPINTERFACE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, NULL },
|
||||
/* ATTR_DISPLAYBIND */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "displaybind" },
|
||||
/* ATTR_DLLNAME */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, "dllname" },
|
||||
/* ATTR_DUAL */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "dual" },
|
||||
/* ATTR_ENABLEALLOCATE */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "enable_allocate" },
|
||||
/* ATTR_ENCODE */ { 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "encode" },
|
||||
/* ATTR_ENDPOINT */ { 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "endpoint" },
|
||||
/* ATTR_ENTRY */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "entry" },
|
||||
/* ATTR_EVENTADD */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "eventadd" },
|
||||
/* ATTR_EVENTREMOVE */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "eventremove" },
|
||||
/* ATTR_EXCLUSIVETO */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "exclusive_to" },
|
||||
/* ATTR_EXPLICIT_HANDLE */ { 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "explicit_handle" },
|
||||
/* ATTR_FAULTSTATUS */ { 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "fault_status" },
|
||||
/* ATTR_FLAGS */ { 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "flags" },
|
||||
/* ATTR_FORCEALLOCATE */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "force_allocate" },
|
||||
/* ATTR_HANDLE */ { 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "handle" },
|
||||
/* ATTR_HELPCONTEXT */ { 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, "helpcontext" },
|
||||
/* ATTR_HELPFILE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, "helpfile" },
|
||||
/* ATTR_HELPSTRING */ { 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, "helpstring" },
|
||||
/* ATTR_HELPSTRINGCONTEXT */ { 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, "helpstringcontext" },
|
||||
/* ATTR_HELPSTRINGDLL */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, "helpstringdll" },
|
||||
/* ATTR_HIDDEN */ { 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, "hidden" },
|
||||
/* ATTR_ID */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, "id" },
|
||||
/* ATTR_IDEMPOTENT */ { 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "idempotent" },
|
||||
/* ATTR_IGNORE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "ignore" },
|
||||
/* ATTR_IIDIS */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "iid_is" },
|
||||
/* ATTR_IMMEDIATEBIND */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "immediatebind" },
|
||||
/* ATTR_IMPLICIT_HANDLE */ { 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "implicit_handle" },
|
||||
/* ATTR_IN */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "in" },
|
||||
/* ATTR_INPUTSYNC */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "inputsync" },
|
||||
/* ATTR_LENGTHIS */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "length_is" },
|
||||
/* ATTR_LIBLCID */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, "lcid" },
|
||||
/* ATTR_LICENSED */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, "licensed" },
|
||||
/* ATTR_LOCAL */ { 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "local" },
|
||||
/* ATTR_MARSHALING_BEHAVIOR */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "marshaling_behavior" },
|
||||
/* ATTR_MAYBE */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "maybe" },
|
||||
/* ATTR_MESSAGE */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "message" },
|
||||
/* ATTR_NOCODE */ { 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "nocode" },
|
||||
/* ATTR_NONBROWSABLE */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "nonbrowsable" },
|
||||
/* ATTR_NONCREATABLE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, "noncreatable" },
|
||||
/* ATTR_NONEXTENSIBLE */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "nonextensible" },
|
||||
/* ATTR_NOTIFY */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "notify" },
|
||||
/* ATTR_NOTIFYFLAG */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "notify_flag" },
|
||||
/* ATTR_OBJECT */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "object" },
|
||||
/* ATTR_ODL */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, "odl" },
|
||||
/* ATTR_OLEAUTOMATION */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "oleautomation" },
|
||||
/* ATTR_OPTIMIZE */ { 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "optimize" },
|
||||
/* ATTR_OPTIONAL */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "optional" },
|
||||
/* ATTR_OUT */ { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "out" },
|
||||
/* ATTR_OVERLOAD */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "overload" },
|
||||
/* ATTR_PARAMLCID */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "lcid" },
|
||||
/* ATTR_PARTIALIGNORE */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "partial_ignore" },
|
||||
/* ATTR_POINTERDEFAULT */ { 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "pointer_default" },
|
||||
/* ATTR_POINTERTYPE */ { 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "ref, unique or ptr" },
|
||||
/* ATTR_PROGID */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, "progid" },
|
||||
/* ATTR_PROPGET */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "propget" },
|
||||
/* ATTR_PROPPUT */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "propput" },
|
||||
/* ATTR_PROPPUTREF */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "propputref" },
|
||||
/* ATTR_PROXY */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "proxy" },
|
||||
/* ATTR_PUBLIC */ { 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "public" },
|
||||
/* ATTR_RANGE */ { 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "range" },
|
||||
/* ATTR_READONLY */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "readonly" },
|
||||
/* ATTR_REPRESENTAS */ { 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "represent_as" },
|
||||
/* ATTR_REQUESTEDIT */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "requestedit" },
|
||||
/* ATTR_RESTRICTED */ { 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, "restricted" },
|
||||
/* ATTR_RETVAL */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "retval" },
|
||||
/* ATTR_SIZEIS */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "size_is" },
|
||||
/* ATTR_SOURCE */ { 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, "source" },
|
||||
/* ATTR_STATIC */ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "static" },
|
||||
/* ATTR_STRICTCONTEXTHANDLE */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "strict_context_handle" },
|
||||
/* ATTR_STRING */ { 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "string" },
|
||||
/* ATTR_SWITCHIS */ { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "switch_is" },
|
||||
/* ATTR_SWITCHTYPE */ { 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "switch_type" },
|
||||
/* ATTR_THREADING */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, "threading" },
|
||||
/* ATTR_TRANSMITAS */ { 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "transmit_as" },
|
||||
/* ATTR_UIDEFAULT */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "uidefault" },
|
||||
/* ATTR_USESGETLASTERROR */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "usesgetlasterror" },
|
||||
/* ATTR_USERMARSHAL */ { 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "user_marshal" },
|
||||
/* ATTR_UUID */ { 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, "uuid" },
|
||||
/* ATTR_V1ENUM */ { 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "v1_enum" },
|
||||
/* ATTR_VARARG */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "vararg" },
|
||||
/* ATTR_VERSION */ { 1, 0, 0, 1, 0, 0, 1, 1, 0, 2, 0, 0, 1, 0, 1, 1, 0, 1, "version" },
|
||||
/* ATTR_VIPROGID */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, "vi_progid" },
|
||||
/* ATTR_WIREMARSHAL */ { 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "wire_marshal" },
|
||||
};
|
||||
|
||||
attr_list_t *append_attr(attr_list_t *list, attr_t *attr)
|
||||
{
|
||||
attr_t *attr_existing;
|
||||
if (!attr) return list;
|
||||
if (!list)
|
||||
{
|
||||
list = xmalloc( sizeof(*list) );
|
||||
list_init( list );
|
||||
}
|
||||
if (!allowed_attr[attr->type].multiple)
|
||||
{
|
||||
LIST_FOR_EACH_ENTRY(attr_existing, list, attr_t, entry)
|
||||
if (attr_existing->type == attr->type)
|
||||
{
|
||||
warning_loc( "duplicate attribute %s\n", get_attr_display_name(attr->type) );
|
||||
/* use the last attribute, like MIDL does */
|
||||
list_remove(&attr_existing->entry);
|
||||
break;
|
||||
}
|
||||
}
|
||||
list_add_tail( list, &attr->entry );
|
||||
return list;
|
||||
}
|
||||
|
||||
const char *get_attr_display_name(enum attr_type type)
|
||||
{
|
||||
return allowed_attr[type].display_name;
|
||||
}
|
||||
|
||||
attr_list_t *check_interface_attrs(const char *name, attr_list_t *attrs)
|
||||
{
|
||||
const attr_t *attr;
|
||||
if (!attrs) return attrs;
|
||||
LIST_FOR_EACH_ENTRY(attr, attrs, const attr_t, entry)
|
||||
{
|
||||
if (!allowed_attr[attr->type].on_interface)
|
||||
error_loc("inapplicable attribute %s for interface %s\n",
|
||||
allowed_attr[attr->type].display_name, name);
|
||||
if (attr->type == ATTR_IMPLICIT_HANDLE)
|
||||
{
|
||||
const var_t *var = attr->u.pval;
|
||||
if (type_get_type( var->declspec.type) == TYPE_BASIC &&
|
||||
type_basic_get_type( var->declspec.type ) == TYPE_BASIC_HANDLE)
|
||||
continue;
|
||||
if (is_aliaschain_attr( var->declspec.type, ATTR_HANDLE ))
|
||||
continue;
|
||||
error_loc("attribute %s requires a handle type in interface %s\n",
|
||||
allowed_attr[attr->type].display_name, name);
|
||||
}
|
||||
}
|
||||
return attrs;
|
||||
}
|
||||
|
||||
static attr_list_t *check_function_attrs(const char *name, attr_list_t *attrs)
|
||||
{
|
||||
const attr_t *attr;
|
||||
if (!attrs) return attrs;
|
||||
LIST_FOR_EACH_ENTRY(attr, attrs, const attr_t, entry)
|
||||
{
|
||||
if (!allowed_attr[attr->type].on_function)
|
||||
error_loc("inapplicable attribute %s for function %s\n",
|
||||
allowed_attr[attr->type].display_name, name);
|
||||
}
|
||||
return attrs;
|
||||
}
|
||||
|
||||
static void check_arg_attrs(const var_t *arg)
|
||||
{
|
||||
const attr_t *attr;
|
||||
|
||||
if (arg->attrs)
|
||||
{
|
||||
LIST_FOR_EACH_ENTRY(attr, arg->attrs, const attr_t, entry)
|
||||
{
|
||||
if (!allowed_attr[attr->type].on_arg)
|
||||
error_loc("inapplicable attribute %s for argument %s\n",
|
||||
allowed_attr[attr->type].display_name, arg->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static attr_list_t *check_typedef_attrs(attr_list_t *attrs)
|
||||
{
|
||||
const attr_t *attr;
|
||||
if (!attrs) return attrs;
|
||||
LIST_FOR_EACH_ENTRY(attr, attrs, const attr_t, entry)
|
||||
{
|
||||
if (!allowed_attr[attr->type].on_type)
|
||||
error_loc("inapplicable attribute %s for typedef\n",
|
||||
allowed_attr[attr->type].display_name);
|
||||
}
|
||||
return attrs;
|
||||
}
|
||||
|
||||
static attr_list_t *check_enum_attrs(attr_list_t *attrs)
|
||||
{
|
||||
const attr_t *attr;
|
||||
if (!attrs) return attrs;
|
||||
LIST_FOR_EACH_ENTRY(attr, attrs, const attr_t, entry)
|
||||
{
|
||||
if (!allowed_attr[attr->type].on_enum)
|
||||
error_loc("inapplicable attribute %s for enum\n",
|
||||
allowed_attr[attr->type].display_name);
|
||||
}
|
||||
return attrs;
|
||||
}
|
||||
|
||||
static attr_list_t *check_enum_member_attrs(attr_list_t *attrs)
|
||||
{
|
||||
const attr_t *attr;
|
||||
if (!attrs) return attrs;
|
||||
LIST_FOR_EACH_ENTRY(attr, attrs, const attr_t, entry)
|
||||
{
|
||||
if (!allowed_attr[attr->type].on_enum_member)
|
||||
error_loc("inapplicable attribute %s for enum member\n",
|
||||
allowed_attr[attr->type].display_name);
|
||||
}
|
||||
return attrs;
|
||||
}
|
||||
|
||||
static attr_list_t *check_struct_attrs(attr_list_t *attrs)
|
||||
{
|
||||
int mask = winrt_mode ? 3 : 1;
|
||||
const attr_t *attr;
|
||||
if (!attrs) return attrs;
|
||||
LIST_FOR_EACH_ENTRY(attr, attrs, const attr_t, entry)
|
||||
{
|
||||
if (!(allowed_attr[attr->type].on_struct & mask))
|
||||
error_loc("inapplicable attribute %s for struct\n",
|
||||
allowed_attr[attr->type].display_name);
|
||||
}
|
||||
return attrs;
|
||||
}
|
||||
|
||||
static attr_list_t *check_union_attrs(attr_list_t *attrs)
|
||||
{
|
||||
const attr_t *attr;
|
||||
if (!attrs) return attrs;
|
||||
LIST_FOR_EACH_ENTRY(attr, attrs, const attr_t, entry)
|
||||
{
|
||||
if (!allowed_attr[attr->type].on_union)
|
||||
error_loc("inapplicable attribute %s for union\n",
|
||||
allowed_attr[attr->type].display_name);
|
||||
}
|
||||
return attrs;
|
||||
}
|
||||
|
||||
static attr_list_t *check_field_attrs(const char *name, attr_list_t *attrs)
|
||||
{
|
||||
const attr_t *attr;
|
||||
if (!attrs) return attrs;
|
||||
LIST_FOR_EACH_ENTRY(attr, attrs, const attr_t, entry)
|
||||
{
|
||||
if (!allowed_attr[attr->type].on_field)
|
||||
error_loc("inapplicable attribute %s for field %s\n",
|
||||
allowed_attr[attr->type].display_name, name);
|
||||
}
|
||||
return attrs;
|
||||
}
|
||||
|
||||
static attr_list_t *check_library_attrs(const char *name, attr_list_t *attrs)
|
||||
{
|
||||
const attr_t *attr;
|
||||
if (!attrs) return attrs;
|
||||
LIST_FOR_EACH_ENTRY(attr, attrs, const attr_t, entry)
|
||||
{
|
||||
if (!allowed_attr[attr->type].on_library)
|
||||
error_loc("inapplicable attribute %s for library %s\n",
|
||||
allowed_attr[attr->type].display_name, name);
|
||||
}
|
||||
return attrs;
|
||||
}
|
||||
|
||||
attr_list_t *check_dispiface_attrs(const char *name, attr_list_t *attrs)
|
||||
{
|
||||
const attr_t *attr;
|
||||
if (!attrs) return attrs;
|
||||
LIST_FOR_EACH_ENTRY(attr, attrs, const attr_t, entry)
|
||||
{
|
||||
if (!allowed_attr[attr->type].on_dispinterface)
|
||||
error_loc("inapplicable attribute %s for dispinterface %s\n",
|
||||
allowed_attr[attr->type].display_name, name);
|
||||
}
|
||||
return attrs;
|
||||
}
|
||||
|
||||
attr_list_t *check_module_attrs(const char *name, attr_list_t *attrs)
|
||||
{
|
||||
const attr_t *attr;
|
||||
if (!attrs) return attrs;
|
||||
LIST_FOR_EACH_ENTRY(attr, attrs, const attr_t, entry)
|
||||
{
|
||||
if (!allowed_attr[attr->type].on_module)
|
||||
error_loc("inapplicable attribute %s for module %s\n",
|
||||
allowed_attr[attr->type].display_name, name);
|
||||
}
|
||||
return attrs;
|
||||
}
|
||||
|
||||
attr_list_t *check_coclass_attrs(const char *name, attr_list_t *attrs)
|
||||
{
|
||||
const attr_t *attr;
|
||||
if (!attrs) return attrs;
|
||||
LIST_FOR_EACH_ENTRY(attr, attrs, const attr_t, entry)
|
||||
{
|
||||
if (!allowed_attr[attr->type].on_coclass)
|
||||
error_loc("inapplicable attribute %s for coclass %s\n",
|
||||
allowed_attr[attr->type].display_name, name);
|
||||
}
|
||||
return attrs;
|
||||
}
|
||||
|
||||
attr_list_t *check_runtimeclass_attrs(const char *name, attr_list_t *attrs)
|
||||
{
|
||||
const attr_t *attr;
|
||||
if (!attrs) return attrs;
|
||||
LIST_FOR_EACH_ENTRY(attr, attrs, const attr_t, entry)
|
||||
if (!allowed_attr[attr->type].on_runtimeclass)
|
||||
error_loc("inapplicable attribute %s for runtimeclass %s\n",
|
||||
allowed_attr[attr->type].display_name, name);
|
||||
return attrs;
|
||||
}
|
||||
|
||||
attr_list_t *check_apicontract_attrs(const char *name, attr_list_t *attrs)
|
||||
{
|
||||
const attr_t *attr;
|
||||
if (!attrs) return attrs;
|
||||
LIST_FOR_EACH_ENTRY(attr, attrs, const attr_t, entry)
|
||||
if (!allowed_attr[attr->type].on_apicontract)
|
||||
error_loc("inapplicable attribute %s for apicontract %s\n",
|
||||
allowed_attr[attr->type].display_name, name);
|
||||
return attrs;
|
||||
}
|
||||
|
||||
static int is_allowed_conf_type(const type_t *type)
|
||||
{
|
||||
switch (type_get_type(type))
|
||||
|
@ -3380,14 +2907,6 @@ static statement_list_t *append_statements(statement_list_t *l1, statement_list_
|
|||
return l1;
|
||||
}
|
||||
|
||||
static attr_list_t *append_attribs(attr_list_t *l1, attr_list_t *l2)
|
||||
{
|
||||
if (!l2) return l1;
|
||||
if (!l1 || l1 == l2) return l2;
|
||||
list_move_tail (l1, l2);
|
||||
return l1;
|
||||
}
|
||||
|
||||
static statement_list_t *append_statement(statement_list_t *list, statement_t *stmt)
|
||||
{
|
||||
if (!stmt) return list;
|
||||
|
|
|
@ -185,19 +185,6 @@ static const char *string_of_type(unsigned char type)
|
|||
}
|
||||
}
|
||||
|
||||
static void *get_aliaschain_attrp(const type_t *type, enum attr_type attr)
|
||||
{
|
||||
const type_t *t = type;
|
||||
for (;;)
|
||||
{
|
||||
if (is_attr(t->attrs, attr))
|
||||
return get_attrp(t->attrs, attr);
|
||||
else if (type_is_alias(t))
|
||||
t = type_alias_get_aliasee_type(t);
|
||||
else return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned char get_basic_fc(const type_t *type)
|
||||
{
|
||||
int sign = type_basic_get_sign(type);
|
||||
|
|
|
@ -32,13 +32,6 @@ enum name_type {
|
|||
NAME_C
|
||||
};
|
||||
|
||||
attr_list_t *check_apicontract_attrs(const char *name, attr_list_t *attrs);
|
||||
attr_list_t *check_coclass_attrs(const char *name, attr_list_t *attrs);
|
||||
attr_list_t *check_dispiface_attrs(const char *name, attr_list_t *attrs);
|
||||
attr_list_t *check_interface_attrs(const char *name, attr_list_t *attrs);
|
||||
attr_list_t *check_module_attrs(const char *name, attr_list_t *attrs);
|
||||
attr_list_t *check_runtimeclass_attrs(const char *name, attr_list_t *attrs);
|
||||
|
||||
type_t *find_parameterized_type(type_t *type, typeref_list_t *params);
|
||||
|
||||
type_t *type_new_function(var_list_t *args);
|
||||
|
@ -80,12 +73,9 @@ int type_is_equal(const type_t *type1, const type_t *type2);
|
|||
const char *type_get_decl_name(const type_t *type, enum name_type name_type);
|
||||
const char *type_get_name(const type_t *type, enum name_type name_type);
|
||||
char *gen_name(void);
|
||||
extern int is_attr(const attr_list_t *list, enum attr_type t);
|
||||
|
||||
typeref_t *make_typeref(type_t *type);
|
||||
typeref_list_t *append_typeref(typeref_list_t *list, typeref_t *ref);
|
||||
attr_t *make_attrp(enum attr_type type, void *val);
|
||||
attr_list_t *append_attr(attr_list_t *list, attr_t *attr);
|
||||
|
||||
/* FIXME: shouldn't need to export this */
|
||||
type_t *duptype(type_t *t, int dupname);
|
||||
|
@ -356,6 +346,11 @@ static inline int type_is_alias(const type_t *type)
|
|||
return type->type_type == TYPE_ALIAS;
|
||||
}
|
||||
|
||||
static inline int type_is_ptr( const type_t *type )
|
||||
{
|
||||
return type->type_type == TYPE_POINTER;
|
||||
}
|
||||
|
||||
static inline const decl_spec_t *type_alias_get_aliasee(const type_t *type)
|
||||
{
|
||||
assert(type_is_alias(type));
|
||||
|
|
|
@ -95,4 +95,42 @@ extern void write_dlldata(const statement_list_t *stmts);
|
|||
extern void start_cplusplus_guard(FILE *fp);
|
||||
extern void end_cplusplus_guard(FILE *fp);
|
||||
|
||||
/* attribute.c */
|
||||
|
||||
extern attr_t *make_attr( enum attr_type attr_type );
|
||||
extern attr_t *make_attrv( enum attr_type attr_type, unsigned int val );
|
||||
extern attr_t *make_attrp( enum attr_type attr_type, void *val );
|
||||
extern attr_t *make_custom_attr( struct uuid *id, expr_t *pval );
|
||||
|
||||
extern int is_attr( const attr_list_t *list, enum attr_type attr_type );
|
||||
extern int is_ptrchain_attr( const var_t *var, enum attr_type attr_type );
|
||||
extern int is_aliaschain_attr( const type_t *type, enum attr_type attr_type );
|
||||
|
||||
extern unsigned int get_attrv( const attr_list_t *list, enum attr_type attr_type );
|
||||
extern void *get_attrp( const attr_list_t *list, enum attr_type attr_type );
|
||||
extern void *get_aliaschain_attrp( const type_t *type, enum attr_type attr_type );
|
||||
|
||||
typedef int (*map_attrs_filter_t)( attr_list_t *, const attr_t * );
|
||||
extern attr_list_t *append_attr( attr_list_t *list, attr_t *attr );
|
||||
extern attr_list_t *append_attr_list( attr_list_t *new_list, attr_list_t *old_list );
|
||||
extern attr_list_t *append_attribs( attr_list_t *, attr_list_t * );
|
||||
extern attr_list_t *map_attrs( const attr_list_t *list, map_attrs_filter_t filter );
|
||||
extern attr_list_t *move_attr( attr_list_t *dst, attr_list_t *src, enum attr_type type );
|
||||
|
||||
extern attr_list_t *check_apicontract_attrs( const char *name, attr_list_t *attrs );
|
||||
extern attr_list_t *check_coclass_attrs( const char *name, attr_list_t *attrs );
|
||||
extern attr_list_t *check_dispiface_attrs( const char *name, attr_list_t *attrs );
|
||||
extern attr_list_t *check_enum_attrs( attr_list_t *attrs );
|
||||
extern attr_list_t *check_enum_member_attrs( attr_list_t *attrs );
|
||||
extern attr_list_t *check_field_attrs( const char *name, attr_list_t *attrs );
|
||||
extern attr_list_t *check_function_attrs( const char *name, attr_list_t *attrs );
|
||||
extern attr_list_t *check_interface_attrs( const char *name, attr_list_t *attrs );
|
||||
extern attr_list_t *check_library_attrs( const char *name, attr_list_t *attrs );
|
||||
extern attr_list_t *check_module_attrs( const char *name, attr_list_t *attrs );
|
||||
extern attr_list_t *check_runtimeclass_attrs( const char *name, attr_list_t *attrs );
|
||||
extern attr_list_t *check_struct_attrs( attr_list_t *attrs );
|
||||
extern attr_list_t *check_typedef_attrs( attr_list_t *attrs );
|
||||
extern attr_list_t *check_union_attrs( attr_list_t *attrs );
|
||||
extern void check_arg_attrs( const var_t *arg );
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue