We don't do this with classes and enums because their attributes
are part of their definitions, not something added on. */
- if (abi_version_at_least (10) && !OVERLOAD_TYPE_P (type))
+ if (!OVERLOAD_TYPE_P (type))
{
auto_vec<tree> vec;
for (tree a = TYPE_ATTRIBUTES (type); a; a = TREE_CHAIN (a))
&& !is_attribute_p ("abi_tag", name))
vec.safe_push (a);
}
- vec.qsort (attr_strcmp);
- while (!vec.is_empty())
+ if (abi_version_crosses (10) && !vec.is_empty ())
+ G.need_abi_warning = true;
+ if (abi_version_at_least (10))
{
- tree a = vec.pop();
- const attribute_spec *as
- = lookup_attribute_spec (get_attribute_name (a));
-
- write_char ('U');
- write_unsigned_number (strlen (as->name));
- write_string (as->name);
- if (TREE_VALUE (a))
+ vec.qsort (attr_strcmp);
+ while (!vec.is_empty())
{
- write_char ('I');
- for (tree args = TREE_VALUE (a); args;
- args = TREE_CHAIN (args))
+ tree a = vec.pop();
+ const attribute_spec *as
+ = lookup_attribute_spec (get_attribute_name (a));
+
+ write_char ('U');
+ write_unsigned_number (strlen (as->name));
+ write_string (as->name);
+ if (TREE_VALUE (a))
{
- tree arg = TREE_VALUE (args);
- write_template_arg (arg);
+ write_char ('I');
+ for (tree args = TREE_VALUE (a); args;
+ args = TREE_CHAIN (args))
+ {
+ tree arg = TREE_VALUE (args);
+ write_template_arg (arg);
+ }
+ write_char ('E');
}
- write_char ('E');
- }
- ++num_qualifiers;
- if (abi_version_crosses (10))
- G.need_abi_warning = true;
+ ++num_qualifiers;
+ }
}
}
--- /dev/null
+// { dg-do run { target { { i?86-*-* x86_64-*-* } && ia32 } } }
+// { dg-options "-fabi-version=8 -Wabi -save-temps" }
+// { dg-final { scan-assembler "_Z18IndirectExternCallIPFviiEiEvT_T0_S3_" } }
+
+template <typename F, typename T>
+void IndirectExternCall(F f, T t1, T t2) { // { dg-warning "mangled name" }
+ typedef F (*WrapF)(F);
+ f (t1, t2);
+}
+
+__attribute__((regparm(3), stdcall))
+void regparm_func (int i, int j)
+{
+ if (i != 24 || j != 42)
+ __builtin_abort();
+}
+
+int main()
+{
+ IndirectExternCall (regparm_func, 24, 42);
+}