aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog13
-rw-r--r--gcc/c-common.c2
-rw-r--r--gcc/config/rs6000/rs6000.c2
-rw-r--r--gcc/config/spu/spu.c2
-rw-r--r--gcc/cp/ChangeLog9
-rw-r--r--gcc/cp/cp-objcp-common.h2
-rw-r--r--gcc/cp/cp-tree.h1
-rw-r--r--gcc/cp/decl2.c63
-rw-r--r--gcc/langhooks-def.h2
-rw-r--r--gcc/langhooks.h6
-rw-r--r--gcc/testsuite/ChangeLog3
-rw-r--r--gcc/testsuite/g++.dg/ext/vector14.C17
12 files changed, 114 insertions, 8 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index c7b850a..09609f2 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,16 @@
+2008-04-24 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/35758
+ * c-common.c (handle_vector_size_attribute): Call
+ lang_hooks.types.reconstruct_complex_type instead of
+ reconstruct_complex_type.
+ * config/rs6000/rs6000.c (rs6000_handle_altivec_attribute): Likewise.
+ * config/spu/spu.c (spu_handle_vector_attribute): Likewise.
+ * langhooks.h (struct lang_hooks_for_types): Add
+ reconstruct_complex_type hook.
+ * langhooks-def.h (LANG_HOOKS_RECONSTRUCT_COMPLEX_TYPE): Define.
+ (LANG_HOOKS_FOR_TYPES_INITIALIZER): Add it.
+
2008-04-24 Richard Guenther <rguenther@suse.de>
* c-common.h (check_builtin_function_arguments): Declare.
diff --git a/gcc/c-common.c b/gcc/c-common.c
index 36e1c3d..d110b32 100644
--- a/gcc/c-common.c
+++ b/gcc/c-common.c
@@ -6170,7 +6170,7 @@ handle_vector_size_attribute (tree *node, tree name, tree args,
new_type = build_vector_type (type, nunits);
/* Build back pointers if needed. */
- *node = reconstruct_complex_type (*node, new_type);
+ *node = lang_hooks.types.reconstruct_complex_type (*node, new_type);
return NULL_TREE;
}
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 6ac9ee1..8811ea5 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -19822,7 +19822,7 @@ rs6000_handle_altivec_attribute (tree *node,
*no_add_attrs = true; /* No need to hang on to the attribute. */
if (result)
- *node = reconstruct_complex_type (*node, result);
+ *node = lang_hooks.types.reconstruct_complex_type (*node, result);
return NULL_TREE;
}
diff --git a/gcc/config/spu/spu.c b/gcc/config/spu/spu.c
index 55868ac..d37f27b 100644
--- a/gcc/config/spu/spu.c
+++ b/gcc/config/spu/spu.c
@@ -3022,7 +3022,7 @@ spu_handle_vector_attribute (tree * node, tree name,
if (!result)
warning (0, "`%s' attribute ignored", IDENTIFIER_POINTER (name));
else
- *node = reconstruct_complex_type (*node, result);
+ *node = lang_hooks.types.reconstruct_complex_type (*node, result);
return NULL_TREE;
}
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index cb7e422..9c116c3 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,12 @@
+2008-04-24 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/35758
+ * cp-tree.h (cp_reconstruct_complex_type): New prototype.
+ * cp-objcp-common.h (LANG_HOOKS_RECONSTRUCT_COMPLEX_TYPE): Define.
+ * decl2.c (is_late_template_attribute): Only make vector_size
+ late tmpl attribute if argument is type or value dependent.
+ (cp_reconstruct_complex_type): New function.
+
2008-04-24 Richard Guenther <rguenther@suse.de>
* typeck.c (cp_build_function_call): Call
diff --git a/gcc/cp/cp-objcp-common.h b/gcc/cp/cp-objcp-common.h
index a15b6b4..b2b8405 100644
--- a/gcc/cp/cp-objcp-common.h
+++ b/gcc/cp/cp-objcp-common.h
@@ -125,6 +125,8 @@ extern tree objcp_tsubst_copy_and_build (tree, tree, tsubst_flags_t,
#define LANG_HOOKS_TYPE_PROMOTES_TO cxx_type_promotes_to
#undef LANG_HOOKS_REGISTER_BUILTIN_TYPE
#define LANG_HOOKS_REGISTER_BUILTIN_TYPE c_register_builtin_type
+#undef LANG_HOOKS_RECONSTRUCT_COMPLEX_TYPE
+#define LANG_HOOKS_RECONSTRUCT_COMPLEX_TYPE cp_reconstruct_complex_type
#undef LANG_HOOKS_TO_TARGET_CHARSET
#define LANG_HOOKS_TO_TARGET_CHARSET c_common_to_target_charset
#undef LANG_HOOKS_GIMPLIFY_EXPR
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 27212c3..8d223bc 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -4282,6 +4282,7 @@ extern tree grokfield (const cp_declarator *, cp_decl_specifier_seq *,
tree, bool, tree, tree);
extern tree grokbitfield (const cp_declarator *, cp_decl_specifier_seq *,
tree);
+extern tree cp_reconstruct_complex_type (tree, tree);
extern void cplus_decl_attributes (tree *, tree, int);
extern void finish_anon_union (tree);
extern void cp_write_global_declarations (void);
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 078ca99..41af32f 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -991,11 +991,8 @@ is_late_template_attribute (tree attr, tree decl)
/* Unknown attribute. */
return false;
- /* Attribute vector_size handling wants to dive into the back end array
- building code, which breaks during template processing. */
- if (is_attribute_p ("vector_size", name)
- /* Attribute weak handling wants to write out assembly right away. */
- || is_attribute_p ("weak", name))
+ /* Attribute weak handling wants to write out assembly right away. */
+ if (is_attribute_p ("weak", name))
return true;
/* If any of the arguments are dependent expressions, we can't evaluate
@@ -1120,6 +1117,62 @@ save_template_attributes (tree *attr_p, tree *decl_p)
}
}
+/* Like reconstruct_complex_type, but handle also template trees. */
+
+tree
+cp_reconstruct_complex_type (tree type, tree bottom)
+{
+ tree inner, outer;
+
+ if (TREE_CODE (type) == POINTER_TYPE)
+ {
+ inner = cp_reconstruct_complex_type (TREE_TYPE (type), bottom);
+ outer = build_pointer_type_for_mode (inner, TYPE_MODE (type),
+ TYPE_REF_CAN_ALIAS_ALL (type));
+ }
+ else if (TREE_CODE (type) == REFERENCE_TYPE)
+ {
+ inner = cp_reconstruct_complex_type (TREE_TYPE (type), bottom);
+ outer = build_reference_type_for_mode (inner, TYPE_MODE (type),
+ TYPE_REF_CAN_ALIAS_ALL (type));
+ }
+ else if (TREE_CODE (type) == ARRAY_TYPE)
+ {
+ inner = cp_reconstruct_complex_type (TREE_TYPE (type), bottom);
+ outer = build_cplus_array_type (inner, TYPE_DOMAIN (type));
+ /* Don't call cp_build_qualified_type on ARRAY_TYPEs, the
+ element type qualification will be handled by the recursive
+ cp_reconstruct_complex_type call and cp_build_qualified_type
+ for ARRAY_TYPEs changes the element type. */
+ return outer;
+ }
+ else if (TREE_CODE (type) == FUNCTION_TYPE)
+ {
+ inner = cp_reconstruct_complex_type (TREE_TYPE (type), bottom);
+ outer = build_function_type (inner, TYPE_ARG_TYPES (type));
+ }
+ else if (TREE_CODE (type) == METHOD_TYPE)
+ {
+ inner = cp_reconstruct_complex_type (TREE_TYPE (type), bottom);
+ /* The build_method_type_directly() routine prepends 'this' to argument list,
+ so we must compensate by getting rid of it. */
+ outer
+ = build_method_type_directly
+ (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (type))),
+ inner,
+ TREE_CHAIN (TYPE_ARG_TYPES (type)));
+ }
+ else if (TREE_CODE (type) == OFFSET_TYPE)
+ {
+ inner = cp_reconstruct_complex_type (TREE_TYPE (type), bottom);
+ outer = build_offset_type (TYPE_OFFSET_BASETYPE (type), inner);
+ }
+ else
+ return bottom;
+
+ return cp_build_qualified_type (outer, TYPE_QUALS (type));
+}
+
/* Like decl_attributes, but handle C++ complexity. */
void
diff --git a/gcc/langhooks-def.h b/gcc/langhooks-def.h
index 30ff306..aae4640 100644
--- a/gcc/langhooks-def.h
+++ b/gcc/langhooks-def.h
@@ -167,6 +167,7 @@ extern tree lhd_make_node (enum tree_code);
lhd_omp_firstprivatize_type_sizes
#define LANG_HOOKS_TYPE_HASH_EQ NULL
#define LANG_HOOKS_GET_ARRAY_DESCR_INFO NULL
+#define LANG_HOOKS_RECONSTRUCT_COMPLEX_TYPE reconstruct_complex_type
#define LANG_HOOKS_HASH_TYPES true
#define LANG_HOOKS_FOR_TYPES_INITIALIZER { \
@@ -182,6 +183,7 @@ extern tree lhd_make_node (enum tree_code);
LANG_HOOKS_OMP_FIRSTPRIVATIZE_TYPE_SIZES, \
LANG_HOOKS_TYPE_HASH_EQ, \
LANG_HOOKS_GET_ARRAY_DESCR_INFO, \
+ LANG_HOOKS_RECONSTRUCT_COMPLEX_TYPE, \
LANG_HOOKS_HASH_TYPES \
}
diff --git a/gcc/langhooks.h b/gcc/langhooks.h
index b693742..6a54b01 100644
--- a/gcc/langhooks.h
+++ b/gcc/langhooks.h
@@ -130,6 +130,12 @@ struct lang_hooks_for_types
for the debugger about the array bounds, strides, etc. */
bool (*get_array_descr_info) (const_tree, struct array_descr_info *);
+ /* If we requested a pointer to a vector, build up the pointers that
+ we stripped off while looking for the inner type. Similarly for
+ return values from functions. The argument TYPE is the top of the
+ chain, and BOTTOM is the new type which we will point to. */
+ tree (*reconstruct_complex_type) (tree, tree);
+
/* Nonzero if types that are identical are to be hashed so that only
one copy is kept. If a language requires unique types for each
user-specified type, such as Ada, this should be set to TRUE. */
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 6dd1a83..002d24a 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -2,6 +2,9 @@
* gcc.dg/pr36017.c: Run on all targets, remove -lm from dg-options.
+ PR c++/35758
+ * g++.dg/ext/vector14.C: New test.
+
2008-04-24 Richard Guenther <rguenther@suse.de>
* gcc.dg/builtin-constant_p-1.c: New testcase.
diff --git a/gcc/testsuite/g++.dg/ext/vector14.C b/gcc/testsuite/g++.dg/ext/vector14.C
new file mode 100644
index 0000000..93f9e0e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/vector14.C
@@ -0,0 +1,17 @@
+// PR c++/35758
+// { dg-do compile }
+
+#define vector __attribute__((vector_size(16)))
+
+template<int N> vector signed int foo (vector float value) {}
+
+template<int> void foo (float) {}
+
+int
+main ()
+{
+ vector float v;
+ float f;
+ foo<1> (v);
+ foo<1> (f);
+}