+2004-09-21 Fariborz Jahanian <fjahanian@apple.com>
+ PR c++/13989
+ PR c++/9844
+
+ * cp/decl.c (grokfndecl): Add new argument "attrlist", use it
+ to call cplus_decl_attributes.
+ (start_function): Remove call to cplus_decl_attributes.
+ * tree.c (reconstruct_complex_type): Remove extra "this".
+ * cp/cvt.c (ocp_convert): Add support to use type conversion
+ function to vector type.
+ * cp/parser.c (cp_parser_conversion_type_id): Add attributes, if any,
+ to the parsed type.
+ * config/rs6000/rs6000.c (rs6000_handle_altivec_attribute):
+ Add V4SFmode to case statement.
+
2004-09-23 Joseph S. Myers <jsm@polyomino.org.uk>
PR c/16833
/* If the user says 'vector int bool', we may be handed the 'bool'
attribute _before_ the 'vector' attribute, and so select the proper
type in the 'b' case below. */
- case V4SImode: case V8HImode: case V16QImode: result = type;
+ case V4SImode: case V8HImode: case V16QImode: case V4SFmode: result = type;
default: break;
}
break;
if (POINTER_TYPE_P (type) || TYPE_PTR_TO_MEMBER_P (type))
return fold (cp_convert_to_pointer (type, e, false));
if (code == VECTOR_TYPE)
- return fold (convert_to_vector (type, e));
+ {
+ tree in_vtype = TREE_TYPE (e);
+ if (IS_AGGR_TYPE (in_vtype))
+ {
+ tree ret_val;
+ ret_val = build_type_conversion (type, e);
+ if (ret_val)
+ return ret_val;
+ if (flags & LOOKUP_COMPLAIN)
+ error ("`%#T' used where a `%T' was expected", in_vtype, type);
+ return error_mark_node;
+ }
+ return fold (convert_to_vector (type, e));
+ }
if (code == REAL_TYPE || code == COMPLEX_TYPE)
{
if (IS_AGGR_TYPE (TREE_TYPE (e)))
static tree grok_reference_init (tree, tree, tree, tree *);
static tree grokfndecl (tree, tree, tree, tree, tree, int,
enum overload_flags, cp_cv_quals,
- tree, int, int, int, int, int, int, tree);
+ tree, int, int, int, int, int, int, tree,
+ tree *);
static tree grokvardecl (tree, tree, const cp_decl_specifier_seq *,
int, int, tree);
static void record_unknown_type (tree, const char *);
int inlinep,
int funcdef_flag,
int template_count,
- tree in_namespace)
+ tree in_namespace,
+ tree* attrlist)
{
tree decl;
int staticp = ctype && TREE_CODE (type) == FUNCTION_TYPE;
if (decl == error_mark_node)
return NULL_TREE;
+ if (attrlist)
+ {
+ cplus_decl_attributes (&decl, *attrlist, 0);
+ *attrlist = NULL_TREE;
+ }
+
if (ctype != NULL_TREE
&& (! TYPE_FOR_JAVA (ctype) || check_java_method (decl))
&& check)
(processing_template_decl
> template_class_depth (ctype))
? current_template_parms
- : NULL_TREE);
+ : NULL_TREE);
if (old_decl && TREE_CODE (old_decl) == TEMPLATE_DECL)
/* Because grokfndecl is always supposed to return a
unqualified_id,
virtualp, flags, quals, raises,
friendp ? -1 : 0, friendp, publicp, inlinep,
- funcdef_flag, template_count, in_namespace);
+ funcdef_flag, template_count, in_namespace, attrlist);
if (decl == NULL_TREE)
return decl;
#if 0
unqualified_id,
virtualp, flags, quals, raises,
friendp ? -1 : 0, friendp, 1, 0, funcdef_flag,
- template_count, in_namespace);
+ template_count, in_namespace, attrlist);
if (decl == NULL_TREE)
return NULL_TREE;
}
virtualp, flags, quals, raises,
1, friendp,
publicp, inlinep, funcdef_flag,
- template_count, in_namespace);
+ template_count, in_namespace, attrlist);
if (decl == NULL_TREE)
return NULL_TREE;
if (decl1 == NULL_TREE || TREE_CODE (decl1) != FUNCTION_DECL)
return 0;
- cplus_decl_attributes (&decl1, attrs, 0);
-
/* If #pragma weak was used, mark the decl weak now. */
if (global_scope_p (current_binding_level))
maybe_apply_pragma_weak (decl1);
tree attributes;
cp_decl_specifier_seq type_specifiers;
cp_declarator *declarator;
+ tree type_specified;
/* Parse the attributes. */
attributes = cp_parser_attributes_opt (parser);
/* Parse the conversion-declarator. */
declarator = cp_parser_conversion_declarator_opt (parser);
- return grokdeclarator (declarator, &type_specifiers, TYPENAME,
- /*initialized=*/0, &attributes);
+ type_specified = grokdeclarator (declarator, &type_specifiers, TYPENAME,
+ /*initialized=*/0, &attributes);
+ if (attributes)
+ cplus_decl_attributes (&type_specified, attributes, /*flags=*/0);
+ return type_specified;
}
/* Parse an (optional) conversion-declarator.
--- /dev/null
+// { dg-do run }
+// PR c++/13989
+
+extern "C" void abort();
+
+#define vector __attribute__((vector_size(16)))
+
+struct Constants {
+ inline vector unsigned int deadbeef(void) const {
+ return (vector unsigned int){0xdeadbeef, 0xabababab, 0x55555555, 0x12345678};
+ };
+};
+
+inline vector unsigned int const_deadbeef(Constants &C)
+{
+ return C.deadbeef();
+}
+
+union u {
+ unsigned int f[4];
+ vector unsigned int v;
+} data;
+
+int main()
+{
+ Constants c;
+ data.v = const_deadbeef(c);
+
+ if (data.f[0] != 0xdeadbeef || data.f[1] != 0xabababab
+ || data.f[2] != 0x55555555 || data.f[3] != 0x12345678)
+ abort();
+
+ return 0;
+}
+
+
--- /dev/null
+// { dg-do run }
+// PR c++/9844
+
+extern "C" void abort();
+
+#define vector __attribute__((vector_size(16)))
+
+class vector_holder
+{
+ char __attribute__((vector_size(16))) vec;
+ char __attribute__((vector_size(16))) vec1;
+public:
+ operator __attribute__((vector_size(16))) short (void) {
+ return (__attribute__((vector_size(16))) short) vec;
+ }
+
+ operator __attribute__((vector_size(16))) int (void) {
+ return (__attribute__((vector_size(16))) int) vec1;
+ }
+
+ vector_holder () {
+ vec = (__attribute__((vector_size(16))) char) {'a', 'b', 'c', 'd', 'a', 'b', 'c', 'd',
+ 'a', 'b', 'c', 'd', 'a', 'b', 'c', 'd'};
+ vec1 = (__attribute__((vector_size(16))) char) {'m', 'n', 'o', 'q', 'm', 'n', 'o', 'p',
+ 'm', 'n', 'o', 'q', 'm', 'n', 'o', 'p'};
+ }
+};
+
+union u {
+ char f[16];
+ vector unsigned int v;
+} data;
+
+
+vector_holder vh;
+
+int main()
+{
+ data.v = (__attribute__((vector_size(16))) short) vh;
+ if (data.f[0] != 'a' || data.f[15] != 'd')
+ abort();
+ data.v = (__attribute__((vector_size(16))) int) vh;
+ if (data.f[0] != 'm' || data.f[15] != 'p')
+ abort();
+
+ return 0;
+}
--- /dev/null
+// { dg-do run }
+
+#define vector __attribute__((vector_size(16)))
+
+extern "C" void abort();
+
+class Star
+{
+ public:
+ inline vector float foo() const;
+
+ Star()
+ {
+ data.f[0] = 1.0; data.f[1] = 2.0; data.f[2] = 3.0, data.f[3] = 4.0;
+ }
+
+ private:
+ union {
+ float f[4];
+ vector float v;
+ } data;
+
+ friend vector float fTest(const Star &);
+};
+
+vector float Star::foo() const
+{
+ return data.v;
+}
+
+vector float fTest(const Star & val)
+{
+ vector float vf = val.foo();
+ return vf;
+}
+
+int main() {
+
+ Star s;
+
+ union u {
+ float f[4];
+ vector float v;
+ } data;
+
+ data.v = fTest(s);
+ for (int i=0 ; i < 4; i++)
+ if (data.f[i] != (float)(i+1))
+ abort();
+ return 0;
+}
+
+
+
+
--- /dev/null
+// { dg-do run }
+
+#define vector __attribute__((vector_size(16)))
+
+extern "C" void abort();
+
+union U {
+ float f[4];
+ vector float v;
+} data;
+
+class Star
+{
+ public:
+ static vector float foo();
+
+ Star()
+ {
+ data.f[0] = 1.0; data.f[1] = 2.0; data.f[2] = 3.0, data.f[3] = 4.0;
+ }
+
+ private:
+ friend vector float fTest();
+};
+
+vector float Star::foo()
+{
+ return data.v;
+}
+
+vector float fTest()
+{
+ vector float vf = Star::foo();
+ return vf;
+}
+
+int main() {
+
+ U data;
+ Star s;
+
+
+ data.v = fTest();
+ for (int i=0 ; i < 4; i++)
+ if (data.f[i] != (float)(i+1))
+ abort();
+ return 0;
+}
}
else if (TREE_CODE (type) == METHOD_TYPE)
{
+ tree argtypes;
inner = 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. */
+ argtypes = TYPE_ARG_TYPES (type);
outer = build_method_type_directly (TYPE_METHOD_BASETYPE (type),
inner,
TYPE_ARG_TYPES (type));
+ TYPE_ARG_TYPES (outer) = argtypes;
}
else
return bottom;