Add support for optional arguments and some suppport for the

defaultvalue attributes.
Better calculation of the typeinfo's res3 member (at least for
interfaces).
This commit is contained in:
Huw Davies 2005-01-10 14:22:24 +00:00 committed by Alexandre Julliard
parent c2ccf0f48c
commit a3026ca8f9
3 changed files with 89 additions and 26 deletions

View File

@ -350,8 +350,8 @@ attribute:
| tCONTEXTHANDLESERIALIZE { $$ = make_attrv(ATTR_CONTEXTHANDLE, 0); /* RPC_CONTEXT_HANDLE_SERIALIZE */ } | tCONTEXTHANDLESERIALIZE { $$ = make_attrv(ATTR_CONTEXTHANDLE, 0); /* RPC_CONTEXT_HANDLE_SERIALIZE */ }
| tCONTROL { $$ = make_attr(ATTR_CONTROL); } | tCONTROL { $$ = make_attr(ATTR_CONTROL); }
| tDEFAULT { $$ = make_attr(ATTR_DEFAULT); } | tDEFAULT { $$ = make_attr(ATTR_DEFAULT); }
| tDEFAULTVALUE '(' expr_const ')' { $$ = make_attrp(ATTR_DEFAULTVALUE, $3); } | tDEFAULTVALUE '(' expr_const ')' { $$ = make_attrp(ATTR_DEFAULTVALUE_EXPR, $3); }
| tDEFAULTVALUE '(' aSTRING ')' { $$ = make_attrp(ATTR_DEFAULTVALUE, $3); } | tDEFAULTVALUE '(' aSTRING ')' { $$ = make_attrp(ATTR_DEFAULTVALUE_STRING, $3); }
| tDLLNAME '(' aSTRING ')' { $$ = make_attrp(ATTR_DLLNAME, $3); } | tDLLNAME '(' aSTRING ')' { $$ = make_attrp(ATTR_DLLNAME, $3); }
| tDUAL { $$ = make_attr(ATTR_DUAL); } | tDUAL { $$ = make_attr(ATTR_DUAL); }
| tENDPOINT '(' aSTRING ')' { $$ = make_attrp(ATTR_ENDPOINT, $3); } | tENDPOINT '(' aSTRING ')' { $$ = make_attrp(ATTR_ENDPOINT, $3); }

View File

@ -62,7 +62,8 @@ enum attr_type
ATTR_CONTEXTHANDLE, ATTR_CONTEXTHANDLE,
ATTR_CONTROL, ATTR_CONTROL,
ATTR_DEFAULT, ATTR_DEFAULT,
ATTR_DEFAULTVALUE, ATTR_DEFAULTVALUE_EXPR,
ATTR_DEFAULTVALUE_STRING,
ATTR_DLLNAME, ATTR_DLLNAME,
ATTR_DUAL, ATTR_DUAL,
ATTR_ENDPOINT, ATTR_ENDPOINT,

View File

@ -648,9 +648,9 @@ static int ctl2_alloc_importfile(
/**************************************************************************** /****************************************************************************
* ctl2_encode_typedesc * ctl2_encode_type
* *
* Encodes a type description, storing information in the TYPEDESC and ARRAYDESC * Encodes a type, storing information in the TYPEDESC and ARRAYDESC
* segments as needed. * segments as needed.
* *
* RETURNS * RETURNS
@ -927,13 +927,53 @@ static int ctl2_find_nth_reference(
} }
static void write_value(msft_typeinfo_t* typeinfo, int *out, var_t *arg, int type, void *value)
{
int vt = (type >> 16) & 0x1ff;
switch(vt) {
case VT_I2:
case VT_I4:
case VT_R4:
case VT_BOOL:
case VT_I1:
case VT_UI1:
case VT_UI2:
case VT_UI4:
case VT_INT:
case VT_UINT:
case VT_HRESULT:
{
unsigned long *lv = value;
if((*lv & 0x3ffffff) == *lv) {
*out = 0x80000000;
*out |= vt << 26;
*out |= *lv;
} else {
int offset = ctl2_alloc_segment(typeinfo->typelib, MSFT_SEG_CUSTDATA, 8, 0);
*((unsigned short *)&typeinfo->typelib->typelib_segment_data[MSFT_SEG_CUSTDATA][offset]) = vt;
memcpy(&typeinfo->typelib->typelib_segment_data[MSFT_SEG_CUSTDATA][offset+2], value, 4);
*((unsigned short *)&typeinfo->typelib->typelib_segment_data[MSFT_SEG_CUSTDATA][offset+6]) = 0x5757;
*out = offset;
}
return;
}
case VT_BSTR:
warning("default value BSTR %s\n", (char*)value);
break;
default:
warning("can't write value of type %d yet\n", vt);
}
return;
}
static HRESULT add_func_desc(msft_typeinfo_t* typeinfo, func_t *func) static HRESULT add_func_desc(msft_typeinfo_t* typeinfo, func_t *func)
{ {
int offset; int offset;
int *typedata; int *typedata;
int i, index = func->idx, id; int i, index = func->idx, id;
int decoded_size; int decoded_size;
int num_params = 0; int num_params = 0, num_defaults = 0;
var_t *arg, *last_arg = NULL; var_t *arg, *last_arg = NULL;
char *namedata; char *namedata;
attr_t *attr; attr_t *attr;
@ -951,6 +991,12 @@ static HRESULT add_func_desc(msft_typeinfo_t* typeinfo, func_t *func)
for(arg = func->args; arg; arg = NEXT_LINK(arg)) { for(arg = func->args; arg; arg = NEXT_LINK(arg)) {
last_arg = arg; last_arg = arg;
num_params++; num_params++;
for(attr = arg->attrs; attr; attr = NEXT_LINK(attr)) {
if(attr->type == ATTR_DEFAULTVALUE_EXPR || attr->type == ATTR_DEFAULTVALUE_STRING) {
num_defaults++;
break;
}
}
} }
chat("num of params %d\n", num_params); chat("num of params %d\n", num_params);
@ -973,30 +1019,56 @@ static HRESULT add_func_desc(msft_typeinfo_t* typeinfo, func_t *func)
} }
/* allocate type data space for us */ /* allocate type data space for us */
offset = typeinfo->typedata[0]; offset = typeinfo->typedata[0];
typeinfo->typedata[0] += 0x18 + (num_params * 12); typeinfo->typedata[0] += 0x18 + (num_params * (num_defaults ? 16 : 12));
typedata = typeinfo->typedata + (offset >> 2) + 1; typedata = typeinfo->typedata + (offset >> 2) + 1;
/* fill out the basic type information */ /* fill out the basic type information */
typedata[0] = (0x18 + (num_params * 12)) | (index << 16); typedata[0] = (0x18 + (num_params * (num_defaults ? 16 : 12))) | (index << 16);
ctl2_encode_type(typeinfo->typelib, func->def->type, func->def->ptr_level, func->def->array, &typedata[1], NULL, NULL, &decoded_size); ctl2_encode_type(typeinfo->typelib, func->def->type, func->def->ptr_level, func->def->array, &typedata[1], NULL, NULL, &decoded_size);
typedata[2] = funcflags; typedata[2] = funcflags;
typedata[3] = ((52 /*sizeof(FUNCDESC)*/ + decoded_size) << 16) | typeinfo->typeinfo->cbSizeVft; typedata[3] = ((52 /*sizeof(FUNCDESC)*/ + decoded_size) << 16) | typeinfo->typeinfo->cbSizeVft;
typedata[4] = (index << 16) | (callconv << 8) | 9; typedata[4] = (index << 16) | (callconv << 8) | 9;
if(num_defaults) typedata[4] |= 0x10;
typedata[5] = num_params; typedata[5] = num_params;
/* NOTE: High word of typedata[3] is total size of FUNCDESC + size of all ELEMDESCs for params + TYPEDESCs for pointer params and return types. */ /* NOTE: High word of typedata[3] is total size of FUNCDESC + size of all ELEMDESCs for params + TYPEDESCs for pointer params and return types. */
/* That is, total memory allocation required to reconstitute the FUNCDESC in its entirety. */ /* That is, total memory allocation required to reconstitute the FUNCDESC in its entirety. */
typedata[3] += (16 /*sizeof(ELEMDESC)*/ * num_params) << 16; typedata[3] += (16 /*sizeof(ELEMDESC)*/ * num_params) << 16;
typedata[3] += (24 /*sizeof(PARAMDESCEX)*/ * num_defaults) << 16;
for (arg = last_arg, i = 0; arg; arg = PREV_LINK(arg), i++) { for (arg = last_arg, i = 0; arg; arg = PREV_LINK(arg), i++) {
attr_t *attr; attr_t *attr;
int paramflags = 0; int paramflags = 0;
int *paramdata = typedata + 6 + (num_defaults ? num_params : 0) + i * 3;
int *defaultdata = num_defaults ? typedata + 6 + i : NULL;
if(defaultdata) *defaultdata = -1;
ctl2_encode_type(typeinfo->typelib, arg->type, arg->ptr_level, arg->array, paramdata, NULL, NULL, &decoded_size);
for(attr = arg->attrs; attr; attr = NEXT_LINK(attr)) { for(attr = arg->attrs; attr; attr = NEXT_LINK(attr)) {
switch(attr->type) { switch(attr->type) {
case ATTR_DEFAULTVALUE_EXPR:
{
expr_t *expr = (expr_t *)attr->u.pval;
paramflags |= 0x30; /* PARAMFLAG_FHASDEFAULT | PARAMFLAG_FOPT */
chat("default value %ld\n", expr->cval);
write_value(typeinfo, defaultdata, arg, *paramdata, &expr->cval);
break;
}
case ATTR_DEFAULTVALUE_STRING:
{
char *s = (char *)attr->u.pval;
paramflags |= 0x30; /* PARAMFLAG_FHASDEFAULT | PARAMFLAG_FOPT */
chat("default value '%s'\n", s);
write_value(typeinfo, defaultdata, arg, *paramdata, s);
break;
}
case ATTR_IN: case ATTR_IN:
paramflags |= 0x01; /* PARAMFLAG_FIN */ paramflags |= 0x01; /* PARAMFLAG_FIN */
break; break;
case ATTR_OPTIONAL:
paramflags |= 0x10; /* PARAMFLAG_FOPT */
break;
case ATTR_OUT: case ATTR_OUT:
paramflags |= 0x02; /* PARAMFLAG_FOUT */ paramflags |= 0x02; /* PARAMFLAG_FOUT */
break; break;
@ -1008,17 +1080,9 @@ static HRESULT add_func_desc(msft_typeinfo_t* typeinfo, func_t *func)
break; break;
} }
} }
ctl2_encode_type(typeinfo->typelib, arg->type, arg->ptr_level, arg->array, &typedata[6+(i*3)], NULL, NULL, &decoded_size); paramdata[1] = -1;
typedata[7+(i*3)] = -1; paramdata[2] = paramflags;
typedata[8+(i*3)] = paramflags;
typedata[3] += decoded_size << 16; typedata[3] += decoded_size << 16;
#if 0
/* FIXME: Doesn't work. Doesn't even come up with usable VTs for varDefaultValue. */
if (pFuncDesc->lprgelemdescParam[i].u.paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT) {
ctl2_alloc_custdata(This->typelib, &pFuncDesc->lprgelemdescParam[i].u.paramdesc.pparamdescex->varDefaultValue);
}
#endif
} }
/* update the index data */ /* update the index data */
@ -1029,14 +1093,12 @@ static HRESULT add_func_desc(msft_typeinfo_t* typeinfo, func_t *func)
/* ??? */ /* ??? */
if (!typeinfo->typeinfo->res2) typeinfo->typeinfo->res2 = 0x20; if (!typeinfo->typeinfo->res2) typeinfo->typeinfo->res2 = 0x20;
typeinfo->typeinfo->res2 <<= 1; typeinfo->typeinfo->res2 <<= 1;
/* ??? */
if (typeinfo->typeinfo->res3 == -1) typeinfo->typeinfo->res3 = 0;
typeinfo->typeinfo->res3 += 0x38;
/* ??? */ /* ??? */
if (index < 2) typeinfo->typeinfo->res2 += num_params << 4; if (index < 2) typeinfo->typeinfo->res2 += num_params << 4;
typeinfo->typeinfo->res3 += num_params << 4;
if (typeinfo->typeinfo->res3 == -1) typeinfo->typeinfo->res3 = 0;
typeinfo->typeinfo->res3 += 0x38 + num_params * 0x10;
if(num_defaults) typeinfo->typeinfo->res3 += num_params * 0x4;
/* adjust size of VTBL */ /* adjust size of VTBL */
typeinfo->typeinfo->cbSizeVft += 4; typeinfo->typeinfo->cbSizeVft += 4;
@ -1058,9 +1120,9 @@ static HRESULT add_func_desc(msft_typeinfo_t* typeinfo, func_t *func)
for (arg = last_arg, i = 0; arg; arg = PREV_LINK(arg), i++) { for (arg = last_arg, i = 0; arg; arg = PREV_LINK(arg), i++) {
/* FIXME: Almost certainly easy to break */ /* FIXME: Almost certainly easy to break */
int *paramdata = &typeinfo->typedata[typeinfo->offsets[index] >> 2]; int *paramdata = &typeinfo->typedata[typeinfo->offsets[index] >> 2];
paramdata += 7 + (num_defaults ? num_params : 0) + i * 3;
offset = ctl2_alloc_name(typeinfo->typelib, arg->name); offset = ctl2_alloc_name(typeinfo->typelib, arg->name);
paramdata[(i * 3) + 8] = offset; paramdata[1] = offset;
chat("param %d name %s offset %d\n", i, arg->name, offset); chat("param %d name %s offset %d\n", i, arg->name, offset);
} }
return S_OK; return S_OK;