/* Implementation of subroutines for the GNU C++ pretty-printer.
- Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+ Copyright (C) 2003, 2004, 2005, 2007, 2008,
+ 2009, 2010 Free Software Foundation, Inc.
Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net>
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2, or (at your option) any later
+Software Foundation; either version 3, or (at your option) any later
version.
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
for more details.
You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING. If not, write to the Free
-Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-02111-1307, USA. */
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
-#include "real.h"
-#include "cxx-pretty-print.h"
+#include "intl.h"
#include "cp-tree.h"
+#include "cxx-pretty-print.h"
+#include "tree-pretty-print.h"
#include "toplev.h"
+/* Translate if being used for diagnostics, but not for dump files or
+ __PRETTY_FUNCTION. */
+#define M_(msgid) (pp_translate_identifiers (pp) ? _(msgid) : (msgid))
+
static void pp_cxx_unqualified_id (cxx_pretty_printer *, tree);
static void pp_cxx_nested_name_specifier (cxx_pretty_printer *, tree);
static void pp_cxx_qualified_id (cxx_pretty_printer *, tree);
static void pp_cxx_declarator (cxx_pretty_printer *, tree);
static void pp_cxx_parameter_declaration_clause (cxx_pretty_printer *, tree);
static void pp_cxx_abstract_declarator (cxx_pretty_printer *, tree);
+static void pp_cxx_statement (cxx_pretty_printer *, tree);
static void pp_cxx_template_parameter (cxx_pretty_printer *, tree);
+static void pp_cxx_cast_expression (cxx_pretty_printer *, tree);
+static void pp_cxx_typeid_expression (cxx_pretty_printer *, tree);
\f
static inline void
static inline void
pp_cxx_conversion_function_id (cxx_pretty_printer *pp, tree t)
{
- pp_cxx_identifier (pp, "operator");
+ pp_cxx_ws_string (pp, "operator");
pp_cxx_type_specifier_seq (pp, TREE_TYPE (t));
}
pp_cxx_end_template_argument_list (pp);
}
-/* unqualified-id:
+/* Prints the unqualified part of the id-expression T.
+
+ unqualified-id:
identifier
operator-function-id
conversion-function-id
switch (code)
{
case RESULT_DECL:
- pp_cxx_identifier (pp, "<return-value>");
+ pp_cxx_ws_string (pp, M_("<return-value>"));
break;
case OVERLOAD:
- t = OVL_CURRENT (t);
+ t = OVL_CURRENT (t);
case VAR_DECL:
case PARM_DECL:
case CONST_DECL:
case USING_DECL:
case TEMPLATE_DECL:
t = DECL_NAME (t);
-
+
case IDENTIFIER_NODE:
if (t == NULL)
- pp_cxx_identifier (pp, "<unnamed>");
+ pp_cxx_ws_string (pp, M_("<unnamed>"));
else if (IDENTIFIER_TYPENAME_P (t))
- pp_cxx_conversion_function_id (pp, t);
+ pp_cxx_conversion_function_id (pp, t);
else
- {
- if (is_destructor_name (t))
- {
- pp_complement (pp);
- /* FIXME: Why is this necessary? */
- if (TREE_TYPE (t))
- t = constructor_name (TREE_TYPE (t));
- }
- pp_cxx_tree_identifier (pp, t);
- }
+ {
+ if (is_destructor_name (t))
+ {
+ pp_complement (pp);
+ /* FIXME: Why is this necessary? */
+ if (TREE_TYPE (t))
+ t = constructor_name (TREE_TYPE (t));
+ }
+ pp_cxx_tree_identifier (pp, t);
+ }
break;
case TEMPLATE_ID_EXPR:
pp_cxx_template_id (pp, t);
break;
+ case BASELINK:
+ pp_cxx_unqualified_id (pp, BASELINK_FUNCTIONS (t));
+ break;
+
case RECORD_TYPE:
case UNION_TYPE:
case ENUMERAL_TYPE:
+ case TYPENAME_TYPE:
+ case UNBOUND_CLASS_TEMPLATE:
pp_cxx_unqualified_id (pp, TYPE_NAME (t));
+ if (CLASS_TYPE_P (t) && CLASSTYPE_USE_TEMPLATE (t))
+ {
+ pp_cxx_begin_template_argument_list (pp);
+ pp_cxx_template_argument_list (pp, INNERMOST_TEMPLATE_ARGS
+ (CLASSTYPE_TI_ARGS (t)));
+ pp_cxx_end_template_argument_list (pp);
+ }
+ break;
+
+ case BIT_NOT_EXPR:
+ pp_cxx_complement (pp);
+ pp_cxx_unqualified_id (pp, TREE_OPERAND (t, 0));
break;
case TEMPLATE_TYPE_PARM:
case TEMPLATE_TEMPLATE_PARM:
if (TYPE_IDENTIFIER (t))
- pp_cxx_unqualified_id (pp, TYPE_IDENTIFIER (t));
+ pp_cxx_unqualified_id (pp, TYPE_IDENTIFIER (t));
else
- pp_cxx_canonical_template_parameter (pp, t);
+ pp_cxx_canonical_template_parameter (pp, t);
break;
case TEMPLATE_PARM_INDEX:
pp_cxx_unqualified_id (pp, TEMPLATE_PARM_DECL (t));
break;
+ case BOUND_TEMPLATE_TEMPLATE_PARM:
+ pp_cxx_cv_qualifier_seq (pp, t);
+ pp_cxx_unqualified_id (pp, TYPE_IDENTIFIER (t));
+ pp_cxx_begin_template_argument_list (pp);
+ pp_cxx_template_argument_list (pp, TYPE_TI_ARGS (t));
+ pp_cxx_end_template_argument_list (pp);
+ break;
+
default:
pp_unsupported_tree (pp, t);
break;
{
if (TREE_CODE (t) == TEMPLATE_ID_EXPR
&& TYPE_P (scope) && dependent_type_p (scope))
- pp_cxx_identifier (pp, "template");
+ pp_cxx_ws_string (pp, "template");
}
/* nested-name-specifier:
break;
/* In Standard C++, functions cannot possibly be used as
- nested-name-specifiers. However, there are situations where
- is "makes sense" to output the surrounding function name for the
- purpose of emphasizing on the scope kind. Just printing the
- function name might not be sufficient as it may be overloaded; so,
- we decorate the function with its signature too.
- FIXME: This is probably the wrong pretty-printing for conversion
- functions and some function templates. */
+ nested-name-specifiers. However, there are situations where
+ is "makes sense" to output the surrounding function name for the
+ purpose of emphasizing on the scope kind. Just printing the
+ function name might not be sufficient as it may be overloaded; so,
+ we decorate the function with its signature too.
+ FIXME: This is probably the wrong pretty-printing for conversion
+ functions and some function templates. */
case OVERLOAD:
t = OVL_CURRENT (t);
case FUNCTION_DECL:
if (DECL_FUNCTION_MEMBER_P (t))
- pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
+ pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
pp_cxx_unqualified_id
- (pp, DECL_CONSTRUCTOR_P (t) ? DECL_CONTEXT (t) : t);
+ (pp, DECL_CONSTRUCTOR_P (t) ? DECL_CONTEXT (t) : t);
pp_cxx_parameter_declaration_clause (pp, TREE_TYPE (t));
break;
default:
{
- tree scope = TYPE_P (t) ? TYPE_CONTEXT (t) : DECL_CONTEXT (t);
- if (scope != pp->enclosing_scope)
- {
- pp_cxx_nested_name_specifier (pp, scope);
- pp_cxx_template_keyword_if_needed (pp, scope, t);
- }
- pp_cxx_unqualified_id (pp, t);
+ tree scope = TYPE_P (t) ? TYPE_CONTEXT (t) : DECL_CONTEXT (t);
+ if (scope != pp->enclosing_scope)
+ {
+ pp_cxx_nested_name_specifier (pp, scope);
+ pp_cxx_template_keyword_if_needed (pp, scope, t);
+ }
+ pp_cxx_unqualified_id (pp, t);
+ }
+ break;
+ }
+}
+
+
+static void
+pp_cxx_constant (cxx_pretty_printer *pp, tree t)
+{
+ switch (TREE_CODE (t))
+ {
+ case STRING_CST:
+ {
+ const bool in_parens = PAREN_STRING_LITERAL_P (t);
+ if (in_parens)
+ pp_cxx_left_paren (pp);
+ pp_c_constant (pp_c_base (pp), t);
+ if (in_parens)
+ pp_cxx_right_paren (pp);
}
break;
+
+ case INTEGER_CST:
+ if (NULLPTR_TYPE_P (TREE_TYPE (t)))
+ {
+ pp_string (pp, "nullptr");
+ break;
+ }
+ /* else fall through. */
+
+ default:
+ pp_c_constant (pp_c_base (pp), t);
+ break;
}
}
:: operator-function-id
:: qualifier-id
( expression )
- id-expression */
+ id-expression
+
+ GNU Extensions:
+ __builtin_va_arg ( assignment-expression , type-id )
+ __builtin_offsetof ( type-id, offsetof-expression )
+
+ __has_nothrow_assign ( type-id )
+ __has_nothrow_constructor ( type-id )
+ __has_nothrow_copy ( type-id )
+ __has_trivial_assign ( type-id )
+ __has_trivial_constructor ( type-id )
+ __has_trivial_copy ( type-id )
+ __has_trivial_destructor ( type-id )
+ __has_virtual_destructor ( type-id )
+ __is_abstract ( type-id )
+ __is_base_of ( type-id , type-id )
+ __is_class ( type-id )
+ __is_convertible_to ( type-id , type-id )
+ __is_empty ( type-id )
+ __is_enum ( type-id )
+ __is_pod ( type-id )
+ __is_polymorphic ( type-id )
+ __is_union ( type-id ) */
static void
pp_cxx_primary_expression (cxx_pretty_printer *pp, tree t)
{
switch (TREE_CODE (t))
{
- case STRING_CST:
case INTEGER_CST:
case REAL_CST:
- pp_c_constant (pp_c_base (pp), t);
+ case COMPLEX_CST:
+ case STRING_CST:
+ pp_cxx_constant (pp, t);
break;
case BASELINK:
pp_cxx_unqualified_id (pp, t);
break;
+ case STMT_EXPR:
+ pp_cxx_left_paren (pp);
+ pp_cxx_statement (pp, STMT_EXPR_STMT (t));
+ pp_cxx_right_paren (pp);
+ break;
+
+ case TRAIT_EXPR:
+ pp_cxx_trait_expression (pp, t);
+ break;
+
+ case VA_ARG_EXPR:
+ pp_cxx_va_arg_expression (pp, t);
+ break;
+
+ case OFFSETOF_EXPR:
+ pp_cxx_offsetof_expression (pp, t);
+ break;
+
default:
pp_c_primary_expression (pp_c_base (pp), t);
break;
simple-type-specifier ( expression-list(opt) )
typename ::(opt) nested-name-specifier identifier ( expression-list(opt) )
typename ::(opt) nested-name-specifier template(opt)
- template-id ( expression-list(opt) )
+ template-id ( expression-list(opt) )
postfix-expression . template(opt) ::(opt) id-expression
postfix-expression -> template(opt) ::(opt) id-expression
postfix-expression . pseudo-destructor-name
reinterpret_cast < type-id > ( expression )
const_cast < type-id > ( expression )
typeid ( expression )
- typeif ( type-id ) */
+ typeid ( type-id ) */
static void
pp_cxx_postfix_expression (cxx_pretty_printer *pp, tree t)
{
enum tree_code code = TREE_CODE (t);
-
+
switch (code)
{
case AGGR_INIT_EXPR:
case CALL_EXPR:
{
- tree fun = TREE_OPERAND (t, 0);
- tree args = TREE_OPERAND (t, 1);
- tree saved_scope = pp->enclosing_scope;
-
- if (TREE_CODE (fun) == ADDR_EXPR)
- fun = TREE_OPERAND (fun, 0);
-
- /* In templates, where there is no way to tell whether a given
- call uses an actual member function. So the parser builds
- FUN as a COMPONENT_REF or a plain IDENTIFIER_NODE until
- instantiation time. */
- if (TREE_CODE (fun) != FUNCTION_DECL)
- ;
- else if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fun))
- {
- tree object = code == AGGR_INIT_EXPR && AGGR_INIT_VIA_CTOR_P (t)
- ? TREE_OPERAND (t, 2)
- : TREE_VALUE (args);
-
- while (TREE_CODE (object) == NOP_EXPR)
- object = TREE_OPERAND (object, 0);
-
- if (TREE_CODE (object) == ADDR_EXPR)
- object = TREE_OPERAND (object, 0);
-
- if (TREE_CODE (TREE_TYPE (object)) != POINTER_TYPE)
- {
- pp_cxx_postfix_expression (pp, object);
- pp_cxx_dot (pp);
- }
- else
- {
- pp_cxx_postfix_expression (pp, object);
- pp_cxx_arrow (pp);
- }
- args = TREE_CHAIN (args);
- pp->enclosing_scope = strip_pointer_operator (TREE_TYPE (object));
- }
-
- pp_cxx_postfix_expression (pp, fun);
- pp->enclosing_scope = saved_scope;
- pp_cxx_call_argument_list (pp, args);
+ tree fun = (code == AGGR_INIT_EXPR ? AGGR_INIT_EXPR_FN (t)
+ : CALL_EXPR_FN (t));
+ tree saved_scope = pp->enclosing_scope;
+ bool skipfirst = false;
+ tree arg;
+
+ if (TREE_CODE (fun) == ADDR_EXPR)
+ fun = TREE_OPERAND (fun, 0);
+
+ /* In templates, where there is no way to tell whether a given
+ call uses an actual member function. So the parser builds
+ FUN as a COMPONENT_REF or a plain IDENTIFIER_NODE until
+ instantiation time. */
+ if (TREE_CODE (fun) != FUNCTION_DECL)
+ ;
+ else if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fun))
+ {
+ tree object = (code == AGGR_INIT_EXPR
+ ? (AGGR_INIT_VIA_CTOR_P (t)
+ ? AGGR_INIT_EXPR_SLOT (t)
+ : AGGR_INIT_EXPR_ARG (t, 0))
+ : CALL_EXPR_ARG (t, 0));
+
+ while (TREE_CODE (object) == NOP_EXPR)
+ object = TREE_OPERAND (object, 0);
+
+ if (TREE_CODE (object) == ADDR_EXPR)
+ object = TREE_OPERAND (object, 0);
+
+ if (TREE_CODE (TREE_TYPE (object)) != POINTER_TYPE)
+ {
+ pp_cxx_postfix_expression (pp, object);
+ pp_cxx_dot (pp);
+ }
+ else
+ {
+ pp_cxx_postfix_expression (pp, object);
+ pp_cxx_arrow (pp);
+ }
+ skipfirst = true;
+ pp->enclosing_scope = strip_pointer_operator (TREE_TYPE (object));
+ }
+
+ pp_cxx_postfix_expression (pp, fun);
+ pp->enclosing_scope = saved_scope;
+ pp_cxx_left_paren (pp);
+ if (code == AGGR_INIT_EXPR)
+ {
+ aggr_init_expr_arg_iterator iter;
+ FOR_EACH_AGGR_INIT_EXPR_ARG (arg, iter, t)
+ {
+ if (skipfirst)
+ skipfirst = false;
+ else
+ {
+ pp_cxx_expression (pp, arg);
+ if (more_aggr_init_expr_args_p (&iter))
+ pp_cxx_separate_with (pp, ',');
+ }
+ }
+ }
+ else
+ {
+ call_expr_arg_iterator iter;
+ FOR_EACH_CALL_EXPR_ARG (arg, iter, t)
+ {
+ if (skipfirst)
+ skipfirst = false;
+ else
+ {
+ pp_cxx_expression (pp, arg);
+ if (more_call_expr_args_p (&iter))
+ pp_cxx_separate_with (pp, ',');
+ }
+ }
+ }
+ pp_cxx_right_paren (pp);
}
if (code == AGGR_INIT_EXPR && AGGR_INIT_VIA_CTOR_P (t))
- {
- pp_cxx_separate_with (pp, ',');
- pp_cxx_postfix_expression (pp, TREE_OPERAND (t, 2));
- }
+ {
+ pp_cxx_separate_with (pp, ',');
+ pp_cxx_postfix_expression (pp, AGGR_INIT_EXPR_SLOT (t));
+ }
break;
case BASELINK:
case REINTERPRET_CAST_EXPR:
case CONST_CAST_EXPR:
if (code == DYNAMIC_CAST_EXPR)
- pp_cxx_identifier (pp, "dynamic_cast");
+ pp_cxx_ws_string (pp, "dynamic_cast");
else if (code == STATIC_CAST_EXPR)
- pp_cxx_identifier (pp, "static_cast");
+ pp_cxx_ws_string (pp, "static_cast");
else if (code == REINTERPRET_CAST_EXPR)
- pp_cxx_identifier (pp, "reinterpret_cast");
+ pp_cxx_ws_string (pp, "reinterpret_cast");
else
- pp_cxx_identifier (pp, "const_cast");
+ pp_cxx_ws_string (pp, "const_cast");
pp_cxx_begin_template_argument_list (pp);
pp_cxx_type_id (pp, TREE_TYPE (t));
pp_cxx_end_template_argument_list (pp);
break;
case TYPEID_EXPR:
- t = TREE_OPERAND (t, 0);
- pp_cxx_identifier (pp, "typeid");
- pp_left_paren (pp);
- if (TYPE_P (t))
- pp_cxx_type_id (pp, t);
- else
- pp_cxx_expression (pp, t);
- pp_right_paren (pp);
+ pp_cxx_typeid_expression (pp, t);
break;
case PSEUDO_DTOR_EXPR:
pp_cxx_unqualified_id (pp, TREE_OPERAND (t, 2));
break;
+ case ARROW_EXPR:
+ pp_cxx_postfix_expression (pp, TREE_OPERAND (t, 0));
+ pp_cxx_arrow (pp);
+ break;
+
default:
pp_c_postfix_expression (pp_c_base (pp), t);
break;
pp_cxx_new_expression (cxx_pretty_printer *pp, tree t)
{
enum tree_code code = TREE_CODE (t);
+ tree type = TREE_OPERAND (t, 1);
+ tree init = TREE_OPERAND (t, 2);
switch (code)
{
case NEW_EXPR:
case VEC_NEW_EXPR:
if (NEW_EXPR_USE_GLOBAL (t))
- pp_cxx_colon_colon (pp);
- pp_cxx_identifier (pp, "new");
+ pp_cxx_colon_colon (pp);
+ pp_cxx_ws_string (pp, "new");
if (TREE_OPERAND (t, 0))
- {
- pp_cxx_call_argument_list (pp, TREE_OPERAND (t, 0));
- pp_space (pp);
- }
- /* FIXME: array-types are built with one more element. */
- pp_cxx_type_id (pp, TREE_OPERAND (t, 1));
- if (TREE_OPERAND (t, 2))
- {
- pp_left_paren (pp);
- t = TREE_OPERAND (t, 2);
- if (TREE_CODE (t) == TREE_LIST)
- pp_c_expression_list (pp_c_base (pp), t);
- else if (t == void_zero_node)
- ; /* OK, empty initializer list. */
- else
- pp_cxx_expression (pp, t);
- pp_right_paren (pp);
- }
+ {
+ pp_cxx_call_argument_list (pp, TREE_OPERAND (t, 0));
+ pp_space (pp);
+ }
+ if (TREE_CODE (type) == ARRAY_REF)
+ type = build_cplus_array_type
+ (TREE_OPERAND (type, 0),
+ build_index_type (fold_build2_loc (input_location,
+ MINUS_EXPR, integer_type_node,
+ TREE_OPERAND (type, 1),
+ integer_one_node)));
+ pp_cxx_type_id (pp, type);
+ if (init)
+ {
+ pp_left_paren (pp);
+ if (TREE_CODE (init) == TREE_LIST)
+ pp_c_expression_list (pp_c_base (pp), init);
+ else if (init == void_zero_node)
+ ; /* OK, empty initializer list. */
+ else
+ pp_cxx_expression (pp, init);
+ pp_right_paren (pp);
+ }
break;
default:
case DELETE_EXPR:
case VEC_DELETE_EXPR:
if (DELETE_EXPR_USE_GLOBAL (t))
- pp_cxx_colon_colon (pp);
- pp_cxx_identifier (pp, "delete");
- if (code == VEC_DELETE_EXPR)
- {
- pp_left_bracket (pp);
- pp_right_bracket (pp);
- }
+ pp_cxx_colon_colon (pp);
+ pp_cxx_ws_string (pp, "delete");
+ pp_space (pp);
+ if (code == VEC_DELETE_EXPR
+ || DELETE_EXPR_USE_VEC (t))
+ {
+ pp_left_bracket (pp);
+ pp_right_bracket (pp);
+ pp_space (pp);
+ }
pp_c_cast_expression (pp_c_base (pp), TREE_OPERAND (t, 0));
- break;
-
+ break;
+
default:
pp_unsupported_tree (pp, t);
}
unary-operator cast-expression
sizeof unary-expression
sizeof ( type-id )
+ sizeof ... ( identifier )
new-expression
delete-expression
case VEC_DELETE_EXPR:
pp_cxx_delete_expression (pp, t);
break;
-
+
+ case SIZEOF_EXPR:
+ if (PACK_EXPANSION_P (TREE_OPERAND (t, 0)))
+ {
+ pp_cxx_ws_string (pp, "sizeof");
+ pp_cxx_ws_string (pp, "...");
+ pp_cxx_whitespace (pp);
+ pp_cxx_left_paren (pp);
+ if (TYPE_P (TREE_OPERAND (t, 0)))
+ pp_cxx_type_id (pp, TREE_OPERAND (t, 0));
+ else
+ pp_unary_expression (pp, TREE_OPERAND (t, 0));
+ pp_cxx_right_paren (pp);
+ break;
+ }
+ /* Fall through */
+
+ case ALIGNOF_EXPR:
+ pp_cxx_ws_string (pp, code == SIZEOF_EXPR ? "sizeof" : "__alignof__");
+ pp_cxx_whitespace (pp);
+ if (TYPE_P (TREE_OPERAND (t, 0)))
+ {
+ pp_cxx_left_paren (pp);
+ pp_cxx_type_id (pp, TREE_OPERAND (t, 0));
+ pp_cxx_right_paren (pp);
+ }
+ else
+ pp_unary_expression (pp, TREE_OPERAND (t, 0));
+ break;
+
+ case UNARY_PLUS_EXPR:
+ pp_plus (pp);
+ pp_cxx_cast_expression (pp, TREE_OPERAND (t, 0));
+ break;
+
default:
pp_c_unary_expression (pp_c_base (pp), t);
break;
{
switch (TREE_CODE (t))
{
- /* Handle unfortunate OFFESET_REF overloading here. */
+ /* Handle unfortunate OFFSET_REF overloading here. */
case OFFSET_REF:
if (TYPE_P (TREE_OPERAND (t, 0)))
- {
- pp_cxx_qualified_id (pp, t);
- break;
- }
+ {
+ pp_cxx_qualified_id (pp, t);
+ break;
+ }
/* Else fall through. */
case MEMBER_REF:
case DOTSTAR_EXPR:
pp_cxx_pm_expression (pp, TREE_OPERAND (t, 0));
- pp_cxx_dot (pp);
+ if (TREE_CODE (t) == MEMBER_REF)
+ pp_cxx_arrow (pp);
+ else
+ pp_cxx_dot (pp);
pp_star(pp);
pp_cxx_cast_expression (pp, TREE_OPERAND (t, 1));
break;
break;
}
- pp_cxx_identifier (pp, op);
+ pp_cxx_ws_string (pp, op);
}
break;
case THROW_EXPR:
- pp_cxx_identifier (pp, "throw");
+ pp_cxx_ws_string (pp, "throw");
if (TREE_OPERAND (e, 0))
- pp_cxx_assignment_expression (pp, TREE_OPERAND (e, 0));
+ pp_cxx_assignment_expression (pp, TREE_OPERAND (e, 0));
break;
case MODOP_EXPR:
case STRING_CST:
case INTEGER_CST:
case REAL_CST:
- pp_c_constant (pp_c_base (pp), t);
+ case COMPLEX_CST:
+ pp_cxx_constant (pp, t);
break;
case RESULT_DECL:
pp_cxx_unqualified_id (pp, t);
break;
-#if 0
+#if 0
case OFFSET_REF:
-#endif
+#endif
case SCOPE_REF:
case PTRMEM_CST:
pp_cxx_qualified_id (pp, t);
case TEMPLATE_TYPE_PARM:
case TEMPLATE_PARM_INDEX:
case TEMPLATE_TEMPLATE_PARM:
+ case STMT_EXPR:
pp_cxx_primary_expression (pp, t);
break;
case STATIC_CAST_EXPR:
case REINTERPRET_CAST_EXPR:
case CONST_CAST_EXPR:
-#if 0
+#if 0
case MEMBER_REF:
-#endif
+#endif
case EMPTY_CLASS_EXPR:
case TYPEID_EXPR:
case PSEUDO_DTOR_EXPR:
case AGGR_INIT_EXPR:
+ case ARROW_EXPR:
pp_cxx_postfix_expression (pp, t);
break;
pp_cxx_delete_expression (pp, t);
break;
+ case SIZEOF_EXPR:
+ case ALIGNOF_EXPR:
+ pp_cxx_unary_expression (pp, t);
+ break;
+
case CAST_EXPR:
pp_cxx_cast_expression (pp, t);
break;
case NON_DEPENDENT_EXPR:
case MUST_NOT_THROW_EXPR:
- pp_cxx_expression (pp, t);
+ pp_cxx_expression (pp, TREE_OPERAND (t, 0));
+ break;
+
+ case EXPR_PACK_EXPANSION:
+ pp_cxx_expression (pp, PACK_EXPANSION_PATTERN (t));
+ pp_cxx_ws_string (pp, "...");
+ break;
+
+ case TEMPLATE_ID_EXPR:
+ pp_cxx_template_id (pp, t);
+ break;
+
+ case NONTYPE_ARGUMENT_PACK:
+ {
+ tree args = ARGUMENT_PACK_ARGS (t);
+ int i, len = TREE_VEC_LENGTH (args);
+ for (i = 0; i < len; ++i)
+ {
+ if (i > 0)
+ pp_cxx_separate_with (pp, ',');
+ pp_cxx_expression (pp, TREE_VEC_ELT (args, i));
+ }
+ }
break;
default:
pp_c_expression (pp_c_base (pp), t);
- break;
+ break;
}
}
{
case FUNCTION_DECL:
if (DECL_VIRTUAL_P (t))
- pp_cxx_identifier (pp, "virtual");
+ pp_cxx_ws_string (pp, "virtual");
else if (DECL_CONSTRUCTOR_P (t) && DECL_NONCONVERTING_P (t))
- pp_cxx_identifier (pp, "explicit");
+ pp_cxx_ws_string (pp, "explicit");
else
- pp_c_function_specifier (pp_c_base (pp), t);
+ pp_c_function_specifier (pp_c_base (pp), t);
default:
break;
pp_cxx_storage_class_specifier (pp, t);
pp_cxx_decl_specifier_seq (pp, TREE_TYPE (t));
break;
-
+
case TYPE_DECL:
- pp_cxx_identifier (pp, "typedef");
+ pp_cxx_ws_string (pp, "typedef");
pp_cxx_decl_specifier_seq (pp, TREE_TYPE (t));
break;
- case RECORD_TYPE:
- if (TYPE_PTRMEMFUNC_P (t))
- {
- tree pfm = TYPE_PTRMEMFUNC_FN_TYPE (t);
- pp_cxx_decl_specifier_seq (pp, TREE_TYPE (TREE_TYPE (pfm)));
- pp_cxx_whitespace (pp);
- pp_cxx_ptr_operator (pp, t);
- }
- break;
-
case FUNCTION_DECL:
/* Constructors don't have return types. And conversion functions
- do not have a type-specifier in their return types. */
+ do not have a type-specifier in their return types. */
if (DECL_CONSTRUCTOR_P (t) || DECL_CONV_FN_P (t))
- pp_cxx_function_specifier (pp, t);
+ pp_cxx_function_specifier (pp, t);
else if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t))
- pp_cxx_decl_specifier_seq (pp, TREE_TYPE (TREE_TYPE (t)));
+ pp_cxx_decl_specifier_seq (pp, TREE_TYPE (TREE_TYPE (t)));
else
- default:
+ default:
pp_c_declaration_specifiers (pp_c_base (pp), t);
break;
}
break;
case TYPENAME_TYPE:
- pp_cxx_identifier (pp, "typename");
+ pp_cxx_ws_string (pp, "typename");
pp_cxx_nested_name_specifier (pp, TYPE_CONTEXT (t));
pp_cxx_unqualified_id (pp, TYPE_NAME (t));
break;
pp_cxx_nested_name_specifier (pp, TYPE_METHOD_BASETYPE (t));
break;
+ case DECLTYPE_TYPE:
+ pp_cxx_ws_string (pp, "decltype");
+ pp_cxx_left_paren (pp);
+ pp_cxx_expression (pp, DECLTYPE_TYPE_EXPR (t));
+ pp_cxx_right_paren (pp);
+ break;
+
+ case RECORD_TYPE:
+ if (TYPE_PTRMEMFUNC_P (t))
+ {
+ tree pfm = TYPE_PTRMEMFUNC_FN_TYPE (t);
+ pp_cxx_decl_specifier_seq (pp, TREE_TYPE (TREE_TYPE (pfm)));
+ pp_cxx_whitespace (pp);
+ pp_cxx_ptr_operator (pp, t);
+ break;
+ }
+ /* else fall through */
+
default:
if (!(TREE_CODE (t) == FUNCTION_DECL && DECL_CONSTRUCTOR_P (t)))
- pp_c_specifier_qualifier_list (pp_c_base (pp), t);
+ pp_c_specifier_qualifier_list (pp_c_base (pp), t);
}
}
case REFERENCE_TYPE:
case POINTER_TYPE:
if (TREE_CODE (TREE_TYPE (t)) == POINTER_TYPE
- || TYPE_PTR_TO_MEMBER_P (TREE_TYPE (t)))
- pp_cxx_ptr_operator (pp, TREE_TYPE (t));
+ || TYPE_PTR_TO_MEMBER_P (TREE_TYPE (t)))
+ pp_cxx_ptr_operator (pp, TREE_TYPE (t));
if (TREE_CODE (t) == POINTER_TYPE)
- {
- pp_star (pp);
- pp_cxx_cv_qualifier_seq (pp, t);
- }
+ {
+ pp_star (pp);
+ pp_cxx_cv_qualifier_seq (pp, t);
+ }
else
- pp_ampersand (pp);
+ pp_ampersand (pp);
break;
case RECORD_TYPE:
if (TYPE_PTRMEMFUNC_P (t))
- {
- pp_cxx_left_paren (pp);
- pp_cxx_nested_name_specifier (pp, TYPE_PTRMEMFUNC_OBJECT_TYPE (t));
- pp_star (pp);
- break;
- }
+ {
+ pp_cxx_left_paren (pp);
+ pp_cxx_nested_name_specifier (pp, TYPE_PTRMEMFUNC_OBJECT_TYPE (t));
+ pp_star (pp);
+ break;
+ }
case OFFSET_TYPE:
if (TYPE_PTR_TO_MEMBER_P (t))
- {
- pp_cxx_nested_name_specifier (pp, TYPE_PTRMEM_CLASS_TYPE (t));
- pp_star (pp);
- pp_cxx_cv_qualifier_seq (pp, t);
- break;
- }
+ {
+ if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
+ pp_cxx_left_paren (pp);
+ pp_cxx_nested_name_specifier (pp, TYPE_PTRMEM_CLASS_TYPE (t));
+ pp_star (pp);
+ pp_cxx_cv_qualifier_seq (pp, t);
+ break;
+ }
/* else fall through. */
default:
pp_cxx_parameter_declaration_clause (cxx_pretty_printer *pp, tree t)
{
tree args = TYPE_P (t) ? NULL : FUNCTION_FIRST_USER_PARM (t);
- tree types = TYPE_P (t) ? TYPE_ARG_TYPES (t) : FUNCTION_FIRST_USER_PARMTYPE (t);
+ tree types =
+ TYPE_P (t) ? TYPE_ARG_TYPES (t) : FUNCTION_FIRST_USER_PARMTYPE (t);
const bool abstract = args == NULL
|| pp_c_base (pp)->flags & pp_c_flag_abstract;
bool first = true;
for (; args; args = TREE_CHAIN (args), types = TREE_CHAIN (types))
{
if (!first)
- pp_cxx_separate_with (pp, ',');
+ pp_cxx_separate_with (pp, ',');
first = false;
pp_cxx_parameter_declaration (pp, abstract ? TREE_VALUE (types) : args);
if (!abstract && pp_c_base (pp)->flags & pp_cxx_flag_default_argument)
- {
- pp_cxx_whitespace (pp);
- pp_equal (pp);
- pp_cxx_whitespace (pp);
- pp_cxx_assignment_expression (pp, TREE_PURPOSE (types));
- }
+ {
+ pp_cxx_whitespace (pp);
+ pp_equal (pp);
+ pp_cxx_whitespace (pp);
+ pp_cxx_assignment_expression (pp, TREE_PURPOSE (types));
+ }
}
pp_cxx_right_paren (pp);
}
pp_cxx_exception_specification (cxx_pretty_printer *pp, tree t)
{
tree ex_spec = TYPE_RAISES_EXCEPTIONS (t);
+ bool need_comma = false;
if (!TYPE_NOTHROW_P (t) && ex_spec == NULL)
return;
- pp_cxx_identifier (pp, "throw");
+ pp_cxx_ws_string (pp, "throw");
pp_cxx_left_paren (pp);
for (; ex_spec && TREE_VALUE (ex_spec); ex_spec = TREE_CHAIN (ex_spec))
{
- pp_cxx_type_id (pp, TREE_VALUE (ex_spec));
- if (TREE_CHAIN (ex_spec))
- pp_cxx_separate_with (pp, ',');
+ tree type = TREE_VALUE (ex_spec);
+ tree argpack = NULL_TREE;
+ int i, len = 1;
+
+ if (ARGUMENT_PACK_P (type))
+ {
+ argpack = ARGUMENT_PACK_ARGS (type);
+ len = TREE_VEC_LENGTH (argpack);
+ }
+
+ for (i = 0; i < len; ++i)
+ {
+ if (argpack)
+ type = TREE_VEC_ELT (argpack, i);
+
+ if (need_comma)
+ pp_cxx_separate_with (pp, ',');
+ else
+ need_comma = true;
+
+ pp_cxx_type_id (pp, type);
+ }
}
pp_cxx_right_paren (pp);
}
/* direct-declarator:
declarator-id
direct-declarator ( parameter-declaration-clause ) cv-qualifier-seq(opt)
- exception-specification(opt)
+ exception-specification(opt)
direct-declaration [ constant-expression(opt) ]
( declarator ) */
case CONST_DECL:
case FIELD_DECL:
if (DECL_NAME (t))
- {
- pp_cxx_space_for_pointer_operator (pp, TREE_TYPE (t));
- pp_cxx_id_expression (pp, DECL_NAME (t));
- }
+ {
+ pp_cxx_space_for_pointer_operator (pp, TREE_TYPE (t));
+
+ if ((TREE_CODE (t) == PARM_DECL && FUNCTION_PARAMETER_PACK_P (t))
+ || template_parameter_pack_p (t))
+ /* A function parameter pack or non-type template
+ parameter pack. */
+ pp_cxx_ws_string (pp, "...");
+
+ pp_cxx_id_expression (pp, DECL_NAME (t));
+ }
pp_cxx_abstract_declarator (pp, TREE_TYPE (t));
break;
-
+
case FUNCTION_DECL:
pp_cxx_space_for_pointer_operator (pp, TREE_TYPE (TREE_TYPE (t)));
pp_cxx_id_expression (pp, t);
pp_cxx_parameter_declaration_clause (pp, t);
-
+
if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t))
- {
- pp_base (pp)->padding = pp_before;
- pp_cxx_cv_qualifier_seq (pp, pp_cxx_implicit_parameter_type (t));
- }
+ {
+ pp_base (pp)->padding = pp_before;
+ pp_cxx_cv_qualifier_seq (pp, pp_cxx_implicit_parameter_type (t));
+ }
pp_cxx_exception_specification (pp, TREE_TYPE (t));
break;
pp_cxx_whitespace (pp);
for (; t; t = TREE_CHAIN (t))
{
- pp_cxx_primary_expression (pp, TREE_PURPOSE (t));
+ tree purpose = TREE_PURPOSE (t);
+ bool is_pack = PACK_EXPANSION_P (purpose);
+
+ if (is_pack)
+ pp_cxx_primary_expression (pp, PACK_EXPANSION_PATTERN (purpose));
+ else
+ pp_cxx_primary_expression (pp, purpose);
pp_cxx_call_argument_list (pp, TREE_VALUE (t));
+ if (is_pack)
+ pp_cxx_ws_string (pp, "...");
if (TREE_CHAIN (t))
- pp_cxx_separate_with (pp, ',');
+ pp_cxx_separate_with (pp, ',');
}
}
decl-specifier-seq(opt) declarator ctor-initializer(opt) function-body
decl-specifier-seq(opt) declarator function-try-block */
-void
+static void
pp_cxx_function_definition (cxx_pretty_printer *pp, tree t)
{
tree saved_scope = pp->enclosing_scope;
else if (POINTER_TYPE_P (t))
{
if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE
- || TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE)
- pp_cxx_right_paren (pp);
+ || TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE)
+ pp_cxx_right_paren (pp);
t = TREE_TYPE (t);
}
pp_cxx_direct_abstract_declarator (pp, t);
/* direct-abstract-declarator:
direct-abstract-declarator(opt) ( parameter-declaration-clause )
- cv-qualifier-seq(opt) exception-specification(opt)
+ cv-qualifier-seq(opt) exception-specification(opt)
direct-abstract-declarator(opt) [ constant-expression(opt) ]
( abstract-declarator ) */
case RECORD_TYPE:
if (TYPE_PTRMEMFUNC_P (t))
- pp_cxx_direct_abstract_declarator (pp, TYPE_PTRMEMFUNC_FN_TYPE (t));
+ pp_cxx_direct_abstract_declarator (pp, TYPE_PTRMEMFUNC_FN_TYPE (t));
break;
case METHOD_TYPE:
pp_cxx_parameter_declaration_clause (pp, t);
pp_cxx_direct_abstract_declarator (pp, TREE_TYPE (t));
if (TREE_CODE (t) == METHOD_TYPE)
- {
- pp_base (pp)->padding = pp_before;
- pp_cxx_cv_qualifier_seq
- (pp, TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (t))));
- }
+ {
+ pp_base (pp)->padding = pp_before;
+ pp_cxx_cv_qualifier_seq
+ (pp, TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (t))));
+ }
pp_cxx_exception_specification (pp, t);
break;
default:
pp_c_direct_abstract_declarator (pp_c_base (pp), t);
- break;
+ break;
}
}
case TEMPLATE_PARM_INDEX:
case TEMPLATE_DECL:
case TYPEOF_TYPE:
+ case DECLTYPE_TYPE:
case TEMPLATE_ID_EXPR:
pp_cxx_type_specifier_seq (pp, t);
break;
+ case TYPE_PACK_EXPANSION:
+ pp_cxx_type_id (pp, PACK_EXPANSION_PATTERN (t));
+ pp_cxx_ws_string (pp, "...");
+ break;
+
default:
pp_c_type_id (pp_c_base (pp), t);
break;
}
/* template-argument-list:
- template-argument
- template-argument-list, template-argument
+ template-argument ...(opt)
+ template-argument-list, template-argument ...(opt)
template-argument:
assignment-expression
type-id
- template-name */
+ template-name */
static void
pp_cxx_template_argument_list (cxx_pretty_printer *pp, tree t)
{
int i;
+ bool need_comma = false;
+
if (t == NULL)
return;
for (i = 0; i < TREE_VEC_LENGTH (t); ++i)
{
tree arg = TREE_VEC_ELT (t, i);
- if (i != 0)
- pp_cxx_separate_with (pp, ',');
- if (TYPE_P (arg) || (TREE_CODE (arg) == TEMPLATE_DECL
- && TYPE_P (DECL_TEMPLATE_RESULT (arg))))
- pp_cxx_type_id (pp, arg);
- else
- pp_cxx_expression (pp, arg);
+ tree argpack = NULL_TREE;
+ int idx, len = 1;
+
+ if (ARGUMENT_PACK_P (arg))
+ {
+ argpack = ARGUMENT_PACK_ARGS (arg);
+ len = TREE_VEC_LENGTH (argpack);
+ }
+
+ for (idx = 0; idx < len; idx++)
+ {
+ if (argpack)
+ arg = TREE_VEC_ELT (argpack, idx);
+
+ if (need_comma)
+ pp_cxx_separate_with (pp, ',');
+ else
+ need_comma = true;
+
+ if (TYPE_P (arg) || (TREE_CODE (arg) == TEMPLATE_DECL
+ && TYPE_P (DECL_TEMPLATE_RESULT (arg))))
+ pp_cxx_type_id (pp, arg);
+ else
+ pp_cxx_expression (pp, arg);
+ }
}
}
/* Statements. */
-void
+static void
pp_cxx_statement (cxx_pretty_printer *pp, tree t)
{
switch (TREE_CODE (t))
break;
case USING_STMT:
- pp_cxx_identifier (pp, "using");
- pp_cxx_identifier (pp, "namespace");
+ pp_cxx_ws_string (pp, "using");
+ pp_cxx_ws_string (pp, "namespace");
+ if (DECL_CONTEXT (t))
+ pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
pp_cxx_qualified_id (pp, USING_STMT_NAMESPACE (t));
break;
case USING_DECL:
- pp_cxx_identifier (pp, "using");
- pp_cxx_nested_name_specifier (pp, DECL_INITIAL (t));
+ pp_cxx_ws_string (pp, "using");
+ pp_cxx_nested_name_specifier (pp, USING_DECL_SCOPE (t));
pp_cxx_unqualified_id (pp, DECL_NAME (t));
break;
break;
/* try-block:
- try compound-statement handler-seq */
+ try compound-statement handler-seq */
case TRY_BLOCK:
pp_maybe_newline_and_indent (pp, 0);
- pp_cxx_identifier (pp, "try");
+ pp_cxx_ws_string (pp, "try");
pp_newline_and_indent (pp, 3);
pp_cxx_statement (pp, TRY_STMTS (t));
pp_newline_and_indent (pp, -3);
if (CLEANUP_P (t))
- ;
+ ;
else
- pp_cxx_statement (pp, TRY_HANDLERS (t));
+ pp_cxx_statement (pp, TRY_HANDLERS (t));
break;
/*
- handler-seq:
- handler handler-seq(opt)
+ handler-seq:
+ handler handler-seq(opt)
- handler:
- catch ( exception-declaration ) compound-statement
+ handler:
+ catch ( exception-declaration ) compound-statement
- exception-declaration:
- type-specifier-seq declarator
- type-specifier-seq abstract-declarator
- ... */
+ exception-declaration:
+ type-specifier-seq declarator
+ type-specifier-seq abstract-declarator
+ ... */
case HANDLER:
- pp_cxx_identifier (pp, "catch");
+ pp_cxx_ws_string (pp, "catch");
pp_cxx_left_paren (pp);
pp_cxx_exception_declaration (pp, HANDLER_PARMS (t));
pp_cxx_right_paren (pp);
break;
/* selection-statement:
- if ( expression ) statement
- if ( expression ) statement else statement */
+ if ( expression ) statement
+ if ( expression ) statement else statement */
case IF_STMT:
- pp_cxx_identifier (pp, "if");
+ pp_cxx_ws_string (pp, "if");
pp_cxx_whitespace (pp);
pp_cxx_left_paren (pp);
pp_cxx_expression (pp, IF_COND (t));
if (ELSE_CLAUSE (t))
{
tree else_clause = ELSE_CLAUSE (t);
- pp_cxx_identifier (pp, "else");
+ pp_cxx_ws_string (pp, "else");
if (TREE_CODE (else_clause) == IF_STMT)
pp_cxx_whitespace (pp);
else
}
break;
+ case SWITCH_STMT:
+ pp_cxx_ws_string (pp, "switch");
+ pp_space (pp);
+ pp_cxx_left_paren (pp);
+ pp_cxx_expression (pp, SWITCH_STMT_COND (t));
+ pp_cxx_right_paren (pp);
+ pp_indentation (pp) += 3;
+ pp_needs_newline (pp) = true;
+ pp_cxx_statement (pp, SWITCH_STMT_BODY (t));
+ pp_newline_and_indent (pp, -3);
+ break;
+
+ /* iteration-statement:
+ while ( expression ) statement
+ do statement while ( expression ) ;
+ for ( expression(opt) ; expression(opt) ; expression(opt) ) statement
+ for ( declaration expression(opt) ; expression(opt) ) statement */
+ case WHILE_STMT:
+ pp_cxx_ws_string (pp, "while");
+ pp_space (pp);
+ pp_cxx_left_paren (pp);
+ pp_cxx_expression (pp, WHILE_COND (t));
+ pp_cxx_right_paren (pp);
+ pp_newline_and_indent (pp, 3);
+ pp_cxx_statement (pp, WHILE_BODY (t));
+ pp_indentation (pp) -= 3;
+ pp_needs_newline (pp) = true;
+ break;
+
+ case DO_STMT:
+ pp_cxx_ws_string (pp, "do");
+ pp_newline_and_indent (pp, 3);
+ pp_cxx_statement (pp, DO_BODY (t));
+ pp_newline_and_indent (pp, -3);
+ pp_cxx_ws_string (pp, "while");
+ pp_space (pp);
+ pp_cxx_left_paren (pp);
+ pp_cxx_expression (pp, DO_COND (t));
+ pp_cxx_right_paren (pp);
+ pp_cxx_semicolon (pp);
+ pp_needs_newline (pp) = true;
+ break;
+
+ case FOR_STMT:
+ pp_cxx_ws_string (pp, "for");
+ pp_space (pp);
+ pp_cxx_left_paren (pp);
+ if (FOR_INIT_STMT (t))
+ pp_cxx_statement (pp, FOR_INIT_STMT (t));
+ else
+ pp_cxx_semicolon (pp);
+ pp_needs_newline (pp) = false;
+ pp_cxx_whitespace (pp);
+ if (FOR_COND (t))
+ pp_cxx_expression (pp, FOR_COND (t));
+ pp_cxx_semicolon (pp);
+ pp_needs_newline (pp) = false;
+ pp_cxx_whitespace (pp);
+ if (FOR_EXPR (t))
+ pp_cxx_expression (pp, FOR_EXPR (t));
+ pp_cxx_right_paren (pp);
+ pp_newline_and_indent (pp, 3);
+ pp_cxx_statement (pp, FOR_BODY (t));
+ pp_indentation (pp) -= 3;
+ pp_needs_newline (pp) = true;
+ break;
+
+ /* jump-statement:
+ goto identifier;
+ continue ;
+ return expression(opt) ; */
+ case BREAK_STMT:
+ case CONTINUE_STMT:
+ pp_string (pp, TREE_CODE (t) == BREAK_STMT ? "break" : "continue");
+ pp_cxx_semicolon (pp);
+ pp_needs_newline (pp) = true;
+ break;
+
+ /* expression-statement:
+ expression(opt) ; */
+ case EXPR_STMT:
+ pp_cxx_expression (pp, EXPR_STMT_EXPR (t));
+ pp_cxx_semicolon (pp);
+ pp_needs_newline (pp) = true;
+ break;
+
case CLEANUP_STMT:
- pp_cxx_identifier (pp, "try");
+ pp_cxx_ws_string (pp, "try");
pp_newline_and_indent (pp, 2);
pp_cxx_statement (pp, CLEANUP_BODY (t));
pp_newline_and_indent (pp, -2);
- pp_cxx_identifier (pp, CLEANUP_EH_ONLY (t) ? "catch" : "finally");
+ pp_cxx_ws_string (pp, CLEANUP_EH_ONLY (t) ? "catch" : "finally");
pp_newline_and_indent (pp, 2);
pp_cxx_statement (pp, CLEANUP_EXPR (t));
pp_newline_and_indent (pp, -2);
break;
+ case STATIC_ASSERT:
+ pp_cxx_declaration (pp, t);
+ break;
+
default:
pp_c_statement (pp_c_base (pp), t);
break;
static void
pp_cxx_original_namespace_definition (cxx_pretty_printer *pp, tree t)
{
- pp_cxx_identifier (pp, "namespace");
+ pp_cxx_ws_string (pp, "namespace");
+ if (DECL_CONTEXT (t))
+ pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
if (DECL_NAME (t))
pp_cxx_unqualified_id (pp, t);
pp_cxx_whitespace (pp);
static void
pp_cxx_namespace_alias_definition (cxx_pretty_printer *pp, tree t)
{
- pp_cxx_identifier (pp, "namespace");
+ pp_cxx_ws_string (pp, "namespace");
+ if (DECL_CONTEXT (t))
+ pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
pp_cxx_unqualified_id (pp, t);
pp_cxx_whitespace (pp);
pp_equal (pp);
pp_cxx_whitespace (pp);
+ if (DECL_CONTEXT (DECL_NAMESPACE_ALIAS (t)))
+ pp_cxx_nested_name_specifier (pp,
+ DECL_CONTEXT (DECL_NAMESPACE_ALIAS (t)));
pp_cxx_qualified_id (pp, DECL_NAMESPACE_ALIAS (t));
pp_cxx_semicolon (pp);
}
for (i = 0; i < n; ++i)
{
if (i)
- pp_cxx_separate_with (pp, ',');
+ pp_cxx_separate_with (pp, ',');
pp_cxx_template_parameter (pp, TREE_VEC_ELT (t, i));
}
}
parameter-declaration
type-parameter:
- class identifier(opt)
- class identifier(op) = type-id
+ class ...(opt) identifier(opt)
+ class identifier(opt) = type-id
typename identifier(opt)
- typename identifier(opt) = type-id
- template < template-parameter-list > class identifier(opt)
- template < template-parameter-list > class identifier(opt) = template-name
-*/
+ typename ...(opt) identifier(opt) = type-id
+ template < template-parameter-list > class ...(opt) identifier(opt)
+ template < template-parameter-list > class identifier(opt) = template-name */
static void
pp_cxx_template_parameter (cxx_pretty_printer *pp, tree t)
switch (TREE_CODE (parameter))
{
case TYPE_DECL:
- pp_cxx_identifier (pp, "class");
+ pp_cxx_ws_string (pp, "class");
+ if (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (t)))
+ pp_cxx_ws_string (pp, "...");
if (DECL_NAME (parameter))
- pp_cxx_tree_identifier (pp, DECL_NAME (parameter));
- /* FIXME: Chech if we should print also default argument. */
+ pp_cxx_tree_identifier (pp, DECL_NAME (parameter));
+ /* FIXME: Check if we should print also default argument. */
break;
case PARM_DECL:
if (code == TEMPLATE_TYPE_PARM || code == TEMPLATE_TEMPLATE_PARM
|| code == BOUND_TEMPLATE_TEMPLATE_PARM)
parm = TEMPLATE_TYPE_PARM_INDEX (parm);
-
+
pp_cxx_begin_template_argument_list (pp);
- pp_cxx_identifier (pp, "template-parameter-");
+ pp_cxx_ws_string (pp, M_("template-parameter-"));
pp_wide_integer (pp, TEMPLATE_PARM_LEVEL (parm));
pp_minus (pp);
pp_wide_integer (pp, TEMPLATE_PARM_IDX (parm) + 1);
pp_maybe_newline_and_indent (pp, 0);
for (level = DECL_TEMPLATE_PARMS (tmpl); level; level = TREE_CHAIN (level))
{
- pp_cxx_identifier (pp, "template");
+ pp_cxx_ws_string (pp, "template");
pp_cxx_begin_template_argument_list (pp);
pp_cxx_template_parameter_list (pp, TREE_VALUE (level));
pp_cxx_end_template_argument_list (pp);
asm-definition
namespace-alias-definition
using-declaration
- using-directive */
+ using-directive
+ static_assert-declaration */
void
pp_cxx_declaration (cxx_pretty_printer *pp, tree t)
{
- if (!DECL_LANG_SPECIFIC (t))
+ if (TREE_CODE (t) == STATIC_ASSERT)
+ {
+ pp_cxx_ws_string (pp, "static_assert");
+ pp_cxx_left_paren (pp);
+ pp_cxx_expression (pp, STATIC_ASSERT_CONDITION (t));
+ pp_cxx_separate_with (pp, ',');
+ pp_cxx_expression (pp, STATIC_ASSERT_MESSAGE (t));
+ pp_cxx_right_paren (pp);
+ }
+ else if (!DECL_LANG_SPECIFIC (t))
pp_cxx_simple_declaration (pp, t);
else if (DECL_USE_TEMPLATE (t))
switch (DECL_USE_TEMPLATE (t))
{
case 1:
- pp_cxx_template_declaration (pp, t);
- break;
-
+ pp_cxx_template_declaration (pp, t);
+ break;
+
case 2:
- pp_cxx_explicit_specialization (pp, t);
- break;
+ pp_cxx_explicit_specialization (pp, t);
+ break;
case 3:
- pp_cxx_explicit_instantiation (pp, t);
- break;
+ pp_cxx_explicit_instantiation (pp, t);
+ break;
default:
- break;
+ break;
}
else switch (TREE_CODE (t))
{
case TYPE_DECL:
pp_cxx_simple_declaration (pp, t);
break;
-
+
case FUNCTION_DECL:
if (DECL_SAVED_TREE (t))
- pp_cxx_function_definition (pp, t);
+ pp_cxx_function_definition (pp, t);
else
- pp_cxx_simple_declaration (pp, t);
+ pp_cxx_simple_declaration (pp, t);
break;
case NAMESPACE_DECL:
if (DECL_NAMESPACE_ALIAS (t))
- pp_cxx_namespace_alias_definition (pp, t);
+ pp_cxx_namespace_alias_definition (pp, t);
else
- pp_cxx_original_namespace_definition (pp, t);
+ pp_cxx_original_namespace_definition (pp, t);
break;
default:
}
}
+static void
+pp_cxx_typeid_expression (cxx_pretty_printer *pp, tree t)
+{
+ t = TREE_OPERAND (t, 0);
+ pp_cxx_ws_string (pp, "typeid");
+ pp_cxx_left_paren (pp);
+ if (TYPE_P (t))
+ pp_cxx_type_id (pp, t);
+ else
+ pp_cxx_expression (pp, t);
+ pp_cxx_right_paren (pp);
+}
+
+void
+pp_cxx_va_arg_expression (cxx_pretty_printer *pp, tree t)
+{
+ pp_cxx_ws_string (pp, "va_arg");
+ pp_cxx_left_paren (pp);
+ pp_cxx_assignment_expression (pp, TREE_OPERAND (t, 0));
+ pp_cxx_separate_with (pp, ',');
+ pp_cxx_type_id (pp, TREE_TYPE (t));
+ pp_cxx_right_paren (pp);
+}
+
+static bool
+pp_cxx_offsetof_expression_1 (cxx_pretty_printer *pp, tree t)
+{
+ switch (TREE_CODE (t))
+ {
+ case ARROW_EXPR:
+ if (TREE_CODE (TREE_OPERAND (t, 0)) == STATIC_CAST_EXPR
+ && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (t, 0))))
+ {
+ pp_cxx_type_id (pp, TREE_TYPE (TREE_TYPE (TREE_OPERAND (t, 0))));
+ pp_cxx_separate_with (pp, ',');
+ return true;
+ }
+ return false;
+ case COMPONENT_REF:
+ if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0)))
+ return false;
+ if (TREE_CODE (TREE_OPERAND (t, 0)) != ARROW_EXPR)
+ pp_cxx_dot (pp);
+ pp_cxx_expression (pp, TREE_OPERAND (t, 1));
+ return true;
+ case ARRAY_REF:
+ if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0)))
+ return false;
+ pp_left_bracket (pp);
+ pp_cxx_expression (pp, TREE_OPERAND (t, 1));
+ pp_right_bracket (pp);
+ return true;
+ default:
+ return false;
+ }
+}
+
+void
+pp_cxx_offsetof_expression (cxx_pretty_printer *pp, tree t)
+{
+ pp_cxx_ws_string (pp, "offsetof");
+ pp_cxx_left_paren (pp);
+ if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0)))
+ pp_cxx_expression (pp, TREE_OPERAND (t, 0));
+ pp_cxx_right_paren (pp);
+}
+
+void
+pp_cxx_trait_expression (cxx_pretty_printer *pp, tree t)
+{
+ cp_trait_kind kind = TRAIT_EXPR_KIND (t);
+
+ switch (kind)
+ {
+ case CPTK_HAS_NOTHROW_ASSIGN:
+ pp_cxx_ws_string (pp, "__has_nothrow_assign");
+ break;
+ case CPTK_HAS_TRIVIAL_ASSIGN:
+ pp_cxx_ws_string (pp, "__has_trivial_assign");
+ break;
+ case CPTK_HAS_NOTHROW_CONSTRUCTOR:
+ pp_cxx_ws_string (pp, "__has_nothrow_constructor");
+ break;
+ case CPTK_HAS_TRIVIAL_CONSTRUCTOR:
+ pp_cxx_ws_string (pp, "__has_trivial_constructor");
+ break;
+ case CPTK_HAS_NOTHROW_COPY:
+ pp_cxx_ws_string (pp, "__has_nothrow_copy");
+ break;
+ case CPTK_HAS_TRIVIAL_COPY:
+ pp_cxx_ws_string (pp, "__has_trivial_copy");
+ break;
+ case CPTK_HAS_TRIVIAL_DESTRUCTOR:
+ pp_cxx_ws_string (pp, "__has_trivial_destructor");
+ break;
+ case CPTK_HAS_VIRTUAL_DESTRUCTOR:
+ pp_cxx_ws_string (pp, "__has_virtual_destructor");
+ break;
+ case CPTK_IS_ABSTRACT:
+ pp_cxx_ws_string (pp, "__is_abstract");
+ break;
+ case CPTK_IS_BASE_OF:
+ pp_cxx_ws_string (pp, "__is_base_of");
+ break;
+ case CPTK_IS_CLASS:
+ pp_cxx_ws_string (pp, "__is_class");
+ break;
+ case CPTK_IS_CONVERTIBLE_TO:
+ pp_cxx_ws_string (pp, "__is_convertible_to");
+ break;
+ case CPTK_IS_EMPTY:
+ pp_cxx_ws_string (pp, "__is_empty");
+ break;
+ case CPTK_IS_ENUM:
+ pp_cxx_ws_string (pp, "__is_enum");
+ break;
+ case CPTK_IS_POD:
+ pp_cxx_ws_string (pp, "__is_pod");
+ break;
+ case CPTK_IS_POLYMORPHIC:
+ pp_cxx_ws_string (pp, "__is_polymorphic");
+ break;
+ case CPTK_IS_STD_LAYOUT:
+ pp_cxx_ws_string (pp, "__is_std_layout");
+ break;
+ case CPTK_IS_TRIVIAL:
+ pp_cxx_ws_string (pp, "__is_trivial");
+ break;
+ case CPTK_IS_UNION:
+ pp_cxx_ws_string (pp, "__is_union");
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
+
+ pp_cxx_left_paren (pp);
+ pp_cxx_type_id (pp, TRAIT_EXPR_TYPE1 (t));
+
+ if (kind == CPTK_IS_BASE_OF || kind == CPTK_IS_CONVERTIBLE_TO)
+ {
+ pp_cxx_separate_with (pp, ',');
+ pp_cxx_type_id (pp, TRAIT_EXPR_TYPE2 (t));
+ }
+
+ pp_cxx_right_paren (pp);
+}
\f
typedef c_pretty_print_fn pp_fun;
/* pp->c_base.statement = (pp_fun) pp_cxx_statement; */
+ pp->c_base.constant = (pp_fun) pp_cxx_constant;
pp->c_base.id_expression = (pp_fun) pp_cxx_id_expression;
pp->c_base.primary_expression = (pp_fun) pp_cxx_primary_expression;
pp->c_base.postfix_expression = (pp_fun) pp_cxx_postfix_expression;