Exemple #1
0
/* primary-expression:
     literal
     this
     :: identifier
     :: operator-function-id
     :: qualifier-id
     ( expression )
     id-expression   */
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);
      break;

    case BASELINK:
      t = BASELINK_FUNCTIONS (t);
    case VAR_DECL:
    case PARM_DECL:
    case FIELD_DECL:
    case FUNCTION_DECL:
    case OVERLOAD:
    case CONST_DECL:
    case TEMPLATE_DECL:
      pp_cxx_id_expression (pp, t);
      break;

    case RESULT_DECL:
    case TEMPLATE_TYPE_PARM:
    case TEMPLATE_PARM_INDEX:
      pp_cxx_unqualified_id (pp, t);
      break;

    default:
      pp_c_primary_expression (pp_c_base (pp), t);
      break;
    }
}
static void
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);
  const bool abstract = args == NULL
    || pp_c_base (pp)->flags & pp_c_flag_abstract;
  bool first = true;

  /* Skip artificial parameter for nonstatic member functions.  */
  if (TREE_CODE (t) == METHOD_TYPE)
    types = TREE_CHAIN (types);

  pp_cxx_left_paren (pp);
  for (; args; args = TREE_CHAIN (args), types = TREE_CHAIN (types))
    {
      if (!first)
	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_right_paren (pp);
}
static void
pp_cxx_assignment_expression (cxx_pretty_printer *pp, tree e)
{
  switch (TREE_CODE (e))
    {
    case MODIFY_EXPR:
    case INIT_EXPR:
      pp_c_logical_or_expression (pp_c_base (pp), TREE_OPERAND (e, 0));
      pp_space (pp);
      pp_equal (pp);
      pp_space (pp);
      pp_cxx_assignment_expression (pp, TREE_OPERAND (e, 1));
      break;

    case THROW_EXPR:
      pp_cxx_identifier (pp, "throw");
      if (TREE_OPERAND (e, 0))
	pp_cxx_assignment_expression (pp, TREE_OPERAND (e, 0));
      break;

    case MODOP_EXPR:
      pp_c_logical_or_expression (pp_c_base (pp), TREE_OPERAND (e, 0));
      pp_cxx_assignment_operator (pp, TREE_OPERAND (e, 1));
      pp_cxx_assignment_expression (pp, TREE_OPERAND (e, 2));
      break;

    default:
      pp_cxx_conditional_expression (pp, e);
      break;
    }
}
static void
pp_cxx_type_id (cxx_pretty_printer *pp, tree t)
{
  pp_flags saved_flags = pp_c_base (pp)->flags;
  pp_c_base (pp)->flags |= pp_c_flag_abstract;

  switch (TREE_CODE (t))
    {
    case TYPE_DECL:
    case UNION_TYPE:
    case RECORD_TYPE:
    case ENUMERAL_TYPE:
    case TYPENAME_TYPE:
    case BOUND_TEMPLATE_TEMPLATE_PARM:
    case UNBOUND_CLASS_TEMPLATE:
    case TEMPLATE_TEMPLATE_PARM:
    case TEMPLATE_TYPE_PARM:
    case TEMPLATE_PARM_INDEX:
    case TEMPLATE_DECL:
    case TYPEOF_TYPE:
    case TEMPLATE_ID_EXPR:
      pp_cxx_type_specifier_seq (pp, t);
      break;

    default:
      pp_c_type_id (pp_c_base (pp), t);
      break;
    }

  pp_c_base (pp)->flags = saved_flags;
}
static void
pp_cxx_conditional_expression (cxx_pretty_printer *pp, tree e)
{
  if (TREE_CODE (e) == COND_EXPR)
    {
      pp_c_logical_or_expression (pp_c_base (pp), TREE_OPERAND (e, 0));
      pp_space (pp);
      pp_question (pp);
      pp_space (pp);
      pp_cxx_expression (pp, TREE_OPERAND (e, 1));
      pp_space (pp);
      pp_cxx_assignment_expression (pp, TREE_OPERAND (e, 2));
    }
  else
    pp_c_logical_or_expression (pp_c_base (pp), e);
}
static void
pp_cxx_type_specifier_seq (cxx_pretty_printer *pp, tree t)
{
  switch (TREE_CODE (t))
    {
    case TEMPLATE_DECL:
    case TEMPLATE_TYPE_PARM:
    case TEMPLATE_TEMPLATE_PARM:
    case TYPE_DECL:
    case BOUND_TEMPLATE_TEMPLATE_PARM:
      pp_cxx_cv_qualifier_seq (pp, t);
      pp_cxx_simple_type_specifier (pp, t);
      break;

    case METHOD_TYPE:
      pp_cxx_type_specifier_seq (pp, TREE_TYPE (t));
      pp_cxx_space_for_pointer_operator (pp, TREE_TYPE (t));
      pp_cxx_nested_name_specifier (pp, TYPE_METHOD_BASETYPE (t));
      break;

    default:
      if (!(TREE_CODE (t) == FUNCTION_DECL && DECL_CONSTRUCTOR_P (t)))
	pp_c_specifier_qualifier_list (pp_c_base (pp), t);
    }
}
static void
pp_cxx_simple_type_specifier (cxx_pretty_printer *pp, tree t)
{
  switch (TREE_CODE (t))
    {
    case RECORD_TYPE:
    case UNION_TYPE:
    case ENUMERAL_TYPE:
      pp_cxx_qualified_id (pp, t);
      break;

    case TEMPLATE_TYPE_PARM:
    case TEMPLATE_TEMPLATE_PARM:
    case TEMPLATE_PARM_INDEX:
      pp_cxx_unqualified_id (pp, t);
      break;

    case TYPENAME_TYPE:
      pp_cxx_identifier (pp, "typename");
      pp_cxx_nested_name_specifier (pp, TYPE_CONTEXT (t));
      pp_cxx_unqualified_id (pp, TYPE_NAME (t));
      break;

    default:
      pp_c_type_specifier (pp_c_base (pp), t);
      break;
    }
}
void
pp_cxx_pretty_printer_init (cxx_pretty_printer *pp)
{
  pp_c_pretty_printer_init (pp_c_base (pp));
  pp_set_line_maximum_length (pp, 0);

  pp->c_base.declaration = (pp_fun) pp_cxx_declaration;
  pp->c_base.declaration_specifiers = (pp_fun) pp_cxx_decl_specifier_seq;
  pp->c_base.function_specifier = (pp_fun) pp_cxx_function_specifier;
  pp->c_base.type_specifier_seq = (pp_fun) pp_cxx_type_specifier_seq;
  pp->c_base.declarator = (pp_fun) pp_cxx_declarator;
  pp->c_base.direct_declarator = (pp_fun) pp_cxx_direct_declarator;
  pp->c_base.parameter_list = (pp_fun) pp_cxx_parameter_declaration_clause;
  pp->c_base.type_id = (pp_fun) pp_cxx_type_id;
  pp->c_base.abstract_declarator = (pp_fun) pp_cxx_abstract_declarator;
  pp->c_base.direct_abstract_declarator =
    (pp_fun) pp_cxx_direct_abstract_declarator;
  pp->c_base.simple_type_specifier = (pp_fun)pp_cxx_simple_type_specifier;

  /* pp->c_base.statement = (pp_fun) pp_cxx_statement;  */

  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;
  pp->c_base.unary_expression = (pp_fun) pp_cxx_unary_expression;
  pp->c_base.multiplicative_expression = (pp_fun) pp_cxx_multiplicative_expression;
  pp->c_base.conditional_expression = (pp_fun) pp_cxx_conditional_expression;
  pp->c_base.assignment_expression = (pp_fun) pp_cxx_assignment_expression;
  pp->c_base.expression = (pp_fun) pp_cxx_expression;
  pp->enclosing_scope = global_namespace;
}
void
pp_c_direct_declarator (c_pretty_printer *pp, tree t)
{
  switch (TREE_CODE (t))
    {
    case VAR_DECL:
    case PARM_DECL:
    case TYPE_DECL:
    case FIELD_DECL:
    case LABEL_DECL:
      pp_c_space_for_pointer_operator (pp, TREE_TYPE (t));
      pp_c_tree_decl_identifier (pp, t);
      break;

    case ARRAY_TYPE:
    case POINTER_TYPE:
	/* APPLE LOCAL blocks */
	case BLOCK_POINTER_TYPE:
      pp_abstract_declarator (pp, TREE_TYPE (t));
      break;

    case FUNCTION_TYPE:
      pp_parameter_list (pp, t);
      pp_abstract_declarator (pp, TREE_TYPE (t));
      break;

    case FUNCTION_DECL:
      pp_c_space_for_pointer_operator (pp, TREE_TYPE (TREE_TYPE (t)));
      pp_c_tree_decl_identifier (pp, t);
      if (pp_c_base (pp)->flags & pp_c_flag_abstract)
	pp_abstract_declarator (pp, TREE_TYPE (t));
      else
	{
	  pp_parameter_list (pp, t);
	  pp_abstract_declarator (pp, TREE_TYPE (TREE_TYPE (t)));
	}
      break;

    case INTEGER_TYPE:
    case REAL_TYPE:
    case ENUMERAL_TYPE:
    case UNION_TYPE:
    case RECORD_TYPE:
      break;

    default:
      pp_unsupported_tree (pp, t);
      break;
    }
}
static void
pp_cxx_cast_expression (cxx_pretty_printer *pp, tree t)
{
  switch (TREE_CODE (t))
    {
    case CAST_EXPR:
      pp_cxx_type_id (pp, TREE_TYPE (t));
      pp_cxx_call_argument_list (pp, TREE_OPERAND (t, 0));
      break;

    default:
      pp_c_cast_expression (pp_c_base (pp), t);
      break;
    }
}
static void
pp_cxx_function_specifier (cxx_pretty_printer *pp, tree t)
{
  switch (TREE_CODE (t))
    {
    case FUNCTION_DECL:
      if (DECL_VIRTUAL_P (t))
	pp_cxx_identifier (pp, "virtual");
      else if (DECL_CONSTRUCTOR_P (t) && DECL_NONCONVERTING_P (t))
	pp_cxx_identifier (pp, "explicit");
      else
	pp_c_function_specifier (pp_c_base (pp), t);

    default:
      break;
    }
}
static void
pp_cxx_direct_declarator (cxx_pretty_printer *pp, tree t)
{
  switch (TREE_CODE (t))
    {
    case VAR_DECL:
    case PARM_DECL:
    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_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_cxx_exception_specification (pp, TREE_TYPE (t));
      break;

    case TYPENAME_TYPE:
    case TEMPLATE_DECL:
    case TEMPLATE_TYPE_PARM:
    case TEMPLATE_PARM_INDEX:
    case TEMPLATE_TEMPLATE_PARM:
      break;

    default:
      pp_c_direct_declarator (pp_c_base (pp), t);
      break;
    }
}
static void
pp_cxx_decl_specifier_seq (cxx_pretty_printer *pp, tree t)
{
  switch (TREE_CODE (t))
    {
    case VAR_DECL:
    case PARM_DECL:
    case CONST_DECL:
    case FIELD_DECL:
      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_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.  */
      if (DECL_CONSTRUCTOR_P (t) || DECL_CONV_FN_P (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)));
      else
	default:
      pp_c_declaration_specifiers (pp_c_base (pp), t);
      break;
    }
}
Exemple #14
0
/* unary-expression:
      postfix-expression
      ++ cast-expression
      -- cast-expression
      unary-operator cast-expression
      sizeof unary-expression
      sizeof ( type-id )
      new-expression
      delete-expression

   unary-operator: one of
      *   &   +   -  !

   GNU extensions:
      __alignof__ unary-expression
      __alignof__ ( type-id )  */
static void
pp_cxx_unary_expression (cxx_pretty_printer *pp, tree t)
{
  enum tree_code code = TREE_CODE (t);
  switch (code)
    {
    case NEW_EXPR:
    case VEC_NEW_EXPR:
      pp_cxx_new_expression (pp, t);
      break;

    case DELETE_EXPR:
    case VEC_DELETE_EXPR:
      pp_cxx_delete_expression (pp, t);
      break;
      
    default:
      pp_c_unary_expression (pp_c_base (pp), t);
      break;
    }
}
static void
pp_cxx_unary_expression (cxx_pretty_printer *pp, tree t)
{
  enum tree_code code = TREE_CODE (t);
  switch (code)
    {
    case NEW_EXPR:
    case VEC_NEW_EXPR:
      pp_cxx_new_expression (pp, t);
      break;

    case DELETE_EXPR:
    case VEC_DELETE_EXPR:
      pp_cxx_delete_expression (pp, t);
      break;

    case SIZEOF_EXPR:
    case ALIGNOF_EXPR:
      pp_cxx_identifier (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;
    }
}
static void
pp_cxx_direct_abstract_declarator (cxx_pretty_printer *pp, tree t)
{
  switch (TREE_CODE (t))
    {
    case REFERENCE_TYPE:
      pp_cxx_abstract_declarator (pp, t);
      break;

    case RECORD_TYPE:
      if (TYPE_PTRMEMFUNC_P (t))
	pp_cxx_direct_abstract_declarator (pp, TYPE_PTRMEMFUNC_FN_TYPE (t));
      break;

    case METHOD_TYPE:
    case FUNCTION_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_cxx_exception_specification (pp, t);
      break;

    case TYPENAME_TYPE:
    case TEMPLATE_TYPE_PARM:
    case TEMPLATE_TEMPLATE_PARM:
    case BOUND_TEMPLATE_TEMPLATE_PARM:
    case UNBOUND_CLASS_TEMPLATE:
      break;

    default:
      pp_c_direct_abstract_declarator (pp_c_base (pp), t);
      break;
    }
}
static void
pp_cxx_delete_expression (cxx_pretty_printer *pp, tree t)
{
  enum tree_code code = TREE_CODE (t);
  switch (code)
    {
    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_c_cast_expression (pp_c_base (pp), TREE_OPERAND (t, 0));
      break;

    default:
      pp_unsupported_tree (pp, t);
    }
}
static void
pp_cxx_new_expression (cxx_pretty_printer *pp, tree t)
{
  enum tree_code code = TREE_CODE (t);
  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");
      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);
	}
      break;

    default:
      pp_unsupported_tree (pp, t);
    }
}
static void
pp_cxx_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);
      break;

    case RESULT_DECL:
      pp_cxx_unqualified_id (pp, t);
      break;

#if 0
    case OFFSET_REF:
#endif
    case SCOPE_REF:
    case PTRMEM_CST:
      pp_cxx_qualified_id (pp, t);
      break;

    case OVERLOAD:
      t = OVL_CURRENT (t);
    case VAR_DECL:
    case PARM_DECL:
    case FIELD_DECL:
    case CONST_DECL:
    case FUNCTION_DECL:
    case BASELINK:
    case TEMPLATE_DECL:
    case TEMPLATE_TYPE_PARM:
    case TEMPLATE_PARM_INDEX:
    case TEMPLATE_TEMPLATE_PARM:
    case STMT_EXPR:
      pp_cxx_primary_expression (pp, t);
      break;

    case CALL_EXPR:
    case DYNAMIC_CAST_EXPR:
    case STATIC_CAST_EXPR:
    case REINTERPRET_CAST_EXPR:
    case CONST_CAST_EXPR:
#if 0
    case MEMBER_REF:
#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;

    case NEW_EXPR:
    case VEC_NEW_EXPR:
      pp_cxx_new_expression (pp, t);
      break;

    case DELETE_EXPR:
    case VEC_DELETE_EXPR:
      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 OFFSET_REF:
    case MEMBER_REF:
    case DOTSTAR_EXPR:
      pp_cxx_pm_expression (pp, t);
      break;

    case MULT_EXPR:
    case TRUNC_DIV_EXPR:
    case TRUNC_MOD_EXPR:
      pp_cxx_multiplicative_expression (pp, t);
      break;

    case COND_EXPR:
      pp_cxx_conditional_expression (pp, t);
      break;

    case MODIFY_EXPR:
    case INIT_EXPR:
    case THROW_EXPR:
    case MODOP_EXPR:
      pp_cxx_assignment_expression (pp, t);
      break;

    case NON_DEPENDENT_EXPR:
    case MUST_NOT_THROW_EXPR:
      pp_cxx_expression (pp, t);
      break;

    default:
      pp_c_expression (pp_c_base (pp), t);
      break;
    }
}
static void
pp_cxx_statement (cxx_pretty_printer *pp, tree t)
{
  switch (TREE_CODE (t))
    {
    case CTOR_INITIALIZER:
      pp_cxx_ctor_initializer (pp, t);
      break;

    case USING_STMT:
      pp_cxx_identifier (pp, "using");
      pp_cxx_identifier (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, USING_DECL_SCOPE (t));
      pp_cxx_unqualified_id (pp, DECL_NAME (t));
      break;

    case EH_SPEC_BLOCK:
      break;

      /* try-block:
	    try compound-statement handler-seq  */
    case TRY_BLOCK:
      pp_maybe_newline_and_indent (pp, 0);
      pp_cxx_identifier (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));
      break;

      /*
	 handler-seq:
	    handler handler-seq(opt)

	 handler:
	 catch ( exception-declaration ) compound-statement

	 exception-declaration:
	    type-specifier-seq declarator
	    type-specifier-seq abstract-declarator
	    ...   */
    case HANDLER:
      pp_cxx_identifier (pp, "catch");
      pp_cxx_left_paren (pp);
      pp_cxx_exception_declaration (pp, HANDLER_PARMS (t));
      pp_cxx_right_paren (pp);
      pp_indentation (pp) += 3;
      pp_needs_newline (pp) = true;
      pp_cxx_statement (pp, HANDLER_BODY (t));
      pp_indentation (pp) -= 3;
      pp_needs_newline (pp) = true;
      break;

      /* selection-statement:
	    if ( expression ) statement
	    if ( expression ) statement else statement  */
    case IF_STMT:
      pp_cxx_identifier (pp, "if");
      pp_cxx_whitespace (pp);
      pp_cxx_left_paren (pp);
      pp_cxx_expression (pp, IF_COND (t));
      pp_cxx_right_paren (pp);
      pp_newline_and_indent (pp, 2);
      pp_cxx_statement (pp, THEN_CLAUSE (t));
      pp_newline_and_indent (pp, -2);
      if (ELSE_CLAUSE (t))
	{
	  tree else_clause = ELSE_CLAUSE (t);
	  pp_cxx_identifier (pp, "else");
	  if (TREE_CODE (else_clause) == IF_STMT)
	    pp_cxx_whitespace (pp);
	  else
	    pp_newline_and_indent (pp, 2);
	  pp_cxx_statement (pp, else_clause);
	  if (TREE_CODE (else_clause) != IF_STMT)
	    pp_newline_and_indent (pp, -2);
	}
      break;

    case SWITCH_STMT:
      pp_cxx_identifier (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_identifier (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_identifier (pp, "do");
      pp_newline_and_indent (pp, 3);
      pp_cxx_statement (pp, DO_BODY (t));
      pp_newline_and_indent (pp, -3);
      pp_cxx_identifier (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_identifier (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_identifier (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_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_newline_and_indent (pp, 2);
      pp_cxx_statement (pp, CLEANUP_EXPR (t));
      pp_newline_and_indent (pp, -2);
      break;

    default:
      pp_c_statement (pp_c_base (pp), t);
      break;
    }
}
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);
      }
      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));
	}
      break;

    case BASELINK:
    case VAR_DECL:
    case PARM_DECL:
    case FIELD_DECL:
    case FUNCTION_DECL:
    case OVERLOAD:
    case CONST_DECL:
    case TEMPLATE_DECL:
    case RESULT_DECL:
      pp_cxx_primary_expression (pp, t);
      break;

    case DYNAMIC_CAST_EXPR:
    case STATIC_CAST_EXPR:
    case REINTERPRET_CAST_EXPR:
    case CONST_CAST_EXPR:
      if (code == DYNAMIC_CAST_EXPR)
	pp_cxx_identifier (pp, "dynamic_cast");
      else if (code == STATIC_CAST_EXPR)
	pp_cxx_identifier (pp, "static_cast");
      else if (code == REINTERPRET_CAST_EXPR)
	pp_cxx_identifier (pp, "reinterpret_cast");
      else
	pp_cxx_identifier (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);
      pp_left_paren (pp);
      pp_cxx_expression (pp, TREE_OPERAND (t, 0));
      pp_right_paren (pp);
      break;

    case EMPTY_CLASS_EXPR:
      pp_cxx_type_id (pp, TREE_TYPE (t));
      pp_left_paren (pp);
      pp_right_paren (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);
      break;

    case PSEUDO_DTOR_EXPR:
      pp_cxx_postfix_expression (pp, TREE_OPERAND (t, 0));
      pp_cxx_dot (pp);
      pp_cxx_qualified_id (pp, TREE_OPERAND (t, 1));
      pp_cxx_colon_colon (pp);
      pp_complement (pp);
      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;
    }
}
Exemple #22
0
void
pp_cxx_statement (cxx_pretty_printer *pp, tree t)
{
  switch (TREE_CODE (t))
    {
    case USING_STMT:
      pp_cxx_identifier (pp, "using");
      pp_cxx_identifier (pp, "namespace");
      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_unqualified_id (pp, DECL_NAME (t));
      break;

    case EH_SPEC_BLOCK:
      break;

      /* try-block:
            try compound-statement handler-seq  */
    case TRY_BLOCK:
      pp_maybe_newline_and_indent (pp, 0);
      pp_cxx_identifier (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));
      break;

      /*
         handler-seq:
            handler handler-seq(opt)

         handler:
         catch ( exception-declaration ) compound-statement 

         exception-declaration:
            type-specifier-seq declarator
            type-specifier-seq abstract-declarator
            ...   */
    case HANDLER:
      pp_cxx_identifier (pp, "catch");
      pp_cxx_left_paren (pp);
      pp_cxx_exception_declaration (pp, HANDLER_PARMS (t));
      pp_cxx_right_paren (pp);
      pp_indentation (pp) += 3;
      pp_needs_newline (pp) = true;
      pp_cxx_statement (pp, HANDLER_BODY (t));
      pp_indentation (pp) -= 3;
      pp_needs_newline (pp) = true;
      break;

    default:
      pp_c_statement (pp_c_base (pp), t);
      break;
    }
}