/* Process source files and output type information.
- Copyright (C) 2006-2014 Free Software Foundation, Inc.
+ Copyright (C) 2006-2020 Free Software Foundation, Inc.
This file is part of GCC.
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
-#ifdef GENERATOR_FILE
-#include "bconfig.h"
-#else
+#ifdef HOST_GENERATOR_FILE
#include "config.h"
+#define GENERATOR_FILE 1
+#else
+#include "bconfig.h"
#endif
#include "system.h"
#include "gengtype.h"
return v;
}
+/* If the next token does not have one of the codes T1, T2, T3 or T4, report a
+ parse error; otherwise return the token's value. */
+static const char *
+require4 (int t1, int t2, int t3, int t4)
+{
+ int u = token ();
+ const char *v = advance ();
+ if (u != t1 && u != t2 && u != t3 && u != t4)
+ {
+ parse_error ("expected %s, %s, %s or %s, have %s",
+ print_token (t1, 0), print_token (t2, 0),
+ print_token (t3, 0), print_token (t4, 0),
+ print_token (u, v));
+ return 0;
+ }
+ return v;
+}
+
/* Near-terminals. */
/* C-style string constant concatenation: STRING+
/* The caller has detected a template declaration that starts
with TMPL_NAME. Parse up to the closing '>'. This recognizes
- simple template declarations of the form ID<ID1,ID2,...,IDn>.
+ simple template declarations of the form ID<ID1,ID2,...,IDn>,
+ potentially with a single level of indirection e.g.
+ ID<ID1 *, ID2, ID3 *, ..., IDn>.
It does not try to parse anything more sophisticated than that.
Returns the template declaration string "ID<ID1,ID2,...,IDn>". */
require_template_declaration (const char *tmpl_name)
{
char *str;
+ int num_indirections = 0;
/* Recognize the opening '<'. */
require ('<');
str = concat (tmpl_name, "<", (char *) 0);
/* Read the comma-separated list of identifiers. */
- while (token () != '>')
+ int depth = 1;
+ while (depth > 0)
{
- const char *id = require2 (ID, ',');
+ if (token () == ENUM)
+ {
+ advance ();
+ str = concat (str, "enum ", (char *) 0);
+ continue;
+ }
+ if (token () == NUM
+ || token () == ':'
+ || token () == '+')
+ {
+ str = concat (str, advance (), (char *) 0);
+ continue;
+ }
+ if (token () == '<')
+ {
+ advance ();
+ str = concat (str, "<", (char *) 0);
+ depth += 1;
+ continue;
+ }
+ if (token () == '>')
+ {
+ advance ();
+ str = concat (str, ">", (char *) 0);
+ depth -= 1;
+ continue;
+ }
+ const char *id = require4 (SCALAR, ID, '*', ',');
if (id == NULL)
- id = ",";
+ {
+ if (T.code == '*')
+ {
+ id = "*";
+ if (num_indirections++)
+ parse_error ("only one level of indirection is supported"
+ " in template arguments");
+ }
+ else
+ id = ",";
+ }
+ else
+ num_indirections = 0;
str = concat (str, id, (char *) 0);
}
-
- /* Recognize the closing '>'. */
- require ('>');
- str = concat (str, ">", (char *) 0);
-
return str;
}
/* One GTY(()) option:
ID str_optvalue_opt
| PTR_ALIAS type_optvalue
- | PARAM_IS type_optvalue
| NESTED_PTR nestedptr_optvalue
*/
static options_p
advance ();
return type_optvalue (prev, "ptr_alias");
- case PARAM_IS:
- return type_optvalue (prev, advance ());
-
case NESTED_PTR:
advance ();
return nestedptr_optvalue (prev);
advance ();
const char *basename = require (ID);
/* This may be either an access specifier, or the base name. */
- if (0 == strcmp (basename, "public")
- || 0 == strcmp (basename, "protected")
- || 0 == strcmp (basename, "private"))
+ if (strcmp (basename, "public") == 0
+ || strcmp (basename, "protected") == 0
+ || strcmp (basename, "private") == 0)
basename = require (ID);
base_class = find_structure (basename, TYPE_STRUCT);
if (!base_class)