Signed-off-by: Rémi Bernon rbernon@codeweavers.com ---
v2: Just add the explicit abi_prefix parameter, we don't really need the buffer management for now. I'll add a strappend helper in some future series.
Supersedes: 196372-196375
tools/widl/header.c | 2 +- tools/widl/parser.y | 2 +- tools/widl/typetree.c | 18 +++++++++--------- tools/widl/widltypes.h | 3 ++- 4 files changed, 13 insertions(+), 12 deletions(-)
diff --git a/tools/widl/header.c b/tools/widl/header.c index 015bbe2ece7..a892243fb54 100644 --- a/tools/widl/header.c +++ b/tools/widl/header.c @@ -132,7 +132,7 @@ static void write_guid(FILE *f, const char *guid_prefix, const char *name, const
static void write_uuid_decl(FILE *f, type_t *type, const UUID *uuid) { - char *name = format_namespace(type->namespace, "", "::", type->name); + char *name = format_namespace(type->namespace, "", "::", type->name, use_abi_namespace ? "ABI" : NULL); fprintf(f, "#ifdef __CRT_UUID_DECL\n"); fprintf(f, "__CRT_UUID_DECL(%s, 0x%08x, 0x%04x, 0x%04x, 0x%02x,0x%02x, 0x%02x," "0x%02x,0x%02x,0x%02x,0x%02x,0x%02x)\n", diff --git a/tools/widl/parser.y b/tools/widl/parser.y index 160e4029a6e..1bbb2e78f7e 100644 --- a/tools/widl/parser.y +++ b/tools/widl/parser.y @@ -1922,7 +1922,7 @@ type_t *reg_type(type_t *type, const char *name, struct namespace *namespace, in if (is_global_namespace(namespace)) type->c_name = name; else - type->c_name = format_namespace(namespace, "__x_", "_C", name); + type->c_name = format_namespace(namespace, "__x_", "_C", name, use_abi_namespace ? "ABI" : NULL); nt->type = type; nt->t = t; nt->next = namespace->type_hash[hash]; diff --git a/tools/widl/typetree.c b/tools/widl/typetree.c index c0547b36a96..df883576915 100644 --- a/tools/widl/typetree.c +++ b/tools/widl/typetree.c @@ -89,38 +89,38 @@ const char *type_get_name(const type_t *type, enum name_type name_type) return NULL; }
-static char *append_namespace(char *ptr, struct namespace *namespace, const char *separator) +static char *append_namespace(char *ptr, struct namespace *namespace, const char *separator, const char *abi_prefix) { if(is_global_namespace(namespace)) { - if(!use_abi_namespace) - return ptr; - strcpy(ptr, "ABI"); + if(!abi_prefix) return ptr; + strcpy(ptr, abi_prefix); strcat(ptr, separator); return ptr + strlen(ptr); }
- ptr = append_namespace(ptr, namespace->parent, separator); + ptr = append_namespace(ptr, namespace->parent, separator, abi_prefix); strcpy(ptr, namespace->name); strcat(ptr, separator); return ptr + strlen(ptr); }
-char *format_namespace(struct namespace *namespace, const char *prefix, const char *separator, const char *suffix) +char *format_namespace(struct namespace *namespace, const char *prefix, const char *separator, const char *suffix, + const char *abi_prefix) { unsigned len = strlen(prefix) + strlen(suffix); unsigned sep_len = strlen(separator); struct namespace *iter; char *ret, *ptr;
- if(use_abi_namespace && !is_global_namespace(namespace)) - len += 3 /* strlen("ABI") */ + sep_len; + if(abi_prefix) + len += strlen(abi_prefix) + sep_len;
for(iter = namespace; !is_global_namespace(iter); iter = iter->parent) len += strlen(iter->name) + sep_len;
ret = xmalloc(len+1); strcpy(ret, prefix); - ptr = append_namespace(ret + strlen(ret), namespace, separator); + ptr = append_namespace(ret + strlen(ret), namespace, separator, abi_prefix); strcpy(ptr, suffix);
return ret; diff --git a/tools/widl/widltypes.h b/tools/widl/widltypes.h index b02b80e122c..7a43e517698 100644 --- a/tools/widl/widltypes.h +++ b/tools/widl/widltypes.h @@ -613,7 +613,8 @@ var_list_t *append_var(var_list_t *list, var_t *var);
void init_loc_info(loc_info_t *);
-char *format_namespace(struct namespace *namespace, const char *prefix, const char *separator, const char *suffix); +char *format_namespace(struct namespace *namespace, const char *prefix, const char *separator, const char *suffix, + const char *abi_prefix);
static inline enum type_type type_get_type_detect_alias(const type_t *type) {
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- tools/widl/parser.l | 1 + tools/widl/parser.y | 12 +++++++++++- tools/widl/widltypes.h | 1 + 3 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/tools/widl/parser.l b/tools/widl/parser.l index d7d96702322..a4e1d0d2c47 100644 --- a/tools/widl/parser.l +++ b/tools/widl/parser.l @@ -338,6 +338,7 @@ static const struct keyword attr_keywords[] = {"context_handle", tCONTEXTHANDLE, 0}, {"context_handle_noserialize", tCONTEXTHANDLENOSERIALIZE, 0}, {"context_handle_serialize", tCONTEXTHANDLENOSERIALIZE, 0}, + {"contractversion", tCONTRACTVERSION, 1}, {"control", tCONTROL, 0}, {"custom", tCUSTOM, 0}, {"decode", tDECODE, 0}, diff --git a/tools/widl/parser.y b/tools/widl/parser.y index 1bbb2e78f7e..3c4c8041a1c 100644 --- a/tools/widl/parser.y +++ b/tools/widl/parser.y @@ -177,7 +177,9 @@ static typelib_t *current_typelib; %token tAUTOHANDLE tBINDABLE tBOOLEAN tBROADCAST tBYTE tBYTECOUNT %token tCALLAS tCALLBACK tCASE tCDECL tCHAR tCOCLASS tCODE tCOMMSTATUS %token tCONST tCONTEXTHANDLE tCONTEXTHANDLENOSERIALIZE -%token tCONTEXTHANDLESERIALIZE tCONTROL tCPPQUOTE +%token tCONTEXTHANDLESERIALIZE +%token tCONTRACTVERSION +%token tCONTROL tCPPQUOTE %token tCUSTOM %token tDECODE tDEFAULT tDEFAULTBIND %token tDEFAULTCOLLELEM @@ -290,6 +292,7 @@ static typelib_t *current_typelib; %type <declarator> m_abstract_declarator abstract_declarator abstract_declarator_no_direct abstract_direct_declarator %type <declarator_list> declarator_list struct_declarator_list %type <type> coclass coclasshdr coclassdef +%type <num> contract_ver %type <num> pointer_type threading_type version %type <str> libraryhdr callconv cppquote importlib import t_ident %type <uuid> uuid_string @@ -492,6 +495,11 @@ str_list: aSTRING { $$ = append_str( NULL, $1 ); } | str_list ',' aSTRING { $$ = append_str( $1, $3 ); } ;
+contract_ver: + aNUM { $$ = MAKEVERSION(0, $1); } + | aNUM '.' aNUM { $$ = MAKEVERSION($3, $1); } + ; + attribute: { $$ = NULL; } | tAGGREGATABLE { $$ = make_attr(ATTR_AGGREGATABLE); } | tANNOTATION '(' aSTRING ')' { $$ = make_attrp(ATTR_ANNOTATION, $3); } @@ -507,6 +515,7 @@ attribute: { $$ = NULL; } | tCONTEXTHANDLE { $$ = make_attrv(ATTR_CONTEXTHANDLE, 0); } | tCONTEXTHANDLENOSERIALIZE { $$ = make_attrv(ATTR_CONTEXTHANDLE, 0); /* RPC_CONTEXT_HANDLE_DONT_SERIALIZE */ } | tCONTEXTHANDLESERIALIZE { $$ = make_attrv(ATTR_CONTEXTHANDLE, 0); /* RPC_CONTEXT_HANDLE_SERIALIZE */ } + | tCONTRACTVERSION '(' contract_ver ')' { $$ = make_attrv(ATTR_CONTRACTVERSION, $3); } | tCONTROL { $$ = make_attr(ATTR_CONTROL); } | tCUSTOM '(' uuid_string ',' expr_const ')' { $$ = make_custom_attr($3, $5); } | tDECODE { $$ = make_attr(ATTR_DECODE); } @@ -2155,6 +2164,7 @@ struct allowed_attr allowed_attr[] = /* ATTR_CODE */ { 0, 1, 0, 1, 1, 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, "comm_status" }, /* ATTR_CONTEXTHANDLE */ { 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "context_handle" }, + /* ATTR_CONTRACTVERSION */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "contractversion" }, /* ATTR_CONTROL */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, "control" }, /* ATTR_CUSTOM */ { 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, "custom" }, /* ATTR_DECODE */ { 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "decode" }, diff --git a/tools/widl/widltypes.h b/tools/widl/widltypes.h index 7a43e517698..78401cf8278 100644 --- a/tools/widl/widltypes.h +++ b/tools/widl/widltypes.h @@ -84,6 +84,7 @@ enum attr_type ATTR_CODE, ATTR_COMMSTATUS, ATTR_CONTEXTHANDLE, + ATTR_CONTRACTVERSION, ATTR_CONTROL, ATTR_CUSTOM, ATTR_DECODE,
Signed-off-by: Rémi Bernon rbernon@codeweavers.com ---
These types generate this kind of preprocessor macros in windowscontracts.h:
#if !defined(WINDOWS_FOUNDATION_FOUNDATIONCONTRACT_VERSION) #define WINDOWS_FOUNDATION_FOUNDATIONCONTRACT_VERSION 0x40000 #endif // defined(WINDOWS_FOUNDATION_FOUNDATIONCONTRACT_VERSION)
#if !defined(WINDOWS_FOUNDATION_UNIVERSALAPICONTRACT_VERSION) #define WINDOWS_FOUNDATION_UNIVERSALAPICONTRACT_VERSION 0xa0000 #endif // defined(WINDOWS_FOUNDATION_UNIVERSALAPICONTRACT_VERSION)
include/Makefile.in | 1 + include/windows.foundation.idl | 1 + include/windowscontracts.idl | 33 +++++ tools/widl/expr.c | 1 + tools/widl/header.c | 27 ++++ tools/widl/parser.l | 1 + tools/widl/parser.y | 239 +++++++++++++++++++-------------- tools/widl/typegen.c | 6 + tools/widl/typelib.c | 3 +- tools/widl/typetree.h | 3 + tools/widl/widltypes.h | 1 + 11 files changed, 211 insertions(+), 105 deletions(-) create mode 100644 include/windowscontracts.idl
diff --git a/include/Makefile.in b/include/Makefile.in index 3df4da64233..a84e44998cc 100644 --- a/include/Makefile.in +++ b/include/Makefile.in @@ -744,6 +744,7 @@ SOURCES = \ windns.h \ windows.foundation.idl \ windows.h \ + windowscontracts.idl \ windowsx.h \ wine/debug.h \ wine/exception.h \ diff --git a/include/windows.foundation.idl b/include/windows.foundation.idl index 2c16fa2da22..2a38e9f671b 100644 --- a/include/windows.foundation.idl +++ b/include/windows.foundation.idl @@ -22,6 +22,7 @@
import "inspectable.idl"; /* import "asyncinfo.idl"; */ +import "windowscontracts.idl"; /* import "eventtoken.idl"; */ /* import "ivectorchangedeventargs.idl"; */
diff --git a/include/windowscontracts.idl b/include/windowscontracts.idl new file mode 100644 index 00000000000..6bcf80ac954 --- /dev/null +++ b/include/windowscontracts.idl @@ -0,0 +1,33 @@ +/* + * Copyright 2020 Rémi Bernon for CodeWeavers + * + * 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 + */ + +#ifdef __WIDL__ +#pragma winrt ns_prefix +#endif + +namespace Windows { + namespace Foundation { + [contractversion(4)] + apicontract FoundationContract + {}; + + [contractversion(10)] + apicontract UniversalApiContract + {}; + } +} diff --git a/tools/widl/expr.c b/tools/widl/expr.c index d1ee599a39e..be8311cfb7f 100644 --- a/tools/widl/expr.c +++ b/tools/widl/expr.c @@ -462,6 +462,7 @@ static type_t *find_identifier(const char *identifier, const type_t *cont_type, case TYPE_POINTER: case TYPE_ARRAY: case TYPE_BITFIELD: + case TYPE_APICONTRACT: /* nothing to do */ break; case TYPE_ALIAS: diff --git a/tools/widl/header.c b/tools/widl/header.c index a892243fb54..657ce50c679 100644 --- a/tools/widl/header.c +++ b/tools/widl/header.c @@ -471,6 +471,10 @@ void write_type_left(FILE *h, const decl_spec_t *ds, enum name_type name_type, i else write_type_left(h, ds, name_type, declonly, write_callconv); break; } + case TYPE_APICONTRACT: + /* shouldn't be here */ + assert(0); + break; } } } @@ -533,6 +537,10 @@ void write_type_right(FILE *h, type_t *t, int is_field) case TYPE_COCLASS: case TYPE_INTERFACE: break; + case TYPE_APICONTRACT: + /* not supposed to be here */ + assert(0); + break; } }
@@ -1452,6 +1460,14 @@ static void write_forward(FILE *header, type_t *iface) fprintf(header, "#endif\n\n" ); }
+static char *format_apicontract_macro(const type_t *type) +{ + char *name = format_namespace(type->namespace, "", "_", type->name, NULL); + int i; + for (i = strlen(name); i > 0; --i) name[i - 1] = toupper(name[i - 1]); + return name; +} + static void write_com_interface_start(FILE *header, const type_t *iface) { int dispinterface = is_attr(iface->attrs, ATTR_DISPINTERFACE); @@ -1616,6 +1632,15 @@ static void write_coclass_forward(FILE *header, type_t *cocl) fprintf(header, "#endif /* defined __%s_FWD_DEFINED__ */\n\n", cocl->name ); }
+static void write_apicontract(FILE *header, type_t *apicontract) +{ + char *name = format_apicontract_macro(apicontract); + fprintf(header, "#if !defined(%s_VERSION)\n", name); + fprintf(header, "#define %s_VERSION %#x\n", name, get_attrv(apicontract->attrs, ATTR_CONTRACTVERSION)); + fprintf(header, "#endif // defined(%s_VERSION)\n\n", name); + free(name); +} + static void write_import(FILE *header, const char *fname) { char *hname, *p; @@ -1734,6 +1759,8 @@ static void write_header_stmts(FILE *header, const statement_list_t *stmts, cons } else if (type_get_type(stmt->u.type) == TYPE_COCLASS) write_coclass(header, stmt->u.type); + else if (type_get_type(stmt->u.type) == TYPE_APICONTRACT) + write_apicontract(header, stmt->u.type); else { write_type_definition(header, stmt->u.type, stmt->declonly); diff --git a/tools/widl/parser.l b/tools/widl/parser.l index a4e1d0d2c47..6a9bb65a483 100644 --- a/tools/widl/parser.l +++ b/tools/widl/parser.l @@ -267,6 +267,7 @@ static const struct keyword keywords[] = { {"_fastcall", tFASTCALL, 0}, {"_pascal", tPASCAL, 0}, {"_stdcall", tSTDCALL, 0}, + {"apicontract", tAPICONTRACT, 1}, {"boolean", tBOOLEAN, 0}, {"byte", tBYTE, 0}, {"case", tCASE, 0}, diff --git a/tools/widl/parser.y b/tools/widl/parser.y index 3c4c8041a1c..5b4bd518a0b 100644 --- a/tools/widl/parser.y +++ b/tools/widl/parser.y @@ -100,6 +100,7 @@ static attr_list_t *check_library_attrs(const char *name, attr_list_t *attrs); static attr_list_t *check_dispiface_attrs(const char *name, attr_list_t *attrs); static attr_list_t *check_module_attrs(const char *name, attr_list_t *attrs); static attr_list_t *check_coclass_attrs(const char *name, attr_list_t *attrs); +static attr_list_t *check_apicontract_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_def(const type_t *t); @@ -173,7 +174,9 @@ static typelib_t *current_typelib; %token GREATEREQUAL LESSEQUAL %token LOGICALOR LOGICALAND %token ELLIPSIS -%token tAGGREGATABLE tALLNODES tALLOCATE tANNOTATION tAPPOBJECT tASYNC tASYNCUUID +%token tAGGREGATABLE tALLNODES tALLOCATE tANNOTATION +%token tAPICONTRACT +%token tAPPOBJECT tASYNC tASYNCUUID %token tAUTOHANDLE tBINDABLE tBOOLEAN tBROADCAST tBYTE tBYTECOUNT %token tCALLAS tCALLBACK tCASE tCDECL tCHAR tCOCLASS tCODE tCOMMSTATUS %token tCONST tCONTEXTHANDLE tCONTEXTHANDLENOSERIALIZE @@ -292,6 +295,7 @@ static typelib_t *current_typelib; %type <declarator> m_abstract_declarator abstract_declarator abstract_declarator_no_direct abstract_direct_declarator %type <declarator_list> declarator_list struct_declarator_list %type <type> coclass coclasshdr coclassdef +%type <type> apicontract %type <num> contract_ver %type <num> pointer_type threading_type version %type <str> libraryhdr callconv cppquote importlib import t_ident @@ -349,6 +353,8 @@ gbl_statements: { $$ = NULL; } | gbl_statements coclassdef { $$ = append_statement($1, make_statement_type_decl($2)); reg_type($2, $2->name, current_namespace, 0); } + | gbl_statements apicontract ';' { $$ = append_statement($1, make_statement_type_decl($2)); + reg_type($2, $2->name, current_namespace, 0); } | gbl_statements moduledef { $$ = append_statement($1, make_statement_module($2)); } | gbl_statements librarydef { $$ = append_statement($1, make_statement_library($2)); } | gbl_statements statement { $$ = append_statement($1, $2); } @@ -363,6 +369,8 @@ imp_statements: { $$ = NULL; } | imp_statements coclassdef { $$ = append_statement($1, make_statement_type_decl($2)); reg_type($2, $2->name, current_namespace, 0); } + | imp_statements apicontract ';' { $$ = append_statement($1, make_statement_type_decl($2)); + reg_type($2, $2->name, current_namespace, 0); } | imp_statements moduledef { $$ = append_statement($1, make_statement_module($2)); } | imp_statements statement { $$ = append_statement($1, $2); } | imp_statements importlib { $$ = append_statement($1, make_statement_importlib($2)); } @@ -868,6 +876,13 @@ coclassdef: coclasshdr '{' coclass_ints '}' semicolon_opt { $$ = type_coclass_define($1, $3); } ;
+apicontract: attributes tAPICONTRACT aIDENTIFIER '{' '}' + { $$ = get_type(TYPE_APICONTRACT, $3, current_namespace, 0); + check_def($$); + $$->attrs = check_apicontract_attrs($$->name, $1); + } + ; + namespacedef: tNAMESPACE aIDENTIFIER { $$ = $2; } | tNAMESPACE aNAMESPACE { $$ = $2; } ; @@ -2143,114 +2158,115 @@ struct allowed_attr unsigned int on_dispinterface : 1; unsigned int on_module : 1; unsigned int on_coclass : 1; + unsigned int on_apicontract : 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 <display name> } */ - /* ATTR_AGGREGATABLE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "aggregatable" }, - /* ATTR_ALLOCATE */ { 0, 1, 0, 0, 0, 0, 1, 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, "annotation" }, - /* ATTR_APPOBJECT */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "appobject" }, - /* ATTR_ASYNC */ { 0, 1, 0, 0, 1, 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, "async_uuid" }, - /* ATTR_AUTO_HANDLE */ { 1, 1, 0, 1, 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, "bindable" }, - /* ATTR_BROADCAST */ { 1, 0, 0, 0, 1, 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, "call_as" }, - /* ATTR_CALLCONV */ { 0, 0, 0, 0, 1, 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, "case" }, - /* ATTR_CODE */ { 0, 1, 0, 1, 1, 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, "comm_status" }, - /* ATTR_CONTEXTHANDLE */ { 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "context_handle" }, - /* ATTR_CONTRACTVERSION */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "contractversion" }, - /* ATTR_CONTROL */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, "control" }, - /* ATTR_CUSTOM */ { 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, "custom" }, - /* ATTR_DECODE */ { 0, 0, 0, 1, 1, 0, 1, 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, "default" }, - /* ATTR_DEFAULTBIND */ { 0, 0, 0, 0, 1, 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, "defaultcollelem" }, - /* ATTR_DEFAULTVALUE */ { 0, 0, 0, 0, 0, 1, 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, "defaultvtable" }, - /* ATTR_DISABLECONSISTENCYCHECK */{ 0, 0, 0, 0, 0, 1, 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, 0, 0, 0, NULL }, - /* ATTR_DISPLAYBIND */ { 0, 0, 0, 0, 1, 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, "dllname" }, - /* ATTR_DUAL */ { 0, 0, 0, 1, 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, "enable_allocate" }, - /* ATTR_ENCODE */ { 0, 0, 0, 1, 1, 0, 1, 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, "endpoint" }, - /* ATTR_ENTRY */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "entry" }, - /* ATTR_EXPLICIT_HANDLE */ { 1, 1, 0, 1, 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, "fault_status" }, - /* ATTR_FORCEALLOCATE */ { 0, 0, 0, 0, 0, 1, 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, "handle" }, - /* ATTR_HELPCONTEXT */ { 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, "helpcontext" }, - /* ATTR_HELPFILE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, "helpfile" }, - /* ATTR_HELPSTRING */ { 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, "helpstring" }, - /* ATTR_HELPSTRINGCONTEXT */ { 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, "helpstringcontext" }, - /* ATTR_HELPSTRINGDLL */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, "helpstringdll" }, - /* ATTR_HIDDEN */ { 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, "hidden" }, - /* ATTR_ID */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, "id" }, - /* ATTR_IDEMPOTENT */ { 1, 0, 0, 0, 1, 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, "ignore" }, - /* ATTR_IIDIS */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, "iid_is" }, - /* ATTR_IMMEDIATEBIND */ { 0, 0, 0, 0, 1, 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, "implicit_handle" }, - /* ATTR_IN */ { 0, 0, 0, 0, 0, 1, 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, "inputsync" }, - /* ATTR_LENGTHIS */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, "length_is" }, - /* ATTR_LIBLCID */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, "lcid" }, - /* ATTR_LICENSED */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "licensed" }, - /* ATTR_LOCAL */ { 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "local" }, - /* ATTR_MAYBE */ { 0, 0, 0, 0, 1, 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, "message" }, - /* ATTR_NOCODE */ { 0, 1, 0, 1, 1, 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, "nonbrowsable" }, - /* ATTR_NONCREATABLE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "noncreatable" }, - /* ATTR_NONEXTENSIBLE */ { 0, 0, 0, 1, 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, "notify" }, - /* ATTR_NOTIFYFLAG */ { 0, 0, 0, 0, 1, 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, "object" }, - /* ATTR_ODL */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, "odl" }, - /* ATTR_OLEAUTOMATION */ { 0, 0, 0, 1, 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, "optimize" }, - /* ATTR_OPTIONAL */ { 0, 0, 0, 0, 0, 1, 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, "out" }, - /* ATTR_PARAMLCID */ { 0, 0, 0, 0, 0, 1, 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, "partial_ignore" }, - /* ATTR_POINTERDEFAULT */ { 1, 0, 0, 1, 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, "ref, unique or ptr" }, - /* ATTR_PROGID */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "progid" }, - /* ATTR_PROPGET */ { 0, 0, 0, 0, 1, 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, "propput" }, - /* ATTR_PROPPUTREF */ { 0, 0, 0, 0, 1, 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, "proxy" }, - /* ATTR_PUBLIC */ { 0, 0, 0, 0, 0, 0, 1, 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, "range" }, - /* ATTR_READONLY */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, "readonly" }, - /* ATTR_REPRESENTAS */ { 1, 0, 0, 0, 0, 0, 1, 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, "requestedit" }, - /* ATTR_RESTRICTED */ { 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, "restricted" }, - /* ATTR_RETVAL */ { 0, 0, 0, 0, 0, 1, 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, "size_is" }, - /* ATTR_SOURCE */ { 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, "source" }, - /* ATTR_STRICTCONTEXTHANDLE */ { 0, 0, 0, 1, 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, "string" }, - /* ATTR_SWITCHIS */ { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, "switch_is" }, - /* ATTR_SWITCHTYPE */ { 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, "switch_type" }, - /* ATTR_THREADING */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "threading" }, - /* ATTR_TRANSMITAS */ { 1, 0, 0, 0, 0, 0, 1, 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, "uidefault" }, - /* ATTR_USESGETLASTERROR */ { 0, 0, 0, 0, 1, 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, "user_marshal" }, - /* ATTR_UUID */ { 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, "uuid" }, - /* ATTR_V1ENUM */ { 0, 0, 0, 0, 0, 0, 1, 1, 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, "vararg" }, - /* ATTR_VERSION */ { 1, 0, 0, 1, 0, 0, 1, 1, 0, 2, 0, 0, 1, 0, 0, 1, "version" }, - /* ATTR_VIPROGID */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "vi_progid" }, - /* ATTR_WIREMARSHAL */ { 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "wire_marshal" }, + /* attr { D ACF M I Fn ARG T En Enm St Un Fi L DI M C AC <display name> } */ + /* ATTR_AGGREGATABLE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, "aggregatable" }, + /* ATTR_ALLOCATE */ { 0, 1, 0, 0, 0, 0, 1, 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, "annotation" }, + /* ATTR_APPOBJECT */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, "appobject" }, + /* ATTR_ASYNC */ { 0, 1, 0, 0, 1, 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, "async_uuid" }, + /* ATTR_AUTO_HANDLE */ { 1, 1, 0, 1, 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, "bindable" }, + /* ATTR_BROADCAST */ { 1, 0, 0, 0, 1, 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, "call_as" }, + /* ATTR_CALLCONV */ { 0, 0, 0, 0, 1, 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, "case" }, + /* ATTR_CODE */ { 0, 1, 0, 1, 1, 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, "comm_status" }, + /* ATTR_CONTEXTHANDLE */ { 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "context_handle" }, + /* ATTR_CONTRACTVERSION */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "contractversion" }, + /* ATTR_CONTROL */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, "control" }, + /* ATTR_CUSTOM */ { 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, "custom" }, + /* ATTR_DECODE */ { 0, 0, 0, 1, 1, 0, 1, 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, "default" }, + /* ATTR_DEFAULTBIND */ { 0, 0, 0, 0, 1, 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, "defaultcollelem" }, + /* ATTR_DEFAULTVALUE */ { 0, 0, 0, 0, 0, 1, 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, "defaultvtable" }, + /* ATTR_DISABLECONSISTENCYCHECK */{ 0, 0, 0, 0, 0, 1, 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, 0, 0, 0, 0, NULL }, + /* ATTR_DISPLAYBIND */ { 0, 0, 0, 0, 1, 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, "dllname" }, + /* ATTR_DUAL */ { 0, 0, 0, 1, 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, "enable_allocate" }, + /* ATTR_ENCODE */ { 0, 0, 0, 1, 1, 0, 1, 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, "endpoint" }, + /* ATTR_ENTRY */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "entry" }, + /* ATTR_EXPLICIT_HANDLE */ { 1, 1, 0, 1, 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, "fault_status" }, + /* ATTR_FORCEALLOCATE */ { 0, 0, 0, 0, 0, 1, 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, "handle" }, + /* ATTR_HELPCONTEXT */ { 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, "helpcontext" }, + /* ATTR_HELPFILE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, "helpfile" }, + /* ATTR_HELPSTRING */ { 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, "helpstring" }, + /* ATTR_HELPSTRINGCONTEXT */ { 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, "helpstringcontext" }, + /* ATTR_HELPSTRINGDLL */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, "helpstringdll" }, + /* ATTR_HIDDEN */ { 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, "hidden" }, + /* ATTR_ID */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, "id" }, + /* ATTR_IDEMPOTENT */ { 1, 0, 0, 0, 1, 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, "ignore" }, + /* ATTR_IIDIS */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 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, "immediatebind" }, + /* ATTR_IMPLICIT_HANDLE */ { 1, 1, 0, 1, 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, "in" }, + /* ATTR_INPUTSYNC */ { 0, 0, 0, 0, 1, 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, "length_is" }, + /* ATTR_LIBLCID */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, "lcid" }, + /* ATTR_LICENSED */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, "licensed" }, + /* ATTR_LOCAL */ { 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "local" }, + /* ATTR_MAYBE */ { 0, 0, 0, 0, 1, 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, "message" }, + /* ATTR_NOCODE */ { 0, 1, 0, 1, 1, 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, "nonbrowsable" }, + /* ATTR_NONCREATABLE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, "noncreatable" }, + /* ATTR_NONEXTENSIBLE */ { 0, 0, 0, 1, 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, "notify" }, + /* ATTR_NOTIFYFLAG */ { 0, 0, 0, 0, 1, 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, "object" }, + /* ATTR_ODL */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, "odl" }, + /* ATTR_OLEAUTOMATION */ { 0, 0, 0, 1, 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, "optimize" }, + /* ATTR_OPTIONAL */ { 0, 0, 0, 0, 0, 1, 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, "out" }, + /* ATTR_PARAMLCID */ { 0, 0, 0, 0, 0, 1, 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, "partial_ignore" }, + /* ATTR_POINTERDEFAULT */ { 1, 0, 0, 1, 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, "ref, unique or ptr" }, + /* ATTR_PROGID */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, "progid" }, + /* ATTR_PROPGET */ { 0, 0, 0, 0, 1, 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, "propput" }, + /* ATTR_PROPPUTREF */ { 0, 0, 0, 0, 1, 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, "proxy" }, + /* ATTR_PUBLIC */ { 0, 0, 0, 0, 0, 0, 1, 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, "range" }, + /* ATTR_READONLY */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 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, "represent_as" }, + /* ATTR_REQUESTEDIT */ { 0, 0, 0, 0, 1, 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, "restricted" }, + /* ATTR_RETVAL */ { 0, 0, 0, 0, 0, 1, 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, "size_is" }, + /* ATTR_SOURCE */ { 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, "source" }, + /* ATTR_STRICTCONTEXTHANDLE */ { 0, 0, 0, 1, 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, "string" }, + /* ATTR_SWITCHIS */ { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 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, "switch_type" }, + /* ATTR_THREADING */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, "threading" }, + /* ATTR_TRANSMITAS */ { 1, 0, 0, 0, 0, 0, 1, 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, "uidefault" }, + /* ATTR_USESGETLASTERROR */ { 0, 0, 0, 0, 1, 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, "user_marshal" }, + /* ATTR_UUID */ { 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, "uuid" }, + /* ATTR_V1ENUM */ { 0, 0, 0, 0, 0, 0, 1, 1, 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, "vararg" }, + /* ATTR_VERSION */ { 1, 0, 0, 1, 0, 0, 1, 1, 0, 2, 0, 0, 1, 0, 0, 1, 0, "version" }, + /* ATTR_VIPROGID */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, "vi_progid" }, + /* ATTR_WIREMARSHAL */ { 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "wire_marshal" }, };
static attr_list_t *append_attr(attr_list_t *list, attr_t *attr) @@ -2465,6 +2481,17 @@ static attr_list_t *check_coclass_attrs(const char *name, attr_list_t *attrs) return attrs; }
+static 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)) @@ -2504,6 +2531,10 @@ static int is_allowed_conf_type(const type_t *type) case TYPE_INTERFACE: case TYPE_BITFIELD: return FALSE; + case TYPE_APICONTRACT: + /* not supposed to be here */ + assert(0); + break; } return FALSE; } diff --git a/tools/widl/typegen.c b/tools/widl/typegen.c index 4874dfd6c24..5d0f24be06f 100644 --- a/tools/widl/typegen.c +++ b/tools/widl/typegen.c @@ -374,6 +374,10 @@ enum typegen_type typegen_detect_type(const type_t *type, const attr_list_t *att case TYPE_ALIAS: case TYPE_BITFIELD: break; + case TYPE_APICONTRACT: + /* not supposed to be here */ + assert(0); + break; } return TGT_INVALID; } @@ -1966,6 +1970,7 @@ unsigned int type_memsize_and_alignment(const type_t *t, unsigned int *align) case TYPE_MODULE: case TYPE_FUNCTION: case TYPE_BITFIELD: + case TYPE_APICONTRACT: /* these types should not be encountered here due to language * restrictions (interface, void, coclass, module), logical * restrictions (alias - due to type_get_type call above) or @@ -2067,6 +2072,7 @@ static unsigned int type_buffer_alignment(const type_t *t) case TYPE_MODULE: case TYPE_FUNCTION: case TYPE_BITFIELD: + case TYPE_APICONTRACT: /* these types should not be encountered here due to language * restrictions (interface, void, coclass, module), logical * restrictions (alias - due to type_get_type call above) or diff --git a/tools/widl/typelib.c b/tools/widl/typelib.c index cf027558d0a..faf76440f93 100644 --- a/tools/widl/typelib.c +++ b/tools/widl/typelib.c @@ -224,7 +224,8 @@ unsigned short get_type_vt(type_t *t) return VT_VOID;
case TYPE_ALIAS: - /* aliases should be filtered out by the type_get_type call above */ + case TYPE_APICONTRACT: + /* not supposed to be here */ assert(0); break;
diff --git a/tools/widl/typetree.h b/tools/widl/typetree.h index e288c574002..7abec41a8fd 100644 --- a/tools/widl/typetree.h +++ b/tools/widl/typetree.h @@ -223,6 +223,9 @@ static inline int type_is_complete(const type_t *type) case TYPE_ARRAY: case TYPE_BITFIELD: return TRUE; + case TYPE_APICONTRACT: + assert(0); + break; } return FALSE; } diff --git a/tools/widl/widltypes.h b/tools/widl/widltypes.h index 78401cf8278..878650d9c27 100644 --- a/tools/widl/widltypes.h +++ b/tools/widl/widltypes.h @@ -440,6 +440,7 @@ enum type_type TYPE_POINTER, TYPE_ARRAY, TYPE_BITFIELD, + TYPE_APICONTRACT, };
struct _type_t {
Signed-off-by: Rémi Bernon rbernon@codeweavers.com ---
This makes the following kind of changes to the generated header files, according to the contract and version specified on each type:
--- a/windows.foundation.h +++ b/windows.foundation.h @@ -35,11 +35,13 @@ namespace ABI { /* Headers for imported files */
#include <inspectable.h> +#include <windowscontracts.h>
#ifdef __cplusplus extern "C" { #endif
+#if WINDOWS_FOUNDATION_FOUNDATIONCONTRACT_VERSION >= 0x10000 #ifdef __cplusplus } /* extern "C" */ namespace ABI { @@ -138,6 +140,8 @@ enum __x_ABI_CWindows_CFoundation_CPropertyType { }; #endif
+#endif /* WINDOWS_FOUNDATION_FOUNDATIONCONTRACT_VERSION >= 0x10000 */ +#if WINDOWS_FOUNDATION_FOUNDATIONCONTRACT_VERSION >= 0x10000 #ifdef __cplusplus } /* extern "C" */ namespace ABI {
include/windows.foundation.idl | 14 +++---- tools/widl/header.c | 72 ++++++++++++++++++++++++++++++++-- tools/widl/parser.l | 1 + tools/widl/parser.y | 10 +++++ tools/widl/widltypes.h | 1 + 5 files changed, 88 insertions(+), 10 deletions(-)
diff --git a/include/windows.foundation.idl b/include/windows.foundation.idl index 2a38e9f671b..5e17062f399 100644 --- a/include/windows.foundation.idl +++ b/include/windows.foundation.idl @@ -28,7 +28,7 @@ import "windowscontracts.idl";
namespace Windows { namespace Foundation { - [version(0x06020000)] + [contract(Windows.Foundation.FoundationContract, 1.0)] enum PropertyType { Empty = 0, UInt8 = 1, @@ -73,19 +73,19 @@ namespace Windows { OtherTypeArray = 1044 };
- [version(0x06020000)] + [contract(Windows.Foundation.FoundationContract, 1.0)] struct Point { FLOAT X; FLOAT Y; };
- [version(0x06020000)] + [contract(Windows.Foundation.FoundationContract, 1.0)] struct Size { FLOAT Width; FLOAT Height; };
- [version(0x06020000)] + [contract(Windows.Foundation.FoundationContract, 1.0)] struct Rect { FLOAT X; FLOAT Y; @@ -93,18 +93,18 @@ namespace Windows { FLOAT Height; };
- [version(0x06020000)] + [contract(Windows.Foundation.FoundationContract, 1.0)] struct DateTime { INT64 UniversalTime; };
- [version(0x06020000)] + [contract(Windows.Foundation.FoundationContract, 1.0)] struct TimeSpan { INT64 Duration; };
[ - version(0x06030000), + contract(Windows.Foundation.FoundationContract, 1.0), uuid(96369f54-8eb6-48f0-abce-c1b211e627c3) ] interface IStringable : IInspectable diff --git a/tools/widl/header.c b/tools/widl/header.c index 657ce50c679..223ab5c5ca9 100644 --- a/tools/widl/header.c +++ b/tools/widl/header.c @@ -45,6 +45,11 @@ generic_handle_list_t generic_handle_list = LIST_INIT(generic_handle_list);
static void write_type_v(FILE *f, const decl_spec_t *t, int is_field, int declonly, const char *name, enum name_type name_type);
+static void write_winrt_type_comments(FILE *header, const type_t *type); + +static void write_apicontract_guard_start(FILE *header, const expr_t *expr); +static void write_apicontract_guard_end(FILE *header, const expr_t *expr); + static void indent(FILE *h, int delta) { int c; @@ -218,7 +223,9 @@ static void write_fields(FILE *h, var_list_t *fields, enum name_type name_type) }
LIST_FOR_EACH_ENTRY( v, fields, var_t, entry ) { + expr_t *contract = get_attrp(v->attrs, ATTR_CONTRACT); if (!v || !v->declspec.type) continue; + if (contract) write_apicontract_guard_start(h, contract);
indent(h, 0); name = v->name; @@ -252,6 +259,7 @@ static void write_fields(FILE *h, var_list_t *fields, enum name_type name_type) } write_type_v(h, &v->declspec, TRUE, v->declonly, name, name_type); fprintf(h, ";\n"); + if (contract) write_apicontract_guard_end(h, contract); } }
@@ -261,6 +269,8 @@ static void write_enums(FILE *h, var_list_t *enums, const char *enum_name) if (!enums) return; LIST_FOR_EACH_ENTRY( v, enums, var_t, entry ) { + expr_t *contract = get_attrp(v->attrs, ATTR_CONTRACT); + if (contract) write_apicontract_guard_start(h, contract); if (v->name) { indent(h, 0); if(!enum_name) @@ -273,8 +283,9 @@ static void write_enums(FILE *h, var_list_t *enums, const char *enum_name) } } if (list_next( enums, &v->entry )) fprintf(h, ",\n"); + else fprintf(h, "\n"); + if (contract) write_apicontract_guard_end(h, contract); } - fprintf(h, "\n"); }
int needs_space_after(type_t *t) @@ -563,7 +574,9 @@ static void write_type_definition(FILE *f, type_t *t, int declonly) int in_namespace = t->namespace && !is_global_namespace(t->namespace); int save_written = t->written; decl_spec_t ds = {.type = t}; + expr_t *contract = get_attrp(t->attrs, ATTR_CONTRACT);
+ if (contract) write_apicontract_guard_start(f, contract); if(in_namespace) { fprintf(f, "#ifdef __cplusplus\n"); fprintf(f, "} /* extern "C" */\n"); @@ -581,6 +594,7 @@ static void write_type_definition(FILE *f, type_t *t, int declonly) fprintf(f, ";\n"); fprintf(f, "#endif\n\n"); } + if (contract) write_apicontract_guard_end(f, contract); }
void write_type_decl(FILE *f, const decl_spec_t *t, const char *name) @@ -1468,12 +1482,55 @@ static char *format_apicontract_macro(const type_t *type) return name; }
+static void write_winrt_type_comments(FILE *header, const type_t *type) +{ + expr_t *contract = get_attrp(type->attrs, ATTR_CONTRACT); + fprintf(header, " *\n"); + if (contract) + { + const type_t *type = contract->u.tref.type; + char *name = format_namespace(type->namespace, "", ".", type->name, NULL); + int ver = contract->ref->u.lval; + fprintf(header, " * Introduced to %s in version %d.%d\n *\n", name, (ver >> 16) & 0xffff, ver & 0xffff); + free(name); + } +} + +static void write_apicontract_guard_start(FILE *header, const expr_t *expr) +{ + const type_t *type; + char *name; + int ver; + if (!winrt_mode) return; + type = expr->u.tref.type; + ver = expr->ref->u.lval; + name = format_apicontract_macro(type); + fprintf(header, "#if %s_VERSION >= %#x\n", name, ver); + free(name); +} + +static void write_apicontract_guard_end(FILE *header, const expr_t *expr) +{ + const type_t *type; + char *name; + int ver; + if (!winrt_mode) return; + type = expr->u.tref.type; + ver = expr->ref->u.lval; + name = format_apicontract_macro(type); + fprintf(header, "#endif /* %s_VERSION >= %#x */\n", name, ver); + free(name); +} + static void write_com_interface_start(FILE *header, const type_t *iface) { int dispinterface = is_attr(iface->attrs, ATTR_DISPINTERFACE); + expr_t *contract = get_attrp(iface->attrs, ATTR_CONTRACT); fprintf(header, "/*****************************************************************************\n"); fprintf(header, " * %s %sinterface\n", iface->name, dispinterface ? "disp" : ""); + if (winrt_mode) write_winrt_type_comments(header, iface); fprintf(header, " */\n"); + if (contract) write_apicontract_guard_start(header, contract); fprintf(header,"#ifndef __%s_%sINTERFACE_DEFINED__\n", iface->c_name, dispinterface ? "DISP" : ""); fprintf(header,"#define __%s_%sINTERFACE_DEFINED__\n\n", iface->c_name, dispinterface ? "DISP" : ""); } @@ -1482,6 +1539,7 @@ static void write_com_interface_end(FILE *header, type_t *iface) { int dispinterface = is_attr(iface->attrs, ATTR_DISPINTERFACE); const UUID *uuid = get_attrp(iface->attrs, ATTR_UUID); + expr_t *contract = get_attrp(iface->attrs, ATTR_CONTRACT); type_t *type;
if (uuid) @@ -1559,17 +1617,22 @@ static void write_com_interface_end(FILE *header, type_t *iface) write_locals(header, iface, FALSE); fprintf(header, "\n"); } - fprintf(header,"#endif /* __%s_%sINTERFACE_DEFINED__ */\n\n", iface->c_name, dispinterface ? "DISP" : ""); + fprintf(header, "#endif /* __%s_%sINTERFACE_DEFINED__ */\n", iface->c_name, dispinterface ? "DISP" : ""); + if (contract) write_apicontract_guard_end(header, contract); + fprintf(header, "\n"); }
static void write_rpc_interface_start(FILE *header, const type_t *iface) { unsigned int ver = get_attrv(iface->attrs, ATTR_VERSION); const var_t *var = get_attrp(iface->attrs, ATTR_IMPLICIT_HANDLE); + expr_t *contract = get_attrp(iface->attrs, ATTR_CONTRACT);
fprintf(header, "/*****************************************************************************\n"); fprintf(header, " * %s interface (v%d.%d)\n", iface->name, MAJORVERSION(ver), MINORVERSION(ver)); + if (winrt_mode) write_winrt_type_comments(header, iface); fprintf(header, " */\n"); + if (contract) write_apicontract_guard_start(header, contract); fprintf(header,"#ifndef __%s_INTERFACE_DEFINED__\n", iface->name); fprintf(header,"#define __%s_INTERFACE_DEFINED__\n\n", iface->name); if (var) @@ -1594,7 +1657,10 @@ static void write_rpc_interface_start(FILE *header, const type_t *iface)
static void write_rpc_interface_end(FILE *header, const type_t *iface) { - fprintf(header,"\n#endif /* __%s_INTERFACE_DEFINED__ */\n\n", iface->name); + expr_t *contract = get_attrp(iface->attrs, ATTR_CONTRACT); + fprintf(header, "\n#endif /* __%s_INTERFACE_DEFINED__ */\n", iface->name); + if (contract) write_apicontract_guard_end(header, contract); + fprintf(header, "\n"); }
static void write_coclass(FILE *header, type_t *cocl) diff --git a/tools/widl/parser.l b/tools/widl/parser.l index 6a9bb65a483..9dce03577c6 100644 --- a/tools/widl/parser.l +++ b/tools/widl/parser.l @@ -339,6 +339,7 @@ static const struct keyword attr_keywords[] = {"context_handle", tCONTEXTHANDLE, 0}, {"context_handle_noserialize", tCONTEXTHANDLENOSERIALIZE, 0}, {"context_handle_serialize", tCONTEXTHANDLENOSERIALIZE, 0}, + {"contract", tCONTRACT, 1}, {"contractversion", tCONTRACTVERSION, 1}, {"control", tCONTROL, 0}, {"custom", tCUSTOM, 0}, diff --git a/tools/widl/parser.y b/tools/widl/parser.y index 5b4bd518a0b..1d413ca74f4 100644 --- a/tools/widl/parser.y +++ b/tools/widl/parser.y @@ -181,6 +181,7 @@ static typelib_t *current_typelib; %token tCALLAS tCALLBACK tCASE tCDECL tCHAR tCOCLASS tCODE tCOMMSTATUS %token tCONST tCONTEXTHANDLE tCONTEXTHANDLENOSERIALIZE %token tCONTEXTHANDLESERIALIZE +%token tCONTRACT %token tCONTRACTVERSION %token tCONTROL tCPPQUOTE %token tCUSTOM @@ -271,6 +272,7 @@ static typelib_t *current_typelib; %type <str_list> str_list %type <expr> m_expr expr expr_const expr_int_const array m_bitfield %type <expr_list> m_exprs /* exprs expr_list */ expr_list_int_const +%type <expr> contract_req %type <type> interfacehdr %type <stgclass> storage_cls_spec %type <type_qualifier> type_qualifier m_type_qual_list @@ -508,6 +510,12 @@ contract_ver: | aNUM '.' aNUM { $$ = MAKEVERSION($3, $1); } ;
+contract_req: decl_spec ',' contract_ver { if ($1->type->type_type != TYPE_APICONTRACT) + error_loc("type %s is not an apicontract\n", $1->type->name); + $$ = make_exprl(EXPR_NUM, $3); + $$ = make_exprt(EXPR_GTREQL, declare_var(NULL, $1, make_declarator(NULL), 0), $$); + } + attribute: { $$ = NULL; } | tAGGREGATABLE { $$ = make_attr(ATTR_AGGREGATABLE); } | tANNOTATION '(' aSTRING ')' { $$ = make_attrp(ATTR_ANNOTATION, $3); } @@ -523,6 +531,7 @@ attribute: { $$ = NULL; } | tCONTEXTHANDLE { $$ = make_attrv(ATTR_CONTEXTHANDLE, 0); } | tCONTEXTHANDLENOSERIALIZE { $$ = make_attrv(ATTR_CONTEXTHANDLE, 0); /* RPC_CONTEXT_HANDLE_DONT_SERIALIZE */ } | tCONTEXTHANDLESERIALIZE { $$ = make_attrv(ATTR_CONTEXTHANDLE, 0); /* RPC_CONTEXT_HANDLE_SERIALIZE */ } + | tCONTRACT '(' contract_req ')' { $$ = make_attrp(ATTR_CONTRACT, $3); } | tCONTRACTVERSION '(' contract_ver ')' { $$ = make_attrv(ATTR_CONTRACTVERSION, $3); } | tCONTROL { $$ = make_attr(ATTR_CONTROL); } | tCUSTOM '(' uuid_string ',' expr_const ')' { $$ = make_custom_attr($3, $5); } @@ -2180,6 +2189,7 @@ struct allowed_attr allowed_attr[] = /* ATTR_CODE */ { 0, 1, 0, 1, 1, 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, "comm_status" }, /* ATTR_CONTEXTHANDLE */ { 1, 0, 0, 0, 0, 0, 1, 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, "contract" }, /* ATTR_CONTRACTVERSION */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "contractversion" }, /* ATTR_CONTROL */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, "control" }, /* ATTR_CUSTOM */ { 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, "custom" }, diff --git a/tools/widl/widltypes.h b/tools/widl/widltypes.h index 878650d9c27..d5862426ad4 100644 --- a/tools/widl/widltypes.h +++ b/tools/widl/widltypes.h @@ -84,6 +84,7 @@ enum attr_type ATTR_CODE, ATTR_COMMSTATUS, ATTR_CONTEXTHANDLE, + ATTR_CONTRACT, ATTR_CONTRACTVERSION, ATTR_CONTROL, ATTR_CUSTOM,