aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2018-11-27 10:37:20 +0000
committerEric Botcazou <ebotcazou@gcc.gnu.org>2018-11-27 10:37:20 +0000
commitda193a2713d34358d564c9fd5b5347d7bc2cc150 (patch)
tree0cb2327e80f2b6e3ed55fd667aad9beb6962e463 /gcc
parent6d760a0197ece131619ac88f0fe34ce452fd774c (diff)
downloadgcc-da193a2713d34358d564c9fd5b5347d7bc2cc150.zip
gcc-da193a2713d34358d564c9fd5b5347d7bc2cc150.tar.gz
gcc-da193a2713d34358d564c9fd5b5347d7bc2cc150.tar.bz2
c-ada-spec.c: Include stringpool.h.
* c-ada-spec.c: Include stringpool.h. (has_static_fields): Return false for incomplete types. (is_tagged_type): Likewise. (has_nontrivial_methods): Likewise. (dump_ada_node) <INTEGER_TYPE>: Deal specifically with __int128. (struct overloaded_name_hash): New structure. (struct overloaded_name_hasher): Likewise. (overloaded_names): New global variable. (init_overloaded_names): New static function. (overloaded_name_p): New predicate. (dump_ada_declaration) <TYPE_DECL>: Tidy up and set TREE_VISITED on the TYPE_STUB_DECL of the original type of a typedef, if any. <FUNCTION_DECL>: Bail out for an unsupported overloaded name. Remove always-true condition and dump forward types. (dump_ada_specs): Delete overloaded_names. From-SVN: r266506
Diffstat (limited to 'gcc')
-rw-r--r--gcc/c-family/ChangeLog18
-rw-r--r--gcc/c-family/c-ada-spec.c119
2 files changed, 117 insertions, 20 deletions
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index 6d60cf0..d993967 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,3 +1,21 @@
+2018-11-27 Eric Botcazou <ebotcazou@adacore.com>
+
+ * c-ada-spec.c: Include stringpool.h.
+ (has_static_fields): Return false for incomplete types.
+ (is_tagged_type): Likewise.
+ (has_nontrivial_methods): Likewise.
+ (dump_ada_node) <INTEGER_TYPE>: Deal specifically with __int128.
+ (struct overloaded_name_hash): New structure.
+ (struct overloaded_name_hasher): Likewise.
+ (overloaded_names): New global variable.
+ (init_overloaded_names): New static function.
+ (overloaded_name_p): New predicate.
+ (dump_ada_declaration) <TYPE_DECL>: Tidy up and set TREE_VISITED
+ on the TYPE_STUB_DECL of the original type of a typedef, if any.
+ <FUNCTION_DECL>: Bail out for an unsupported overloaded name.
+ Remove always-true condition and dump forward types.
+ (dump_ada_specs): Delete overloaded_names.
+
2018-11-20 Martin Sebor <msebor@redhat.com>
* c-attribs.c (type_for_vector_size): New function.
diff --git a/gcc/c-family/c-ada-spec.c b/gcc/c-family/c-ada-spec.c
index 2e1b91e..4e96d2a 100644
--- a/gcc/c-family/c-ada-spec.c
+++ b/gcc/c-family/c-ada-spec.c
@@ -23,6 +23,7 @@ along with GCC; see the file COPYING3. If not see
#include "system.h"
#include "coretypes.h"
#include "tm.h"
+#include "stringpool.h"
#include "tree.h"
#include "c-ada-spec.h"
#include "fold-const.h"
@@ -1041,7 +1042,7 @@ get_underlying_decl (tree type)
static bool
has_static_fields (const_tree type)
{
- if (!type || !RECORD_OR_UNION_TYPE_P (type))
+ if (!type || !RECORD_OR_UNION_TYPE_P (type) || !COMPLETE_TYPE_P (type))
return false;
for (tree fld = TYPE_FIELDS (type); fld; fld = TREE_CHAIN (fld))
@@ -1057,7 +1058,7 @@ has_static_fields (const_tree type)
static bool
is_tagged_type (const_tree type)
{
- if (!type || !RECORD_OR_UNION_TYPE_P (type))
+ if (!type || !RECORD_OR_UNION_TYPE_P (type) || !COMPLETE_TYPE_P (type))
return false;
for (tree fld = TYPE_FIELDS (type); fld; fld = TREE_CHAIN (fld))
@@ -1075,7 +1076,7 @@ is_tagged_type (const_tree type)
static bool
has_nontrivial_methods (tree type)
{
- if (!type || !RECORD_OR_UNION_TYPE_P (type))
+ if (!type || !RECORD_OR_UNION_TYPE_P (type) || !COMPLETE_TYPE_P (type))
return false;
/* Only C++ types can have methods. */
@@ -2092,7 +2093,10 @@ dump_ada_node (pretty_printer *buffer, tree node, tree type, int spc,
case INTEGER_TYPE:
case FIXED_POINT_TYPE:
case BOOLEAN_TYPE:
- if (TYPE_NAME (node))
+ if (TYPE_NAME (node)
+ && !(TREE_CODE (TYPE_NAME (node)) == TYPE_DECL
+ && !strcmp (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (node))),
+ "__int128")))
{
if (TREE_CODE (TYPE_NAME (node)) == IDENTIFIER_NODE)
pp_ada_tree_identifier (buffer, TYPE_NAME (node), node,
@@ -2568,6 +2572,73 @@ dump_nested_type (pretty_printer *buffer, tree field, tree t, tree parent,
}
}
+/* Hash table of overloaded names that we cannot support. It is needed even
+ in Ada 2012 because we merge different types, e.g. void * and const void *
+ in System.Address, so we cannot have overloading for them in Ada. */
+
+struct overloaded_name_hash {
+ hashval_t hash;
+ tree name;
+ unsigned int n;
+};
+
+struct overloaded_name_hasher : delete_ptr_hash<overloaded_name_hash>
+{
+ static inline hashval_t hash (overloaded_name_hash *t)
+ { return t->hash; }
+ static inline bool equal (overloaded_name_hash *a, overloaded_name_hash *b)
+ { return a->name == b->name; }
+};
+
+static hash_table<overloaded_name_hasher> *overloaded_names;
+
+/* Initialize the table with the problematic overloaded names. */
+
+static hash_table<overloaded_name_hasher> *
+init_overloaded_names (void)
+{
+ static const char *names[] =
+ /* The overloaded names from the /usr/include/string.h file. */
+ { "memchr", "rawmemchr", "memrchr", "strchr", "strrchr", "strchrnul",
+ "strpbrk", "strstr", "strcasestr", "index", "rindex", "basename" };
+
+ hash_table<overloaded_name_hasher> *table
+ = new hash_table<overloaded_name_hasher> (64);
+
+ for (unsigned int i = 0; i < ARRAY_SIZE (names); i++)
+ {
+ struct overloaded_name_hash in, *h, **slot;
+ tree id = get_identifier (names[i]);
+ hashval_t hash = htab_hash_pointer (id);
+ in.hash = hash;
+ in.name = id;
+ slot = table->find_slot_with_hash (&in, hash, INSERT);
+ h = new overloaded_name_hash;
+ h->hash = hash;
+ h->name = id;
+ h->n = 0;
+ *slot = h;
+ }
+
+ return table;
+}
+
+/* Return whether NAME cannot be supported as overloaded name. */
+
+static bool
+overloaded_name_p (tree name)
+{
+ if (!overloaded_names)
+ overloaded_names = init_overloaded_names ();
+
+ struct overloaded_name_hash in, *h;
+ hashval_t hash = htab_hash_pointer (name);
+ in.hash = hash;
+ in.name = name;
+ h = overloaded_names->find_with_hash (&in, hash);
+ return h && ++h->n > 1;
+}
+
/* Dump in BUFFER constructor spec corresponding to T for TYPE. */
static void
@@ -2603,7 +2674,7 @@ type_name (tree t)
return IDENTIFIER_POINTER (DECL_NAME (n));
}
-/* Dump in BUFFER the declaration of a variable T of type TYPE in Ada syntax.
+/* Dump in BUFFER the declaration of object T of type TYPE in Ada syntax.
SPC is the indentation level. Return 1 if a declaration was printed,
0 otherwise. */
@@ -2628,22 +2699,24 @@ dump_ada_declaration (pretty_printer *buffer, tree t, tree type, int spc)
{
orig = DECL_ORIGINAL_TYPE (t);
+ /* This is a typedef. */
if (orig && TYPE_STUB_DECL (orig))
{
tree stub = TYPE_STUB_DECL (orig);
- tree typ = TREE_TYPE (stub);
- if (TYPE_NAME (typ))
+ /* If this is a typedef of a named type, then output it as a subtype
+ declaration. ??? Use a derived type declaration instead. */
+ if (TYPE_NAME (orig))
{
/* If the types have the same name (ignoring casing), then ignore
the second type, but forward declare the first if need be. */
- if (type_name (typ) == type_name (TREE_TYPE (t))
- || !strcasecmp (type_name (typ), type_name (TREE_TYPE (t))))
+ if (type_name (orig) == type_name (TREE_TYPE (t))
+ || !strcasecmp (type_name (orig), type_name (TREE_TYPE (t))))
{
- if (RECORD_OR_UNION_TYPE_P (typ) && !TREE_VISITED (stub))
+ if (RECORD_OR_UNION_TYPE_P (orig) && !TREE_VISITED (stub))
{
INDENT (spc);
- dump_forward_type (buffer, typ, t, 0);
+ dump_forward_type (buffer, orig, t, 0);
}
TREE_VISITED (t) = 1;
@@ -2652,19 +2725,25 @@ dump_ada_declaration (pretty_printer *buffer, tree t, tree type, int spc)
INDENT (spc);
- if (RECORD_OR_UNION_TYPE_P (typ) && !TREE_VISITED (stub))
- dump_forward_type (buffer, typ, t, spc);
+ if (RECORD_OR_UNION_TYPE_P (orig) && !TREE_VISITED (stub))
+ dump_forward_type (buffer, orig, t, spc);
pp_string (buffer, "subtype ");
dump_ada_node (buffer, t, type, spc, false, true);
pp_string (buffer, " is ");
- dump_ada_node (buffer, typ, type, spc, false, true);
+ dump_ada_node (buffer, orig, type, spc, false, true);
pp_string (buffer, "; -- ");
dump_sloc (buffer, t);
TREE_VISITED (t) = 1;
return 1;
}
+
+ /* This is a typedef of an anonymous type. We'll output the full
+ type declaration of the anonymous type with the typedef'ed name
+ below. Prevent forward declarations for the anonymous type to
+ be emitted from now on. */
+ TREE_VISITED (stub) = 1;
}
/* Skip unnamed or anonymous structs/unions/enum types. */
@@ -2764,6 +2843,7 @@ dump_ada_declaration (pretty_printer *buffer, tree t, tree type, int spc)
default:
pp_string (buffer, "subtype ");
}
+
TREE_VISITED (t) = 1;
}
else
@@ -2825,7 +2905,7 @@ dump_ada_declaration (pretty_printer *buffer, tree t, tree type, int spc)
bool is_copy_constructor = false;
bool is_move_constructor = false;
- if (!decl_name)
+ if (!decl_name || overloaded_name_p (decl_name))
return 0;
if (cpp_check)
@@ -2863,8 +2943,9 @@ dump_ada_declaration (pretty_printer *buffer, tree t, tree type, int spc)
return 1;
}
- if (need_indent)
- INDENT (spc);
+ INDENT (spc);
+
+ dump_forward_type (buffer, TREE_TYPE (t), t, spc);
if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (t))) && !is_constructor)
pp_string (buffer, "procedure ");
@@ -2927,9 +3008,6 @@ dump_ada_declaration (pretty_printer *buffer, tree t, tree type, int spc)
bool is_interface = false;
bool is_abstract_record = false;
- if (need_indent)
- INDENT (spc);
-
/* Anonymous structs/unions. */
dump_ada_node (buffer, TREE_TYPE (t), t, spc, false, true);
@@ -3346,4 +3424,5 @@ dump_ada_specs (void (*collect_all_refs)(const char *),
/* Free various tables. */
free (source_refs);
+ delete overloaded_names;
}