===================================================================
@@ -29,6 +29,7 @@ along with GCC; see the file COPYING3.
#include "tree-pretty-print.h"
#include "tree-iterator.h"
#include "diagnostic.h"
+#include "target.h"
/* Translate if being used for diagnostics, but not for dump files or
__PRETTY_FUNCTION. */
@@ -460,6 +461,7 @@ pp_c_specifier_qualifier_list (c_pretty_
{
pp_c_whitespace (pp);
pp_c_left_paren (pp);
+ pp_c_calling_convention_attributes (pp, TYPE_ATTRIBUTES (pointee));
}
else if (!c_dialect_cxx ())
pp_c_whitespace (pp);
@@ -790,6 +792,45 @@ pp_c_attributes (c_pretty_printer *pp, t
pp_c_right_paren (pp);
}
+/* Pretty-print ATTRIBUTES using GNU C extension syntax for calling
+ convention affecting attributes. */
+
+void
+pp_c_calling_convention_attributes (c_pretty_printer *pp, tree a)
+{
+ bool is_first = true;
+
+ if (a == NULL_TREE)
+ return;
+
+ for (; a != NULL_TREE; a = TREE_CHAIN (a))
+ {
+ if (!targetm.attribute_affects_calling_convention (TREE_PURPOSE (a)))
+ continue;
+ if (is_first)
+ {
+ pp_c_ws_string (pp, "__attribute__");
+ pp_c_left_paren (pp);
+ pp_c_left_paren (pp);
+ is_first = false;
+ }
+ else
+ {
+ pp_separate_with (pp, ',');
+ }
+ pp_tree_identifier (pp, TREE_PURPOSE (a));
+ if (TREE_VALUE (a))
+ pp_c_call_argument_list (pp, TREE_VALUE (a));
+ }
+
+ if (!is_first)
+ {
+ pp_c_right_paren (pp);
+ pp_c_right_paren (pp);
+ pp_c_whitespace (pp);
+ }
+}
+
/* function-definition:
declaration-specifiers declarator compound-statement */
===================================================================
@@ -661,6 +661,8 @@ dump_type_prefix (tree t, int flags)
{
pp_cxx_whitespace (cxx_pp);
pp_cxx_left_paren (cxx_pp);
+ pp_c_calling_convention_attributes (pp_c_base (cxx_pp),
+ TYPE_ATTRIBUTES (sub));
}
if (TREE_CODE (t) == POINTER_TYPE)
pp_character(cxx_pp, '*');
===================================================================
@@ -176,6 +176,7 @@ void pp_c_space_for_pointer_operator (c_
void pp_c_tree_decl_identifier (c_pretty_printer *, tree);
void pp_c_function_definition (c_pretty_printer *, tree);
void pp_c_attributes (c_pretty_printer *, tree);
+void pp_c_calling_convention_attributes (c_pretty_printer *, tree);
void pp_c_cv_qualifiers (c_pretty_printer *pp, int qualifiers, bool func_type);
void pp_c_type_qualifier_list (c_pretty_printer *, tree);
void pp_c_parameter_type_list (c_pretty_printer *, tree);
===================================================================
@@ -5116,6 +5116,46 @@ ix86_function_ok_for_sibcall (tree decl,
return true;
}
+static bool
+ix86_attribute_affects_calling_convention (tree name)
+{
+ int ident_len;
+ const char *p;
+
+ gcc_assert (TREE_CODE (name) == IDENTIFIER_NODE);
+ p = IDENTIFIER_POINTER (name);
+ ident_len = IDENTIFIER_LENGTH (name);
+
+ if (ident_len > 4 && p[0] == '_' && p[1] == '_' && p[ident_len - 1] == '_'
+ && p[ident_len - 2] == '_')
+ {
+ ident_len -= 4;
+ p += 2;
+ }
+ switch (ident_len)
+ {
+ case 5:
+ if (!strncmp (p, "cdecl", 5))
+ return true;
+ break;
+ case 6:
+ if (!strncmp (p, "ms_abi", 6))
+ return true;
+ break;
+ case 7:
+ if (!strncmp (p, "regparm", 7) || !strncmp (p, "stdcall", 7))
+ return true;
+ break;
+ case 8:
+ if (!strncmp (p, "thiscall", 8) || !strncmp (p, "fastcall", 8)
+ || !strncmp (p, "sysv_abi", 8))
+ return true;
+ break;
+ }
+
+ return false;
+}
+
/* Handle "cdecl", "stdcall", "fastcall", "regparm", "thiscall",
and "sseregparm" calling convention attributes;
arguments as in struct attribute_spec.handler. */
@@ -34813,6 +34853,10 @@ ix86_autovectorize_vector_sizes (void)
#undef TARGET_CONDITIONAL_REGISTER_USAGE
#define TARGET_CONDITIONAL_REGISTER_USAGE ix86_conditional_register_usage
+#undef TARGET_ATTRIBUTE_AFFECTS_CALLING_CONVENTION
+#define TARGET_ATTRIBUTE_AFFECTS_CALLING_CONVENTION \
+ ix86_attribute_affects_calling_convention
+
struct gcc_target targetm = TARGET_INITIALIZER;
#include "gt-i386.h"
===================================================================
@@ -9765,6 +9765,10 @@ to perform initial processing of the @sa
@file{i386/i386.c}, for example.
@end deftypefn
+@deftypefn {Target Hook} bool TARGET_ATTRIBUTE_AFFECTS_CALLING_CONVENTION (const_tree @var{name})
+Returns @code{true} if given attribute by its @var{name} affects calling convention, otherwise @code{false}.
+@end deftypefn
+
@deftypefn {Target Hook} bool TARGET_VALID_DLLIMPORT_ATTRIBUTE_P (const_tree @var{decl})
@var{decl} is a variable or function with @code{__attribute__((dllimport))} specified. Use this hook if the target needs to add extra validation checks to @code{handle_dll_attribute}.
@end deftypefn
===================================================================
@@ -9729,6 +9729,8 @@ to perform initial processing of the @sa
@file{i386/i386.c}, for example.
@end deftypefn
+@hook TARGET_ATTRIBUTE_AFFECTS_CALLING_CONVENTION
+
@hook TARGET_VALID_DLLIMPORT_ATTRIBUTE_P
@defmac TARGET_DECLSPEC
===================================================================
@@ -1113,6 +1113,14 @@ DEFHOOK
tree, (tree olddecl, tree newdecl),
merge_decl_attributes)
+/* Return true iff attribute NAME affects calling convention. */
+DEFHOOK
+(attribute_affects_calling_convention,
+ "Returns @code{true} if given attribute by its @var{name} affects calling\
+ convention, otherwise @code{false}.",
+ bool, (const_tree name),
+ hook_bool_const_tree_false)
+
/* Given two types, merge their attributes and return the result. */
DEFHOOK
(merge_type_attributes,