123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175 |
- /* This file contains subroutine used by the C front-end to construct GENERIC.
- Copyright (C) 2000-2015 Free Software Foundation, Inc.
- Written by Benjamin Chelf (chelf@codesourcery.com).
- 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 3, or (at your option) any later
- version.
- GCC is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- for more details.
- You should have received a copy of the GNU General Public License
- 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 "hash-set.h"
- #include "machmode.h"
- #include "vec.h"
- #include "double-int.h"
- #include "input.h"
- #include "alias.h"
- #include "symtab.h"
- #include "options.h"
- #include "wide-int.h"
- #include "inchash.h"
- #include "tree.h"
- #include "hard-reg-set.h"
- #include "function.h"
- #include "splay-tree.h"
- #include "c-common.h"
- #include "flags.h"
- #include "tree-iterator.h"
- /* Create an empty statement tree rooted at T. */
- tree
- push_stmt_list (void)
- {
- tree t;
- t = alloc_stmt_list ();
- vec_safe_push (stmt_list_stack, t);
- return t;
- }
- /* Finish the statement tree rooted at T. */
- tree
- pop_stmt_list (tree t)
- {
- tree u = NULL_TREE;
- /* Pop statement lists until we reach the target level. The extra
- nestings will be due to outstanding cleanups. */
- while (1)
- {
- u = stmt_list_stack->pop ();
- if (!stmt_list_stack->is_empty ())
- {
- tree x = stmt_list_stack->last ();
- STATEMENT_LIST_HAS_LABEL (x) |= STATEMENT_LIST_HAS_LABEL (u);
- }
- if (t == u)
- break;
- }
- gcc_assert (u != NULL_TREE);
- /* If the statement list is completely empty, just return it. This is
- just as good small as build_empty_stmt, with the advantage that
- statement lists are merged when they appended to one another. So
- using the STATEMENT_LIST avoids pathological buildup of EMPTY_STMT_P
- statements. */
- if (TREE_SIDE_EFFECTS (t))
- {
- tree_stmt_iterator i = tsi_start (t);
- /* If the statement list contained exactly one statement, then
- extract it immediately. */
- if (tsi_one_before_end_p (i))
- {
- u = tsi_stmt (i);
- tsi_delink (&i);
- free_stmt_list (t);
- t = u;
- }
- }
- return t;
- }
- /* Build a generic statement based on the given type of node and
- arguments. Similar to `build_nt', except that we set
- EXPR_LOCATION to LOC. */
- /* ??? This should be obsolete with the lineno_stmt productions
- in the grammar. */
- tree
- build_stmt (location_t loc, enum tree_code code, ...)
- {
- tree ret;
- int length, i;
- va_list p;
- bool side_effects;
- /* This function cannot be used to construct variably-sized nodes. */
- gcc_assert (TREE_CODE_CLASS (code) != tcc_vl_exp);
- va_start (p, code);
- ret = make_node (code);
- TREE_TYPE (ret) = void_type_node;
- length = TREE_CODE_LENGTH (code);
- SET_EXPR_LOCATION (ret, loc);
- /* TREE_SIDE_EFFECTS will already be set for statements with
- implicit side effects. Here we make sure it is set for other
- expressions by checking whether the parameters have side
- effects. */
- side_effects = false;
- for (i = 0; i < length; i++)
- {
- tree t = va_arg (p, tree);
- if (t && !TYPE_P (t))
- side_effects |= TREE_SIDE_EFFECTS (t);
- TREE_OPERAND (ret, i) = t;
- }
- TREE_SIDE_EFFECTS (ret) |= side_effects;
- va_end (p);
- return ret;
- }
- /* Build a REALPART_EXPR or IMAGPART_EXPR, according to CODE, from ARG. */
- tree
- build_real_imag_expr (location_t location, enum tree_code code, tree arg)
- {
- tree ret;
- tree arg_type = TREE_TYPE (arg);
- gcc_assert (code == REALPART_EXPR || code == IMAGPART_EXPR);
- if (TREE_CODE (arg_type) == COMPLEX_TYPE)
- {
- ret = build1 (code, TREE_TYPE (TREE_TYPE (arg)), arg);
- SET_EXPR_LOCATION (ret, location);
- }
- else if (INTEGRAL_TYPE_P (arg_type) || SCALAR_FLOAT_TYPE_P (arg_type))
- {
- ret = (code == REALPART_EXPR
- ? arg
- : omit_one_operand_loc (location, arg_type,
- integer_zero_node, arg));
- }
- else
- {
- error_at (location, "wrong type argument to %s",
- code == REALPART_EXPR ? "__real" : "__imag");
- ret = error_mark_node;
- }
- return ret;
- }
|