1/* This file contains subroutine used by the C front-end to construct GENERIC.
2   Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008
3   Free Software Foundation, Inc.
4   Written by Benjamin Chelf (chelf@codesourcery.com).
5
6This file is part of GCC.
7
8GCC is free software; you can redistribute it and/or modify it under
9the terms of the GNU General Public License as published by the Free
10Software Foundation; either version 3, or (at your option) any later
11version.
12
13GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14WARRANTY; without even the implied warranty of MERCHANTABILITY or
15FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16for more details.
17
18You should have received a copy of the GNU General Public License
19along with GCC; see the file COPYING3.  If not see
20<http://www.gnu.org/licenses/>.  */
21
22#include "config.h"
23#include "system.h"
24#include "coretypes.h"
25#include "tm.h"
26#include "tree.h"
27#include "function.h"
28#include "splay-tree.h"
29#include "varray.h"
30#include "c-common.h"
31#include "except.h"
32/* In order for the format checking to accept the C frontend
33   diagnostic framework extensions, you must define this token before
34   including toplev.h.  */
35#define GCC_DIAG_STYLE __gcc_cdiag__
36#include "toplev.h"
37#include "flags.h"
38#include "ggc.h"
39#include "rtl.h"
40#include "output.h"
41#include "timevar.h"
42#include "predict.h"
43#include "tree-inline.h"
44#include "gimple.h"
45#include "tree-iterator.h"
46#include "langhooks.h"
47
48/* Create an empty statement tree rooted at T.  */
49
50tree
51push_stmt_list (void)
52{
53  tree t;
54  t = alloc_stmt_list ();
55  TREE_CHAIN (t) = cur_stmt_list;
56  cur_stmt_list = t;
57  return t;
58}
59
60/* Finish the statement tree rooted at T.  */
61
62tree
63pop_stmt_list (tree t)
64{
65  tree u = cur_stmt_list, chain;
66
67  /* Pop statement lists until we reach the target level.  The extra
68     nestings will be due to outstanding cleanups.  */
69  while (1)
70    {
71      chain = TREE_CHAIN (u);
72      TREE_CHAIN (u) = NULL_TREE;
73      if (chain)
74	STATEMENT_LIST_HAS_LABEL (chain) |= STATEMENT_LIST_HAS_LABEL (u);
75      if (t == u)
76	break;
77      u = chain;
78    }
79  cur_stmt_list = chain;
80
81  /* If the statement list is completely empty, just return it.  This is
82     just as good small as build_empty_stmt, with the advantage that
83     statement lists are merged when they appended to one another.  So
84     using the STATEMENT_LIST avoids pathological buildup of EMPTY_STMT_P
85     statements.  */
86  if (TREE_SIDE_EFFECTS (t))
87    {
88      tree_stmt_iterator i = tsi_start (t);
89
90      /* If the statement list contained exactly one statement, then
91	 extract it immediately.  */
92      if (tsi_one_before_end_p (i))
93	{
94	  u = tsi_stmt (i);
95	  tsi_delink (&i);
96	  free_stmt_list (t);
97	  t = u;
98	}
99    }
100
101  return t;
102}
103
104/* Build a generic statement based on the given type of node and
105   arguments. Similar to `build_nt', except that we set
106   EXPR_LOCATION to LOC. */
107/* ??? This should be obsolete with the lineno_stmt productions
108   in the grammar.  */
109
110tree
111build_stmt (location_t loc, enum tree_code code, ...)
112{
113  tree ret;
114  int length, i;
115  va_list p;
116  bool side_effects;
117
118  /* This function cannot be used to construct variably-sized nodes.  */
119  gcc_assert (TREE_CODE_CLASS (code) != tcc_vl_exp);
120
121  va_start (p, code);
122
123  ret = make_node (code);
124  TREE_TYPE (ret) = void_type_node;
125  length = TREE_CODE_LENGTH (code);
126  SET_EXPR_LOCATION (ret, loc);
127
128  /* TREE_SIDE_EFFECTS will already be set for statements with
129     implicit side effects.  Here we make sure it is set for other
130     expressions by checking whether the parameters have side
131     effects.  */
132
133  side_effects = false;
134  for (i = 0; i < length; i++)
135    {
136      tree t = va_arg (p, tree);
137      if (t && !TYPE_P (t))
138	side_effects |= TREE_SIDE_EFFECTS (t);
139      TREE_OPERAND (ret, i) = t;
140    }
141
142  TREE_SIDE_EFFECTS (ret) |= side_effects;
143
144  va_end (p);
145  return ret;
146}
147
148/* Create a CASE_LABEL_EXPR tree node and return it.  */
149
150tree
151build_case_label (location_t loc,
152		  tree low_value, tree high_value, tree label_decl)
153{
154  return build_stmt (loc, CASE_LABEL_EXPR, low_value, high_value, label_decl);
155}
156