Ability to create and match struct and union types.
authorJustin Seyster <jseyster@cs.sunysb.edu>
Fri, 27 Aug 2010 00:00:29 +0000 (20:00 -0400)
committerJustin Seyster <jseyster@cs.sunysb.edu>
Fri, 27 Aug 2010 00:00:29 +0000 (20:00 -0400)
src/aop-type.c
src/aop.h

index 0f7912cec5676517f368caad73503d1eec33c08c..0c5caffc46e456499f3093017b873fefb416d7c6 100644 (file)
@@ -30,6 +30,7 @@
 #include <tm.h>
 #include <tree.h>
 #include <hashtab.h>
+#include <toplev.h>
 
 #include "aop.h"
 #include "aop-type.h"
@@ -254,6 +255,21 @@ get_dedup_type (struct aop_type *type)
   return *type_slot;
 }
 
+/* Return a deduplicated pointer to an aop_type object.  The pointer
+   is valid for the rest of the compiler's execution. */
+static const struct aop_type *
+init_aop_type (enum aop_tykind kind, int pointer_levels, const char *tag,
+              int size)
+{
+  struct aop_type type;
+  type.kind = kind;
+  type.pointer_levels = pointer_levels;
+  type.tag = tag;
+  type.size = size;
+
+  return get_dedup_type (&type);
+}
+
 void
 init_type_table ()
 {
@@ -497,6 +513,26 @@ aop_t_float128 ()
   return &_aop_t_float128;
 }
 
+const struct aop_type *
+aop_t_struct (const char *tag)
+{
+  if (tag == NULL)
+    fatal_error ("(InterAspect) Must supply a non-NULL tag when specifying a"
+                " struct type.");
+
+  return init_aop_type (ATK_STRUCT, 0, tag, -1);
+}
+
+const struct aop_type *
+aop_t_union (const char *tag)
+{
+  if (tag == NULL)
+    fatal_error ("(InterAspect) Must supply a non-NULL tag when specifying a"
+                " union type.");
+
+  return init_aop_type (ATK_UNION, 0, tag, -1);
+}
+
 /**
  * Return a type that will match pointers to the specified type.
  *
@@ -542,6 +578,35 @@ is_all_fp_type (const struct aop_type *type)
          && type->size <= 0);
 }
 
+/* Given a type node, get that type node's identifier. */
+static tree
+get_type_identifier (tree gcc_type)
+{
+  tree type_name = TYPE_NAME (gcc_type);
+
+  /* On rare occasion, TYPE_NAME() mysteriously gives us a TYPE_DECL
+     instead of the IDENTIFIER_NODE we really wanted for Christmas.
+     Documentation in tree.h promises that you can use
+     DECL_ORIGINAL_TYPE to get through to the _actual_ type, which has
+     the real IDENTIFIER_NODE.*/
+  while (type_name != NULL && TREE_CODE (type_name) == TYPE_DECL)
+    if (DECL_ORIGINAL_TYPE (type_name) != NULL)
+      type_name = TYPE_NAME (DECL_ORIGINAL_TYPE (type_name));
+    else
+      type_name = NULL;
+  gcc_assert(type_name == NULL || TREE_CODE (type_name) == IDENTIFIER_NODE);
+  return type_name;
+}
+
+/* Given a type node, get that type node's name, or NULL if it has no
+   name. */
+static const char *
+get_type_name (tree gcc_type)
+{
+  tree type_name = get_type_identifier (gcc_type);
+  return (type_name != NULL) ? IDENTIFIER_POINTER (type_name) : NULL;
+}
+
 static bool
 does_int_type_match (tree gcc_type, enum aop_tykind kind, int aop_size)
 {
@@ -592,6 +657,23 @@ does_fp_type_match (tree gcc_type, int aop_size)
     }
 }
 
+static bool
+does_custom_type_match (tree gcc_type, enum aop_tykind kind, const char *tag)
+{
+  aop_assert (kind == ATK_STRUCT || kind == ATK_UNION);
+
+  if ((kind == ATK_STRUCT && TREE_CODE (gcc_type) == RECORD_TYPE)
+      || (kind == ATK_UNION && TREE_CODE (gcc_type) == UNION_TYPE))
+    {
+      aop_assert (tag != NULL);
+      return safe_str_equal (tag, get_type_name (gcc_type));
+    }
+  else
+    {
+      return false;
+    }
+}
+
 /* Match an actual GCC type with an AOP type specification. */
 bool
 does_type_match (tree gcc_type, const struct aop_type *aop_type)
@@ -620,6 +702,9 @@ does_type_match (tree gcc_type, const struct aop_type *aop_type)
       return does_int_type_match (gcc_type, aop_type->kind, aop_type->size);
     case ATK_FP:
       return does_fp_type_match (gcc_type, aop_type->size);
+    case ATK_STRUCT:
+    case ATK_UNION:
+      return does_custom_type_match (gcc_type, aop_type->kind, aop_type->tag);
     default:
       aop_assert (0);
     }
index 10f9f72a3e63f7485139f2eaa83f5af766b2baf3..7536c1e98ca64a7555685bf313cc766f35902005 100644 (file)
--- a/src/aop.h
+++ b/src/aop.h
@@ -180,6 +180,8 @@ extern const struct aop_type *aop_t_unsigned128 ();
 extern const struct aop_type *aop_t_float32 ();
 extern const struct aop_type *aop_t_float64 ();
 extern const struct aop_type *aop_t_float128 ();
+extern const struct aop_type *aop_t_struct (const char *tag);
+extern const struct aop_type *aop_t_union (const char *tag);
 extern const struct aop_type *aop_t_pointer_to (const struct aop_type *type);
 
 extern void aop_register_pass (const char *pass_name, pass_callback callback);