First of two patches for class'ized cp/parser.c|h gives limited support for gengtype to parse C++ classes and enums as first class citizens.
Patch to SVN HEAD 2012-08-30 Aaron Gray <aaronngray.li...@gmail.com> * gengtype-lex.l: Support for FILE Support for C++ single line Comments Support for classes Support for enums ignore 'static' ignore 'inline' ignore 'public:' ignore 'protected:' ignore 'private:' ignore 'friend' support for 'operator' token support for 'new' support for 'delete' added support for '+' as a token for summations in enum bodies * gengtype.h: added 'TYPE_ENUM' to 'enum typekind' added enum TYPE_ENUM to 'struct type' union added OPERATOR_KEYWORD and OPERATOR keywords to Token Code enum * gengtype-parser.c: updated 'token_names[]' (direct_declarator): support for parsing limited operators support for parsing constructors with no parameters support for parsing enums * gengtype.c: added 'type_p enums' to maintain list of enums (resolve_typedef): added support for stucture types and enums added 'new_enum()' diff --git a/gcc/gengtype-lex.l b/gcc/gengtype-lex.l index 5788a6a..af9696a 100644 --- a/gcc/gengtype-lex.l +++ b/gcc/gengtype-lex.l @@ -53,11 +53,11 @@ update_lineno (const char *l, size_t len) ID [[:alpha:]_][[:alnum:]_]* WS [[:space:]]+ HWS [ \t\r\v\f]* -IWORD short|long|(un)?signed|char|int|HOST_WIDE_INT|HOST_WIDEST_INT|bool|size_t|BOOL_BITFIELD|CPPCHAR_SIGNED_T|ino_t|dev_t|HARD_REG_SET +IWORD short|long|(un)?signed|char|int|HOST_WIDE_INT|HOST_WIDEST_INT|bool|size_t|BOOL_BITFIELD|CPPCHAR_SIGNED_T|ino_t|dev_t|HARD_REG_SET|FILE ITYPE {IWORD}({WS}{IWORD})* EOID [^[:alnum:]_] -%x in_struct in_struct_comment in_comment +%x in_struct in_struct_comment in_comment in_line_comment in_line_struct_comment %option warn noyywrap nounput nodefault perf-report %option 8bit never-interactive %% @@ -83,6 +83,14 @@ EOID [^[:alnum:]_] BEGIN(in_struct); return UNION; } +^{HWS}class/{EOID} { + BEGIN(in_struct); + return STRUCT; +} +^{HWS}enum/{EOID} { + BEGIN(in_struct); + return ENUM; +} ^{HWS}extern/{EOID} { BEGIN(in_struct); return EXTERN; @@ -101,10 +109,20 @@ EOID [^[:alnum:]_] \\\n { lexer_line.line++; } "const"/{EOID} /* don't care */ +"static"/{EOID} /* don't care */ +"inline"/{EOID} /* don't care */ +"public:" /* don't care */ +"private:" /* don't care */ +"protected:" /* don't care */ +"operator"/{EOID} { return OPERATOR_KEYWORD; } +"new"/{EOID} { *yylval = XDUPVAR (const char, yytext+1, yyleng-2, yyleng-1); return OPERATOR; } +"delete"/{EOID} { *yylval = XDUPVAR (const char, yytext+1, yyleng-2, yyleng-1); return OPERATOR; } +"friend"/{EOID} "GTY"/{EOID} { return GTY_TOKEN; } "VEC"/{EOID} { return VEC_TOKEN; } "union"/{EOID} { return UNION; } "struct"/{EOID} { return STRUCT; } +"class"/{EOID} { return CLASS; } "enum"/{EOID} { return ENUM; } "ptr_alias"/{EOID} { return PTR_ALIAS; } "nested_ptr"/{EOID} { return NESTED_PTR; } @@ -148,7 +166,7 @@ EOID [^[:alnum:]_] } "..." { return ELLIPSIS; } -[(){},*:<>;=%|-] { return yytext[0]; } +[(){},*:<>;=%|\-\+] { return yytext[0]; } /* ignore pp-directives */ ^{HWS}"#"{HWS}[a-z_]+[^\n]*\n {lexer_line.line++;} @@ -159,6 +177,7 @@ EOID [^[:alnum:]_] } "/*" { BEGIN(in_comment); } +"//" { BEGIN(in_line_comment); } \n { lexer_line.line++; } {ID} | "'"("\\".|[^\\])"'" | @@ -172,8 +191,17 @@ EOID [^[:alnum:]_] [^*\n] /* do nothing */ "*"/[^/] /* do nothing */ } + +<in_line_comment,in_line_struct_comment>{ +[^*\n]{16} | +[^*\n] /* do nothing */ +"*"/[^/] /* do nothing */ +} + <in_comment>"*/" { BEGIN(INITIAL); } <in_struct_comment>"*/" { BEGIN(in_struct); } +<in_line_comment>\n { lexer_line.line++; BEGIN(INITIAL); } +<in_line_struct_comment>\n { lexer_line.line++; BEGIN(in_struct); } ["/] | <in_struct_comment,in_comment>"*" { diff --git a/gcc/gengtype-parse.c b/gcc/gengtype-parse.c index 03ee781..663db56 100644 --- a/gcc/gengtype-parse.c +++ b/gcc/gengtype-parse.c @@ -3,7 +3,7 @@ This file is part of GCC. - GCC is free software; you can redistribute it and/or modify it under + /GCC is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. @@ -75,6 +75,7 @@ static const char *const token_names[] = { "static", "union", "struct", + "class", "enum", "VEC", "...", @@ -608,10 +609,22 @@ direct_declarator (type_p ty, const char **namep, options_p *optsp) case '(': advance (); + + if (token() == ')') + { + advance(); + return create_scalar_type ("constructor"); + } + ty = inner_declarator (ty, namep, optsp); require (')'); break; + case OPERATOR_KEYWORD: + advance(); + *namep = require (OPERATOR); + break; + default: parse_error ("expected '(', 'GTY', or an identifier, have %s", print_cur_token ()); @@ -778,6 +791,7 @@ type (options_p *optsp, bool nested) return resolve_typedef (s, &lexer_line); case STRUCT: + case CLASS: case UNION: { options_p opts = 0; @@ -923,6 +937,20 @@ struct_or_union (void) advance (); } +/* enum definition: type() does all the work. */ +static void +parse_enum (void) +{ + options_p dummy; + type (&dummy, false); + /* There may be junk after the type: notably, we cannot currently + distinguish 'struct foo *function(prototype);' from 'struct foo;' + ... we could call declarator(), but it's a waste of time at + present. Instead, just eat whatever token is currently lookahead + and go back to lexical skipping mode. */ + advance (); +} + /* GC root declaration: (extern|static) gtymarker? type ID array_declarators_opt (';'|'=') If the gtymarker is not present, we ignore the rest of the declaration. */ @@ -974,10 +1002,15 @@ parse_file (const char *fname) break; case STRUCT: + case CLASS: case UNION: struct_or_union (); break; + case ENUM: + parse_enum (); + break; + case TYPEDEF: typedef_decl (); break; diff --git a/gcc/gengtype.c b/gcc/gengtype.c index 2ae4372..2cd07fe 100644 --- a/gcc/gengtype.c +++ b/gcc/gengtype.c @@ -497,10 +497,11 @@ struct type scalar_char = { /* Lists of various things. */ -pair_p typedefs; -type_p structures; -type_p param_structs; -pair_p variables; +pair_p typedefs = NULL; +type_p structures = NULL; +type_p enums = NULL; +type_p param_structs = NULL; +pair_p variables = NULL; static type_p find_param_structure (type_p t, type_p param[NUM_PARAM]); static type_p adjust_field_tree_exp (type_p t, options_p opt); @@ -601,16 +602,93 @@ type_p resolve_typedef (const char *s, struct fileloc *pos) { pair_p p; + type_p t; + type_p e; + for (p = typedefs; p != NULL; p = p->next) if (strcmp (p->name, s) == 0) return p->type; + for (t = structures; t != NULL; t = t->next) + { + switch ( t->kind) + { + case TYPE_NONE: + if (do_debug) + fprintf(stderr, "TYPE_NONE:\n"); + break; + case TYPE_SCALAR: + if (do_debug) + fprintf(stderr, "TYPE_SCALAR:\n"); + break; + case TYPE_STRING: + if (do_debug) + fprintf(stderr, "TYPE_STRING:\n"); + break; + case TYPE_STRUCT: + if (do_debug) + fprintf(stderr, "TYPE_STRUCT: '%s'\n", t->u.s.tag); + goto structure; + case TYPE_UNION: + if (do_debug) + fprintf(stderr, "TYPE_UNION: '%s'\n", t->u.s.tag); + goto structure; + case TYPE_LANG_STRUCT: + if (do_debug) + fprintf(stderr, "TYPE_LANG_STRUCT: '%s'\n", t->u.s.tag); + structure: + if (strcmp (t->u.s.tag, s) == 0) + return t; + break; + case TYPE_POINTER: + if (do_debug) + fprintf(stderr, "TYPE_POINTER:\n"); + break; + case TYPE_ARRAY: + if (do_debug) + fprintf(stderr, "TYPE_ARRAY:\n"); + break; + case TYPE_PARAM_STRUCT: + if (do_debug) + fprintf(stderr, "TYPE_PARAM_STRUCT:\n"); + break; + default: + if (do_debug) + fprintf(stderr, "default:\n"); + break; + } + }; + + for (e = enums; e != NULL; e = e->next) + if (strcmp (e->u.e.tag, s) == 0) + return e; + /* If we did not find a typedef registered, assume this is a name for a user-defined type which will need to provide its own marking functions. */ return create_user_defined_type (s, pos); } +type_p +new_enum (const char *name) +{ + type_p ei; + type_p e; + + for (ei = enums; ei != NULL; ei = ei->next) + if (strcmp (name, ei->u.e.tag) == 0) + return ei; + + e = XCNEW (struct type); + + e->u.e.tag = name; + + e->next = enums; + enums = e; + + return e; +} + /* Create and return a new structure with tag NAME at POS with fields FIELDS and options O. The KIND of structure must be one of TYPE_STRUCT, TYPE_UNION or TYPE_USER_STRUCT. */ @@ -2450,6 +2528,7 @@ output_mangled_typename (outf_p of, const_type_p t) } break; case TYPE_ARRAY: + case TYPE_ENUM: gcc_unreachable (); } } @@ -3137,6 +3216,7 @@ write_types_process_field (type_p f, const struct walk_type_data *d) break; case TYPE_ARRAY: + case TYPE_ENUM: gcc_unreachable (); } } diff --git a/gcc/gengtype.h b/gcc/gengtype.h index 4a178ec..3d43c75 100644 --- a/gcc/gengtype.h +++ b/gcc/gengtype.h @@ -125,6 +125,7 @@ extern struct fileloc lexer_line; gengtype.c & in gengtype-state.c files. */ extern pair_p typedefs; extern type_p structures; +extern type_p enums; extern type_p param_structs; extern pair_p variables; @@ -148,9 +149,10 @@ enum typekind { param1_is, param2_is,... use_param1, use_param_2,... use_params) GTY options. */ - TYPE_USER_STRUCT /* User defined type. Walkers and markers for + TYPE_USER_STRUCT, /* User defined type. Walkers and markers for this type are assumed to be provided by the user. */ + TYPE_ENUM /* Type for enums. */ }; /* Discriminating kind for options. */ @@ -309,6 +311,11 @@ struct type { struct fileloc line; /* The source location. */ } param_struct; + /* when TYPE_ENUM */ + + struct { + const char *tag; /* the aggragate tag, if any. */ + } e; } u; }; @@ -425,6 +432,7 @@ extern type_p new_structure (const char *name, enum typekind kind, struct fileloc *pos, pair_p fields, options_p o); extern type_p find_structure (const char *s, enum typekind kind); +extern type_p new_enum (const char *name); extern type_p create_scalar_type (const char *name); extern type_p create_pointer (type_p t); extern type_p create_array (type_p t, const char *len); @@ -458,6 +466,7 @@ enum STATIC, UNION, STRUCT, + CLASS, ENUM, VEC_TOKEN, ELLIPSIS, @@ -471,6 +480,8 @@ enum STRING, CHAR, ARRAY, + OPERATOR_KEYWORD, + OPERATOR, /* print_token assumes that any token >= FIRST_TOKEN_WITH_VALUE may have a meaningful value to be printed. */
gengtype.diff
Description: Binary data