c-semantics.c 4.3 KB
Newer Older
1 2
/* This file contains the definitions and documentation for the common
   tree codes used in the GNU C and C++ compilers (see c-common.def
3
   for the standard codes).
4 5
   Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005
   Free Software Foundation, Inc.
6
   Written by Benjamin Chelf (chelf@codesourcery.com).
7

8
This file is part of GCC.
9

10 11 12 13
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
version.
14

15 16 17 18
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.
19 20

You should have received a copy of the GNU General Public License
21
along with GCC; see the file COPYING.  If not, write to the Free
Kelley Cook committed
22 23
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.  */
24 25 26

#include "config.h"
#include "system.h"
27 28
#include "coretypes.h"
#include "tm.h"
29 30 31 32 33 34
#include "tree.h"
#include "function.h"
#include "splay-tree.h"
#include "varray.h"
#include "c-common.h"
#include "except.h"
35 36 37 38
/* In order for the format checking to accept the C frontend
   diagnostic framework extensions, you must define this token before
   including toplev.h.  */
#define GCC_DIAG_STYLE __gcc_cdiag__
39 40 41 42 43 44
#include "toplev.h"
#include "flags.h"
#include "ggc.h"
#include "rtl.h"
#include "output.h"
#include "timevar.h"
45
#include "predict.h"
46
#include "tree-inline.h"
47
#include "tree-gimple.h"
48
#include "langhooks.h"
49

50 51
/* Create an empty statement tree rooted at T.  */

52 53
tree
push_stmt_list (void)
54
{
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
  tree t;
  t = alloc_stmt_list ();
  TREE_CHAIN (t) = cur_stmt_list;
  cur_stmt_list = t;
  return t;
}

/* Finish the statement tree rooted at T.  */

tree
pop_stmt_list (tree t)
{
  tree u = cur_stmt_list, chain;

  /* Pop statement lists until we reach the target level.  The extra
     nestings will be due to outstanding cleanups.  */
  while (1)
    {
      chain = TREE_CHAIN (u);
      TREE_CHAIN (u) = NULL_TREE;
      if (t == u)
	break;
      u = chain;
    }
  cur_stmt_list = chain;

  /* If the statement list is completely empty, just return it.  This is
Mike Stump committed
82
     just as good small as build_empty_stmt, with the advantage that
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
     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;
102 103
}

104 105
/* Build a generic statement based on the given type of node and
   arguments. Similar to `build_nt', except that we set
106
   EXPR_LOCATION to be the current source location.  */
107 108
/* ??? This should be obsolete with the lineno_stmt productions
   in the grammar.  */
109 110

tree
111
build_stmt (enum tree_code code, ...)
112
{
113 114
  tree ret;
  int length, i;
115
  va_list p;
116
  bool side_effects;
117

118
  va_start (p, code);
119

120
  ret = make_node (code);
121
  TREE_TYPE (ret) = void_type_node;
122
  length = TREE_CODE_LENGTH (code);
123
  SET_EXPR_LOCATION (ret, input_location);
124

125 126 127 128
  /* 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.  */
129

130
  side_effects = false;
131
  for (i = 0; i < length; i++)
132
    {
133
      tree t = va_arg (p, tree);
134
      if (t && !TYPE_P (t))
Mike Stump committed
135
	side_effects |= TREE_SIDE_EFFECTS (t);
136
      TREE_OPERAND (ret, i) = t;
137
    }
138

139
  TREE_SIDE_EFFECTS (ret) |= side_effects;
140 141 142

  va_end (p);
  return ret;
143 144 145 146 147
}

/* Let the back-end know about DECL.  */

void
148
emit_local_var (tree decl)
149 150
{
  /* Create RTL for this variable.  */
151
  if (!DECL_RTL_SET_P (decl))
152
    {
153
      if (DECL_HARD_REGISTER (decl))
154 155
	/* The user specified an assembler name for this variable.
	   Set that up now.  */
156
	rest_of_decl_compilation (decl, 0, 0);
157 158 159 160 161
      else
	expand_decl (decl);
    }
}

162
/* Create a CASE_LABEL_EXPR tree node and return it.  */
163 164

tree
165
build_case_label (tree low_value, tree high_value, tree label_decl)
166
{
167
  return build_stmt (CASE_LABEL_EXPR, low_value, high_value, label_decl);
168
}