Commit 34e2f87f authored by Ove Kaaven's avatar Ove Kaaven Committed by Alexandre Julliard

Handle encapsulated unions in a cleaner (and less buggy) way. Emit the

names "DUMMYUNIONNAME" and "DUMMYSTRUCTNAME" for anonymous unions and structs. Support const and extern definitions. Retain tokens (and whether numbers are hex or not) used for computing constant expressions, so that the full expression can be written to the header file instead of the computed integer result of the expression. Parse the sizeof() operator. Compute and remember constant definitions and enum values so they can be used in expressions. Improved identifier lookup speed. Fixed some bugs.
parent 75e9c468
......@@ -78,8 +78,8 @@ static void write_array(FILE *h, expr_t *v)
while (NEXT_LINK(v)) v = NEXT_LINK(v);
fprintf(h, "[");
while (v) {
if (v->type == EXPR_NUM)
fprintf(h, "%ld", v->u.lval); /* statically sized array */
if (v->is_const)
fprintf(h, "%ld", v->cval); /* statically sized array */
else
fprintf(h, "1"); /* dynamically sized array */
if (PREV_LINK(v))
......@@ -99,6 +99,21 @@ static void write_field(FILE *h, var_t *v)
fprintf(h, " ");
write_pident(h, v);
}
else {
/* not all C/C++ compilers support anonymous structs and unions */
switch (v->type->type) {
case RPC_FC_STRUCT:
case RPC_FC_ENCAPSULATED_UNION:
fprintf(h, " DUMMYSTRUCTNAME");
break;
case RPC_FC_NON_ENCAPSULATED_UNION:
fprintf(h, " DUMMYUNIONNAME");
break;
default:
/* ? */
break;
}
}
write_array(h, v->array);
fprintf(h, ";\n");
}
......@@ -124,8 +139,10 @@ static void write_enums(FILE *h, var_t *v)
if (get_name(v)) {
indent(0);
write_name(h, v);
if (v->has_val)
fprintf(h, " = %ld", v->lval);
if (v->eval) {
fprintf(h, " = ");
write_expr(h, v->eval);
}
}
if (PREV_LINK(v))
fprintf(h, ",\n");
......@@ -181,6 +198,7 @@ void write_type(FILE *h, type_t *t, var_t *v, char *n)
if (t->defined && !t->written) {
if (t->name) fprintf(h, "enum %s {\n", t->name);
else fprintf(h, "enum {\n");
t->written = TRUE;
indentation++;
write_enums(h, t->fields);
indent(-1);
......@@ -189,29 +207,13 @@ void write_type(FILE *h, type_t *t, var_t *v, char *n)
else fprintf(h, "enum %s", t->name);
break;
case RPC_FC_STRUCT:
if (t->defined && !t->written) {
if (t->name) fprintf(h, "struct %s {\n", t->name);
else fprintf(h, "struct {\n");
indentation++;
write_fields(h, t->fields);
indent(-1);
fprintf(h, "}");
}
else fprintf(h, "struct %s", t->name);
break;
case RPC_FC_ENCAPSULATED_UNION:
if (t->defined && !t->written) {
var_t *d = t->fields;
if (t->name) fprintf(h, "struct %s {\n", t->name);
else fprintf(h, "struct {\n");
t->written = TRUE;
indentation++;
write_field(h, d);
indent(0);
fprintf(h, "union {\n");
indentation++;
write_fields(h, NEXT_LINK(d));
indent(-1);
fprintf(h, "} u;\n");
write_fields(h, t->fields);
indent(-1);
fprintf(h, "}");
}
......@@ -221,6 +223,7 @@ void write_type(FILE *h, type_t *t, var_t *v, char *n)
if (t->defined && !t->written) {
if (t->name) fprintf(h, "union %s {\n", t->name);
else fprintf(h, "union {\n");
t->written = TRUE;
indentation++;
write_fields(h, t->fields);
indent(-1);
......@@ -262,6 +265,89 @@ void write_typedef(type_t *type, var_t *names)
fprintf(header, ";\n\n");
}
static void do_write_expr(FILE *h, expr_t *e, int p)
{
switch (e->type) {
case EXPR_VOID:
break;
case EXPR_NUM:
fprintf(h, "%ld", e->u.lval);
break;
case EXPR_HEXNUM:
fprintf(h, "0x%lx", e->u.lval);
break;
case EXPR_IDENTIFIER:
fprintf(h, "%s", e->u.sval);
break;
case EXPR_NEG:
fprintf(h, "-");
do_write_expr(h, e->ref, 1);
break;
case EXPR_PPTR:
fprintf(h, "*");
do_write_expr(h, e->ref, 1);
break;
case EXPR_CAST:
fprintf(h, "(");
write_type(h, e->u.tref->ref, NULL, e->u.tref->name);
fprintf(h, ")");
do_write_expr(h, e->ref, 1);
break;
case EXPR_SIZEOF:
fprintf(h, "sizeof(");
write_type(h, e->u.tref->ref, NULL, e->u.tref->name);
fprintf(h, ")");
break;
case EXPR_SHL:
case EXPR_SHR:
case EXPR_MUL:
case EXPR_DIV:
case EXPR_ADD:
case EXPR_SUB:
case EXPR_AND:
case EXPR_OR:
if (p) fprintf(h, "(");
do_write_expr(h, e->ref, 1);
switch (e->type) {
case EXPR_SHL: fprintf(h, " << "); break;
case EXPR_SHR: fprintf(h, " >> "); break;
case EXPR_MUL: fprintf(h, " * "); break;
case EXPR_DIV: fprintf(h, " / "); break;
case EXPR_ADD: fprintf(h, " + "); break;
case EXPR_SUB: fprintf(h, " - "); break;
case EXPR_AND: fprintf(h, " & "); break;
case EXPR_OR: fprintf(h, " | "); break;
default: break;
}
do_write_expr(h, e->u.ext, 1);
if (p) fprintf(h, ")");
break;
}
}
void write_expr(FILE *h, expr_t *e)
{
do_write_expr(h, e, 0);
}
void write_constdef(var_t *v)
{
fprintf(header, "#define %s (", get_name(v));
write_expr(header, v->eval);
fprintf(header, ")\n\n");
}
void write_externdef(var_t *v)
{
fprintf(header, "extern const ");
write_type(header, v->type, NULL, v->tname);
if (get_name(v)) {
fprintf(header, " ");
write_pident(header, v);
}
fprintf(header, ";\n\n");
}
/********** INTERFACES **********/
uuid_t *get_uuid(attr_t *a)
......
......@@ -32,5 +32,8 @@ extern void write_method_args(FILE *h, var_t *arg, char *name);
extern void write_forward(type_t *iface);
extern void write_interface(type_t *iface);
extern void write_typedef(type_t *type, var_t *names);
extern void write_expr(FILE *h, expr_t *e);
extern void write_constdef(var_t *v);
extern void write_externdef(var_t *v);
#endif
......@@ -31,7 +31,7 @@ extern int yy_flex_debug;
int yylex(void);
extern int import_stack_ptr;
void do_import(char *fname);
int do_import(char *fname);
void abort_import(void);
#define parse_only import_stack_ptr
......
......@@ -118,7 +118,10 @@ static uuid_t* parse_uuid(const char*u)
yylval.uuid = parse_uuid(yytext);
return aUUID;
}
{hex} |
{hex} {
yylval.num = strtol(yytext, NULL, 0);
return aHEXNUM;
}
{int} {
yylval.num = strtol(yytext, NULL, 0);
return aNUM;
......@@ -145,7 +148,7 @@ int yywrap(void)
}
#endif
static struct {
static struct keyword {
const char *kw;
int token;
int val;
......@@ -241,16 +244,34 @@ static struct {
{"version", tVERSION},
{"void", tVOID},
{"wchar_t", tWCHAR},
{"wire_marshal", tWIREMARSHAL},
{NULL}
{"wire_marshal", tWIREMARSHAL}
};
#define NKEYWORDS (sizeof(keywords)/sizeof(keywords[0]))
#define KWP(p) ((struct keyword *)(p))
static int kw_cmp_func(const void *s1, const void *s2)
{
return strcmp(KWP(s1)->kw, KWP(s2)->kw);
}
#define KW_BSEARCH
static int kw_token(const char *kw)
{
int i;
for (i=0; keywords[i].kw; i++)
if (strcmp(kw, keywords[i].kw) == 0)
return keywords[i].token;
struct keyword key, *kwp;
key.kw = kw;
#ifdef KW_BSEARCH
kwp = bsearch(&key, keywords, NKEYWORDS, sizeof(keywords[0]), kw_cmp_func);
#else
{
int i;
for (kwp=NULL, i=0; i < NKEYWORDS; i++)
if (!kw_cmp_func(&key, &keywords[i])) {
kwp = &keywords[i];
break;
}
}
#endif
if (kwp) return kwp->token;
yylval.str = xstrdup(kw);
return is_type(kw) ? aKNOWNTYPE : aIDENTIFIER;
}
......@@ -293,7 +314,7 @@ struct imports {
struct imports *next;
} *first_import;
void do_import(char *fname)
int do_import(char *fname)
{
FILE *f;
char *hname, *path;
......@@ -312,7 +333,7 @@ void do_import(char *fname)
import = first_import;
while (import && strcmp(import->name, fname))
import = import->next;
if (import) return; /* already imported */
if (import) return 0; /* already imported */
import = xmalloc(sizeof(struct imports));
import->name = xstrdup(fname);
......@@ -334,6 +355,7 @@ void do_import(char *fname)
import_stack[ptr].state = YY_CURRENT_BUFFER;
yy_switch_to_buffer(yy_create_buffer(f, YY_BUF_SIZE));
return 1;
}
void abort_import(void)
......
......@@ -67,10 +67,12 @@ enum expr_type
{
EXPR_VOID,
EXPR_NUM,
EXPR_HEXNUM,
EXPR_IDENTIFIER,
EXPR_NEG,
EXPR_PPTR,
EXPR_CAST,
EXPR_SIZEOF,
EXPR_SHL,
EXPR_SHR,
EXPR_MUL,
......@@ -98,7 +100,10 @@ struct _expr_t {
long lval;
char *sval;
expr_t *ext;
typeref_t *tref;
} u;
int is_const;
long cval;
/* parser-internal */
DECL_LINK(expr_t)
};
......@@ -131,7 +136,7 @@ struct _var_t {
type_t *type;
char *tname;
attr_t *attrs;
int has_val;
expr_t *eval;
long lval;
/* parser-internal */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment