From: Justin Seyster Date: Fri, 27 Aug 2010 00:00:29 +0000 (-0400) Subject: Ability to create and match struct and union types. X-Git-Tag: release-v1.0~53 X-Git-Url: https://git.fsl.cs.stonybrook.edu/?a=commitdiff_plain;h=bbcdefd6bacdb1f9cde3a0ac2d6f333031853f24;p=interaspect.git Ability to create and match struct and union types. --- diff --git a/src/aop-type.c b/src/aop-type.c index 0f7912c..0c5caff 100644 --- a/src/aop-type.c +++ b/src/aop-type.c @@ -30,6 +30,7 @@ #include #include #include +#include #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); } diff --git a/src/aop.h b/src/aop.h index 10f9f72..7536c1e 100644 --- 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);