#include "function.h"
#include "basic-block.h"
#include "gimple.h"
+#include "tm.h"
/* The pretty-printer code is primarily designed to closely follow
(GNU) C and C++ grammars. That is to be contrasted with spaghetti
takes expression or declaration contexts into account. */
-#define pp_c_maybe_whitespace(PP) \
- do { \
- if ((PP)->get_padding () == pp_before) \
- pp_c_whitespace (PP); \
- } while (0)
-
/* literal */
static void pp_c_char (c_pretty_printer *, int);
pp_c_identifier (pp, name);
}
+/* Prints "[version: VERSION]" for a versioned function decl.
+ This will only print for targets with target_version semantics. */
+void
+pp_c_function_target_version (c_pretty_printer *pp, tree t)
+{
+ if (TARGET_HAS_FMV_TARGET_ATTRIBUTE)
+ return;
+
+ string_slice version = get_target_version (t);
+ if (!version.is_valid ())
+ return;
+
+ pp_c_whitespace (pp);
+
+ pp_c_left_bracket (pp);
+ pp_c_left_bracket (pp);
+ pp_string (pp, "target_version");
+ pp_c_left_paren (pp);
+ pp_doublequote (pp);
+ pp_string_n (pp, version.begin (), version.size ());
+ pp_doublequote (pp);
+ pp_c_right_paren (pp);
+ pp_c_right_bracket (pp);
+ pp_c_right_bracket (pp);
+
+ pp->set_padding (pp_before);
+}
+
+/* Prints "[clones: VERSION, +]" for a versioned function decl.
+ This only works for targets with target_version semantics. */
+void
+pp_c_function_target_clones (c_pretty_printer *pp, tree t)
+{
+ /* Only print for target_version semantics.
+ This is because for target FMV semantics a target_clone always defines
+ the entire FMV set. target_version semantics can mix target_clone and
+ target_version decls in the definition of a FMV set and so the
+ target_clone becomes a part of the identity of the declaration. */
+ if (TARGET_HAS_FMV_TARGET_ATTRIBUTE)
+ return;
+
+ auto_vec<string_slice> versions = get_clone_versions (t, NULL, false);
+ if (versions.is_empty ())
+ return;
+
+ pp_c_whitespace (pp);
+
+ string_slice final_version = versions.pop ();
+ pp_c_left_bracket (pp);
+ pp_c_left_bracket (pp);
+ pp_string (pp, "target_clones");
+ pp_c_left_paren (pp);
+ for (string_slice version : versions)
+ {
+ pp_doublequote (pp);
+ pp_string_n (pp, version.begin (), version.size ());
+ pp_doublequote (pp);
+ pp_string (pp, ",");
+ pp_c_whitespace (pp);
+ }
+ pp_doublequote (pp);
+ pp_string_n (pp, final_version.begin (), final_version.size ());
+ pp_doublequote (pp);
+ pp_c_right_paren (pp);
+ pp_c_right_bracket (pp);
+ pp_c_right_bracket (pp);
+
+ pp->set_padding (pp_before);
+}
+
#if CHECKING_P
namespace selftest {
#define pp_ptr_operator(PP, D) (PP)->ptr_operator (PP, D)
#define pp_parameter_list(PP, T) (PP)->parameter_list (PP, T)
+#define pp_c_maybe_whitespace(PP) \
+ do { \
+ if ((PP)->get_padding () == pp_before) \
+ pp_c_whitespace (PP); \
+ } while (0)
+
void pp_c_whitespace (c_pretty_printer *);
void pp_c_left_paren (c_pretty_printer *);
void pp_c_right_paren (c_pretty_printer *);
void pp_c_identifier (c_pretty_printer *, const char *);
void pp_c_string_literal (c_pretty_printer *, tree);
void pp_c_integer_constant (c_pretty_printer *, tree);
+void pp_c_function_target_version (c_pretty_printer *, tree);
+void pp_c_function_target_clones (c_pretty_printer *, tree);
void print_c_tree (FILE *file, tree t, dump_flags_t);
#include "c-tree.h"
#include "intl.h"
#include "c-family/c-pretty-print.h"
+#include "tree-core.h"
#include "tree-pretty-print.h"
#include "tree-pretty-print-markup.h"
#include "gimple-pretty-print.h"
if (DECL_NAME (t))
{
pp_identifier (cpp, lang_hooks.decl_printable_name (t, 2));
+ if (TREE_CODE (t) == FUNCTION_DECL)
+ {
+ pp_c_function_target_version (cpp, t);
+ pp_c_function_target_clones (cpp, t);
+ }
return true;
}
break;
#define pp_cxx_ws_string(PP, I) pp_c_ws_string (PP, I)
#define pp_cxx_identifier(PP, I) pp_c_identifier (PP, I)
+#define pp_cxx_maybe_whitespace(PP) pp_c_maybe_whitespace (PP)
#define pp_cxx_tree_identifier(PP, T) \
pp_c_tree_identifier (PP, T)
+#define pp_cxx_function_target_version(PP, T) \
+ pp_c_function_target_version (PP, T)
+#define pp_cxx_function_target_clones(PP, T) \
+ pp_c_function_target_clones (PP, T)
void pp_cxx_begin_template_argument_list (cxx_pretty_printer *);
void pp_cxx_end_template_argument_list (cxx_pretty_printer *);
dump_function_name (pp, t, dump_function_name_flags);
+ /* By default we need no padding here, but if we emit target_version or
+ target_clones then we need some. */
+ pp->set_padding (pp_none);
+ pp_cxx_function_target_version (pp, t);
+ pp_cxx_maybe_whitespace (pp);
+ pp_cxx_function_target_clones (pp, t);
+ pp_cxx_maybe_whitespace (pp);
+
if (!(flags & TFF_NO_FUNCTION_ARGUMENTS))
{
int const parm_flags