Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
77228b52
Commit
77228b52
authored
Jan 06, 2009
by
Rob Shearman
Committed by
Alexandre Julliard
Jan 07, 2009
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
widl: Determine the type of an array entirely at code generation time instead of at parse time.
Previously, this was done partially (for fixed array types only).
parent
2b698132
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
138 additions
and
75 deletions
+138
-75
header.c
tools/widl/header.c
+7
-11
parser.y
tools/widl/parser.y
+40
-40
typegen.c
tools/widl/typegen.c
+70
-24
typelib.c
tools/widl/typelib.c
+5
-0
typetree.c
tools/widl/typetree.c
+14
-0
typetree.h
tools/widl/typetree.h
+2
-0
No files found.
tools/widl/header.c
View file @
77228b52
...
@@ -116,9 +116,7 @@ int is_void(const type_t *t)
...
@@ -116,9 +116,7 @@ int is_void(const type_t *t)
int
is_conformant_array
(
const
type_t
*
t
)
int
is_conformant_array
(
const
type_t
*
t
)
{
{
return
t
->
type
==
RPC_FC_CARRAY
return
is_array
(
t
)
&&
type_array_has_conformance
(
t
);
||
t
->
type
==
RPC_FC_CVARRAY
||
(
t
->
type
==
RPC_FC_BOGUS_ARRAY
&&
type_array_has_conformance
(
t
));
}
}
void
write_guid
(
FILE
*
f
,
const
char
*
guid_prefix
,
const
char
*
name
,
const
UUID
*
uuid
)
void
write_guid
(
FILE
*
f
,
const
char
*
guid_prefix
,
const
char
*
name
,
const
UUID
*
uuid
)
...
@@ -186,7 +184,7 @@ static void write_enums(FILE *h, var_list_t *enums)
...
@@ -186,7 +184,7 @@ static void write_enums(FILE *h, var_list_t *enums)
int
needs_space_after
(
type_t
*
t
)
int
needs_space_after
(
type_t
*
t
)
{
{
return
(
type_is_alias
(
t
)
||
return
(
type_is_alias
(
t
)
||
(
!
is_ptr
(
t
)
&&
(
!
is_conformant_array
(
t
)
||
t
->
declarray
)));
(
!
is_ptr
(
t
)
&&
(
!
is_conformant_array
(
t
)
||
t
->
declarray
||
(
is_array
(
t
)
&&
t
->
name
)
)));
}
}
void
write_type_left
(
FILE
*
h
,
type_t
*
t
,
int
declonly
)
void
write_type_left
(
FILE
*
h
,
type_t
*
t
,
int
declonly
)
...
@@ -202,7 +200,11 @@ void write_type_left(FILE *h, type_t *t, int declonly)
...
@@ -202,7 +200,11 @@ void write_type_left(FILE *h, type_t *t, int declonly)
else
{
else
{
if
(
t
->
sign
>
0
)
fprintf
(
h
,
"signed "
);
if
(
t
->
sign
>
0
)
fprintf
(
h
,
"signed "
);
else
if
(
t
->
sign
<
0
)
fprintf
(
h
,
"unsigned "
);
else
if
(
t
->
sign
<
0
)
fprintf
(
h
,
"unsigned "
);
switch
(
t
->
type
)
{
if
(
is_array
(
t
)
&&
!
t
->
name
)
{
write_type_left
(
h
,
type_array_get_element
(
t
),
declonly
);
fprintf
(
h
,
"%s*"
,
needs_space_after
(
type_array_get_element
(
t
))
?
" "
:
""
);
}
else
switch
(
t
->
type
)
{
case
RPC_FC_ENUM16
:
case
RPC_FC_ENUM16
:
case
RPC_FC_ENUM32
:
case
RPC_FC_ENUM32
:
if
(
!
declonly
&&
t
->
defined
&&
!
t
->
written
)
{
if
(
!
declonly
&&
t
->
defined
&&
!
t
->
written
)
{
...
@@ -257,12 +259,6 @@ void write_type_left(FILE *h, type_t *t, int declonly)
...
@@ -257,12 +259,6 @@ void write_type_left(FILE *h, type_t *t, int declonly)
fprintf
(
h
,
"%s*"
,
needs_space_after
(
type_pointer_get_ref
(
t
))
?
" "
:
""
);
fprintf
(
h
,
"%s*"
,
needs_space_after
(
type_pointer_get_ref
(
t
))
?
" "
:
""
);
if
(
is_attr
(
t
->
attrs
,
ATTR_CONST
))
fprintf
(
h
,
"const "
);
if
(
is_attr
(
t
->
attrs
,
ATTR_CONST
))
fprintf
(
h
,
"const "
);
break
;
break
;
case
RPC_FC_CARRAY
:
case
RPC_FC_CVARRAY
:
case
RPC_FC_BOGUS_ARRAY
:
write_type_left
(
h
,
type_array_get_element
(
t
),
declonly
);
fprintf
(
h
,
"%s*"
,
needs_space_after
(
type_array_get_element
(
t
))
?
" "
:
""
);
break
;
default:
default:
fprintf
(
h
,
"%s"
,
t
->
name
);
fprintf
(
h
,
"%s"
,
t
->
name
);
}
}
...
...
tools/widl/parser.y
View file @
77228b52
...
@@ -1404,9 +1404,9 @@ static void set_type(var_t *v, decl_spec_t *decl_spec, const declarator_t *decl,
...
@@ -1404,9 +1404,9 @@ static void set_type(var_t *v, decl_spec_t *decl_spec, const declarator_t *decl,
{
{
expr_list_t *sizes = get_attrp(v->attrs, ATTR_SIZEIS);
expr_list_t *sizes = get_attrp(v->attrs, ATTR_SIZEIS);
expr_list_t *lengs = get_attrp(v->attrs, ATTR_LENGTHIS);
expr_list_t *lengs = get_attrp(v->attrs, ATTR_LENGTHIS);
int sizeless
, has_varconf
;
int sizeless;
expr_t *dim;
expr_t *dim;
type_t *
atype, *
*ptype;
type_t **ptype;
array_dims_t *arr = decl ? decl->array : NULL;
array_dims_t *arr = decl ? decl->array : NULL;
type_t *func_type = decl ? decl->func_type : NULL;
type_t *func_type = decl ? decl->func_type : NULL;
type_t *type = decl_spec->type;
type_t *type = decl_spec->type;
...
@@ -1469,6 +1469,7 @@ static void set_type(var_t *v, decl_spec_t *decl_spec, const declarator_t *decl,
...
@@ -1469,6 +1469,7 @@ static void set_type(var_t *v, decl_spec_t *decl_spec, const declarator_t *decl,
error_loc("'%s': [v1_enum] attribute applied to non-enum type\n", v->name);
error_loc("'%s': [v1_enum] attribute applied to non-enum type\n", v->name);
}
}
ptype = &v->type;
sizeless = FALSE;
sizeless = FALSE;
if (arr) LIST_FOR_EACH_ENTRY_REV(dim, arr, expr_t, entry)
if (arr) LIST_FOR_EACH_ENTRY_REV(dim, arr, expr_t, entry)
{
{
...
@@ -1477,35 +1478,46 @@ static void set_type(var_t *v, decl_spec_t *decl_spec, const declarator_t *decl,
...
@@ -1477,35 +1478,46 @@ static void set_type(var_t *v, decl_spec_t *decl_spec, const declarator_t *decl,
if (dim->is_const)
if (dim->is_const)
{
{
v->type = make_type(RPC_FC_LGFARRAY, v->type);
if (dim->cval <= 0)
error_loc("%s: array dimension must be positive\n", v->name);
/* FIXME: should use a type_memsize that allows us to pass in a pointer size */
if (0)
{
unsigned int align = 0;
size_t size = type_memsize(v->type, &align);
if (0xffffffffuL / size < (unsigned long) dim->cval)
error_loc("%s: total array size is too large\n", v->name);
}
}
}
else
else
{
sizeless = TRUE;
sizeless = TRUE;
v->type = make_type(RPC_FC_CARRAY, v->type);
}
v->type->declarray = TRUE;
*ptype = type_new_array(NULL, *ptype, TRUE,
v->type->details.array.dim = dim->cval;
dim->is_const ? dim->cval : 0,
dim->is_const ? NULL : dim, NULL);
}
}
ptype = &v->type;
ptype = &v->type;
has_varconf = FALSE;
if (sizes) LIST_FOR_EACH_ENTRY(dim, sizes, expr_t, entry)
if (sizes) LIST_FOR_EACH_ENTRY(dim, sizes, expr_t, entry)
{
{
if (dim->type != EXPR_VOID)
if (dim->type != EXPR_VOID)
{
{
has_varconf = TRUE;
if (is_array(*ptype))
atype = *ptype = duptype(*ptype, 0);
{
if (type_array_get_conformance(*ptype)->is_const)
if (atype->type == RPC_FC_SMFARRAY || atype->type == RPC_FC_LGFARRAY)
error_loc("%s: cannot specify size_is for a fixed sized array\n", v->name);
error_loc("%s: cannot specify size_is for a fixed sized array\n", v->name);
else
*ptype = type_new_array((*ptype)->name,
if (atype->type != RPC_FC_CARRAY && !is_ptr(atype))
type_array_get_element(*ptype), TRUE,
0, dim, NULL);
}
else if (is_ptr(*ptype))
*ptype = type_new_array((*ptype)->name, type_pointer_get_ref(*ptype), FALSE,
0, dim, NULL);
else
error_loc("%s: size_is attribute applied to illegal type\n", v->name);
error_loc("%s: size_is attribute applied to illegal type\n", v->name);
atype->type = RPC_FC_CARRAY;
atype->details.array.size_is = dim;
}
}
ptype = &(*ptype)->ref;
ptype = &(*ptype)->ref;
...
@@ -1518,19 +1530,17 @@ static void set_type(var_t *v, decl_spec_t *decl_spec, const declarator_t *decl,
...
@@ -1518,19 +1530,17 @@ static void set_type(var_t *v, decl_spec_t *decl_spec, const declarator_t *decl,
{
{
if (dim->type != EXPR_VOID)
if (dim->type != EXPR_VOID)
{
{
has_varconf = TRUE;
if (is_array(*ptype))
atype = *ptype = duptype(*ptype, 0);
{
*ptype = type_new_array((*ptype)->name,
if (atype->type == RPC_FC_SMFARRAY)
type_array_get_element(*ptype),
atype->type = RPC_FC_SMVARRAY;
(*ptype)->declarray,
else if (atype->type == RPC_FC_LGFARRAY)
type_array_get_dim(*ptype),
atype->type = RPC_FC_LGVARRAY;
type_array_get_conformance(*ptype),
else if (atype->type == RPC_FC_CARRAY)
dim);
atype->type = RPC_FC_CVARRAY;
}
else
else
error_loc("%s: length_is attribute applied to illegal type\n", v->name);
error_loc("%s: length_is attribute applied to illegal type\n", v->name);
atype->details.array.length_is = dim;
}
}
ptype = &(*ptype)->ref;
ptype = &(*ptype)->ref;
...
@@ -1538,16 +1548,6 @@ static void set_type(var_t *v, decl_spec_t *decl_spec, const declarator_t *decl,
...
@@ -1538,16 +1548,6 @@ static void set_type(var_t *v, decl_spec_t *decl_spec, const declarator_t *decl,
error_loc("%s: too many expressions in length_is attribute\n", v->name);
error_loc("%s: too many expressions in length_is attribute\n", v->name);
}
}
if (has_varconf && !last_array(v->type))
{
ptype = &v->type;
for (ptype = &v->type; is_array(*ptype); ptype = &(*ptype)->ref)
{
*ptype = duptype(*ptype, 0);
(*ptype)->type = RPC_FC_BOGUS_ARRAY;
}
}
/* v->type is currently pointing to the type on the left-side of the
/* v->type is currently pointing to the type on the left-side of the
* declaration, so we need to fix this up so that it is the return type of the
* declaration, so we need to fix this up so that it is the return type of the
* function and make v->type point to the function side of the declaration */
* function and make v->type point to the function side of the declaration */
...
...
tools/widl/typegen.c
View file @
77228b52
...
@@ -120,6 +120,15 @@ const char *string_of_type(unsigned char type)
...
@@ -120,6 +120,15 @@ const char *string_of_type(unsigned char type)
}
}
}
}
static
unsigned
char
get_pointer_fc
(
const
type_t
*
type
)
{
assert
(
is_ptr
(
type
));
/* FIXME: see corresponding hack in set_type - we shouldn't be getting
* the pointer type from an alias, rather determining it from the
* position */
return
type
->
type
;
}
static
int
get_struct_type
(
const
type_t
*
type
)
static
int
get_struct_type
(
const
type_t
*
type
)
{
{
int
has_pointer
=
0
;
int
has_pointer
=
0
;
...
@@ -210,6 +219,10 @@ static int get_struct_type(const type_t *type)
...
@@ -210,6 +219,10 @@ static int get_struct_type(const type_t *type)
has_pointer
=
1
;
has_pointer
=
1
;
break
;
break
;
case
RPC_FC_SMFARRAY
:
case
RPC_FC_LGFARRAY
:
case
RPC_FC_SMVARRAY
:
case
RPC_FC_LGVARRAY
:
case
RPC_FC_CARRAY
:
case
RPC_FC_CARRAY
:
case
RPC_FC_CVARRAY
:
case
RPC_FC_CVARRAY
:
case
RPC_FC_BOGUS_ARRAY
:
case
RPC_FC_BOGUS_ARRAY
:
...
@@ -281,37 +294,70 @@ static int get_struct_type(const type_t *type)
...
@@ -281,37 +294,70 @@ static int get_struct_type(const type_t *type)
return
RPC_FC_STRUCT
;
return
RPC_FC_STRUCT
;
}
}
static
int
get_array_type
(
const
type_t
*
type
)
static
unsigned
char
get_array_type
(
const
type_t
*
type
)
{
{
if
(
is_array
(
type
))
unsigned
char
fc
;
const
expr_t
*
size_is
;
const
type_t
*
elem_type
;
if
(
!
is_array
(
type
))
return
type
->
type
;
elem_type
=
type_array_get_element
(
type
);
size_is
=
type_array_get_conformance
(
type
);
if
(
!
size_is
)
{
{
const
type_t
*
rt
=
type_array_get_element
(
type
);
unsigned
int
align
=
0
;
if
(
is_user_type
(
rt
))
size_t
size
=
type_memsize
(
elem_type
,
&
align
);
return
RPC_FC_BOGUS_ARRAY
;
if
(
size
*
type_array_get_dim
(
type
)
>
0xffffuL
)
switch
(
get_struct_type
(
rt
))
fc
=
RPC_FC_LGFARRAY
;
else
fc
=
RPC_FC_SMFARRAY
;
}
else
fc
=
RPC_FC_CARRAY
;
if
(
type_array_has_variance
(
type
))
{
if
(
fc
==
RPC_FC_SMFARRAY
)
fc
=
RPC_FC_SMVARRAY
;
else
if
(
fc
==
RPC_FC_LGFARRAY
)
fc
=
RPC_FC_LGVARRAY
;
else
if
(
fc
==
RPC_FC_CARRAY
)
fc
=
RPC_FC_CVARRAY
;
}
if
(
is_user_type
(
elem_type
))
fc
=
RPC_FC_BOGUS_ARRAY
;
else
if
(
is_struct
(
elem_type
->
type
))
{
switch
(
get_struct_type
(
elem_type
))
{
{
case
RPC_FC_BOGUS_STRUCT
:
case
RPC_FC_BOGUS_STRUCT
:
case
RPC_FC_NON_ENCAPSULATED_UNION
:
fc
=
RPC_FC_BOGUS_ARRAY
;
case
RPC_FC_ENCAPSULATED_UNION
:
case
RPC_FC_ENUM16
:
return
RPC_FC_BOGUS_ARRAY
;
/* FC_RP should be above, but widl overuses these, and will break things. */
case
RPC_FC_UP
:
case
RPC_FC_RP
:
if
(
type_pointer_get_ref
(
rt
)
->
type
==
RPC_FC_IP
)
return
RPC_FC_BOGUS_ARRAY
;
break
;
break
;
}
}
if
(
type
->
type
==
RPC_FC_LGFARRAY
||
type
->
type
==
RPC_FC_LGVARRAY
)
{
unsigned
int
align
=
0
;
size_t
size
=
type_memsize
(
type
,
&
align
);
if
(
size
*
type_array_get_dim
(
type
)
<=
0xffff
)
return
(
type
->
type
==
RPC_FC_LGFARRAY
)
?
RPC_FC_SMFARRAY
:
RPC_FC_SMVARRAY
;
}
}
}
return
type
->
type
;
else
if
(
elem_type
->
type
==
RPC_FC_ENUM16
)
{
/* is 16-bit enum - if so, wire size differs from mem size and so
* the array cannot be block copied, which means the array is complex */
fc
=
RPC_FC_BOGUS_ARRAY
;
}
else
if
(
is_union
(
elem_type
->
type
))
fc
=
RPC_FC_BOGUS_ARRAY
;
else
if
(
is_ptr
(
elem_type
))
{
/* ref pointers cannot just be block copied. unique pointers to
* interfaces need special treatment. either case means the array is
* complex */
if
(
get_pointer_fc
(
elem_type
)
==
RPC_FC_RP
||
type_pointer_get_ref
(
elem_type
)
->
type
==
RPC_FC_IP
)
fc
=
RPC_FC_BOGUS_ARRAY
;
}
return
fc
;
}
}
int
is_struct
(
unsigned
char
type
)
int
is_struct
(
unsigned
char
type
)
...
...
tools/widl/typelib.c
View file @
77228b52
...
@@ -190,8 +190,13 @@ unsigned short get_type_vt(type_t *t)
...
@@ -190,8 +190,13 @@ unsigned short get_type_vt(type_t *t)
case
RPC_FC_UP
:
case
RPC_FC_UP
:
case
RPC_FC_OP
:
case
RPC_FC_OP
:
case
RPC_FC_FP
:
case
RPC_FC_FP
:
case
RPC_FC_SMFARRAY
:
case
RPC_FC_LGFARRAY
:
case
RPC_FC_SMVARRAY
:
case
RPC_FC_LGVARRAY
:
case
RPC_FC_CARRAY
:
case
RPC_FC_CARRAY
:
case
RPC_FC_CVARRAY
:
case
RPC_FC_CVARRAY
:
case
RPC_FC_BOGUS_ARRAY
:
if
(
t
->
ref
)
if
(
t
->
ref
)
{
{
if
(
match
(
t
->
ref
->
name
,
"SAFEARRAY"
))
if
(
match
(
t
->
ref
->
name
,
"SAFEARRAY"
))
...
...
tools/widl/typetree.c
View file @
77228b52
...
@@ -78,6 +78,20 @@ type_t *type_new_module(char *name)
...
@@ -78,6 +78,20 @@ type_t *type_new_module(char *name)
return
type
;
return
type
;
}
}
type_t
*
type_new_array
(
const
char
*
name
,
type_t
*
element
,
int
declarray
,
unsigned
long
dim
,
expr_t
*
size_is
,
expr_t
*
length_is
)
{
type_t
*
t
=
make_type
(
RPC_FC_LGFARRAY
,
element
);
if
(
name
)
t
->
name
=
xstrdup
(
name
);
t
->
declarray
=
declarray
;
t
->
details
.
array
.
length_is
=
length_is
;
if
(
size_is
)
t
->
details
.
array
.
size_is
=
size_is
;
else
t
->
details
.
array
.
dim
=
dim
;
return
t
;
}
static
int
compute_method_indexes
(
type_t
*
iface
)
static
int
compute_method_indexes
(
type_t
*
iface
)
{
{
int
idx
;
int
idx
;
...
...
tools/widl/typetree.h
View file @
77228b52
...
@@ -28,6 +28,8 @@ type_t *type_new_function(var_list_t *args);
...
@@ -28,6 +28,8 @@ type_t *type_new_function(var_list_t *args);
type_t
*
type_new_pointer
(
type_t
*
ref
,
attr_list_t
*
attrs
);
type_t
*
type_new_pointer
(
type_t
*
ref
,
attr_list_t
*
attrs
);
type_t
*
type_new_alias
(
type_t
*
t
,
const
char
*
name
);
type_t
*
type_new_alias
(
type_t
*
t
,
const
char
*
name
);
type_t
*
type_new_module
(
char
*
name
);
type_t
*
type_new_module
(
char
*
name
);
type_t
*
type_new_array
(
const
char
*
name
,
type_t
*
element
,
int
declarray
,
unsigned
long
dim
,
expr_t
*
size_is
,
expr_t
*
length_is
);
void
type_interface_define
(
type_t
*
iface
,
type_t
*
inherit
,
statement_list_t
*
stmts
);
void
type_interface_define
(
type_t
*
iface
,
type_t
*
inherit
,
statement_list_t
*
stmts
);
void
type_dispinterface_define
(
type_t
*
iface
,
var_list_t
*
props
,
func_list_t
*
methods
);
void
type_dispinterface_define
(
type_t
*
iface
,
var_list_t
*
props
,
func_list_t
*
methods
);
void
type_dispinterface_define_from_iface
(
type_t
*
dispiface
,
type_t
*
iface
);
void
type_dispinterface_define_from_iface
(
type_t
*
dispiface
,
type_t
*
iface
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment