case '"':
case '\'':
{
- char quote = *p;
+ char quote;
+
+ if (saw_operand)
+ goto unknown;
+ quote = *p;
*q++ = *p++;
while (*p != quote)
{
/* Global type definitions. */
htab_t type_hash;
+ /* Invalid types. */
+ htab_t invalid_hash;
+
/* Obstack used to write out a type definition. */
struct obstack type_obstack;
};
|| TREE_CODE (type) == FUNCTION_TYPE))
{
tree name;
+ void **slot;
name = TYPE_NAME (type);
- if (TREE_CODE (name) == IDENTIFIER_NODE)
- {
- obstack_1grow (ob, '_');
- go_append_string (ob, name);
- return ret;
- }
- else if (TREE_CODE (name) == TYPE_DECL)
- {
- obstack_1grow (ob, '_');
- go_append_string (ob, DECL_NAME (name));
- return ret;
- }
+ if (TREE_CODE (name) == TYPE_DECL)
+ name = DECL_NAME (name);
+
+ slot = htab_find_slot (container->invalid_hash, IDENTIFIER_POINTER (name),
+ NO_INSERT);
+ if (slot != NULL)
+ ret = false;
+
+ obstack_1grow (ob, '_');
+ go_append_string (ob, name);
+ return ret;
}
pointer_set_insert (container->decls_seen, type);
case FUNCTION_TYPE:
{
- tree args;
+ tree arg_type;
bool is_varargs;
tree result;
+ function_args_iterator iter;
+ bool seen_arg;
/* Go has no way to write a type which is a function but not a
pointer to a function. */
}
obstack_1grow (ob, '(');
- is_varargs = true;
- for (args = TYPE_ARG_TYPES (type);
- args != NULL_TREE;
- args = TREE_CHAIN (args))
+ is_varargs = stdarg_p (type);
+ seen_arg = false;
+ FOREACH_FUNCTION_ARGS (type, arg_type, iter)
{
- if (VOID_TYPE_P (TREE_VALUE (args)))
- {
- gcc_assert (TREE_CHAIN (args) == NULL);
- is_varargs = false;
- break;
- }
- if (args != TYPE_ARG_TYPES (type))
+ if (VOID_TYPE_P (arg_type))
+ break;
+ if (seen_arg)
obstack_grow (ob, ", ", 2);
- if (!go_format_type (container, TREE_VALUE (args), true, false))
+ if (!go_format_type (container, arg_type, true, false))
ret = false;
+ seen_arg = true;
}
if (is_varargs)
{
- if (TYPE_ARG_TYPES (type) != NULL_TREE)
+ if (prototype_p (type))
obstack_grow (ob, ", ", 2);
obstack_grow (ob, "...interface{}", 14);
}
for (element = TYPE_VALUES (TREE_TYPE (decl));
element != NULL_TREE;
element = TREE_CHAIN (element))
- fprintf (go_dump_file, "const _%s = " HOST_WIDE_INT_PRINT_DEC "\n",
- IDENTIFIER_POINTER (TREE_PURPOSE (element)),
- tree_low_cst (TREE_VALUE (element), 0));
+ {
+ const char *name;
+ void **slot;
+
+ name = IDENTIFIER_POINTER (TREE_PURPOSE (element));
+
+ /* Sometimes a name will be defined as both an enum constant
+ and a macro. Avoid duplicate definition errors by
+ treating enum constants as macros. */
+ slot = htab_find_slot (macro_hash, name, INSERT);
+ if (*slot == NULL)
+ {
+ *slot = CONST_CAST (char *, name);
+ fprintf (go_dump_file,
+ "const _%s = " HOST_WIDE_INT_PRINT_DEC "\n",
+ name, tree_low_cst (TREE_VALUE (element), 0));
+ }
+ }
pointer_set_insert (container->decls_seen, TREE_TYPE (decl));
if (TYPE_CANONICAL (TREE_TYPE (decl)) != NULL_TREE)
pointer_set_insert (container->decls_seen,
*slot = CONST_CAST (void *, (const void *) type);
if (!go_format_type (container, TREE_TYPE (decl), false, false))
- fprintf (go_dump_file, "// ");
+ {
+ fprintf (go_dump_file, "// ");
+ slot = htab_find_slot (container->invalid_hash, type, INSERT);
+ *slot = CONST_CAST (void *, (const void *) type);
+ }
fprintf (go_dump_file, "type _%s ",
IDENTIFIER_POINTER (DECL_NAME (decl)));
go_output_type (container);
*slot = CONST_CAST (void *, (const void *) type);
if (!go_format_type (container, TREE_TYPE (decl), false, false))
- fprintf (go_dump_file, "// ");
+ {
+ fprintf (go_dump_file, "// ");
+ slot = htab_find_slot (container->invalid_hash, type, INSERT);
+ *slot = CONST_CAST (void *, (const void *) type);
+ }
fprintf (go_dump_file, "type _%s ",
IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (decl))));
go_output_type (container);
container.pot_dummy_types = pointer_set_create ();
container.type_hash = htab_create (100, htab_hash_string,
string_hash_eq, NULL);
+ container.invalid_hash = htab_create (10, htab_hash_string,
+ string_hash_eq, NULL);
container.keyword_hash = htab_create (50, htab_hash_string,
string_hash_eq, NULL);
obstack_init (&container.type_obstack);
pointer_set_destroy (container.decls_seen);
pointer_set_destroy (container.pot_dummy_types);
htab_delete (container.type_hash);
+ htab_delete (container.invalid_hash);
htab_delete (container.keyword_hash);
obstack_free (&container.type_obstack, NULL);