]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/c-family/c-semantics.c
2015-06-17 Andrew MacLeod <amacleod@redhat.com>
[thirdparty/gcc.git] / gcc / c-family / c-semantics.c
CommitLineData
862f468c 1/* This file contains subroutine used by the C front-end to construct GENERIC.
d353bf18 2 Copyright (C) 2000-2015 Free Software Foundation, Inc.
efbe600e 3 Written by Benjamin Chelf (chelf@codesourcery.com).
5c3247a9 4
f12b58b3 5This file is part of GCC.
5c3247a9 6
f12b58b3 7GCC is free software; you can redistribute it and/or modify it under
8the terms of the GNU General Public License as published by the Free
8c4c00c1 9Software Foundation; either version 3, or (at your option) any later
f12b58b3 10version.
5c3247a9 11
f12b58b3 12GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13WARRANTY; without even the implied warranty of MERCHANTABILITY or
14FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15for more details.
5c3247a9 16
17You should have received a copy of the GNU General Public License
8c4c00c1 18along with GCC; see the file COPYING3. If not see
19<http://www.gnu.org/licenses/>. */
5c3247a9 20
21#include "config.h"
22#include "system.h"
805e22b2 23#include "coretypes.h"
24#include "tm.h"
b20a8bb4 25#include "alias.h"
26#include "symtab.h"
27#include "options.h"
b20a8bb4 28#include "tree.h"
29#include "hard-reg-set.h"
5c3247a9 30#include "function.h"
31#include "splay-tree.h"
5c3247a9 32#include "c-common.h"
5c3247a9 33#include "flags.h"
75a70cf9 34#include "tree-iterator.h"
3b584d94 35
a08e60ae 36/* Create an empty statement tree rooted at T. */
37
2363ef00 38tree
39push_stmt_list (void)
a08e60ae 40{
2363ef00 41 tree t;
42 t = alloc_stmt_list ();
f1f41a6c 43 vec_safe_push (stmt_list_stack, t);
2363ef00 44 return t;
45}
46
2363ef00 47/* Finish the statement tree rooted at T. */
48
49tree
50pop_stmt_list (tree t)
51{
cacfdc02 52 tree u = NULL_TREE;
2363ef00 53
54 /* Pop statement lists until we reach the target level. The extra
55 nestings will be due to outstanding cleanups. */
56 while (1)
57 {
f1f41a6c 58 u = stmt_list_stack->pop ();
59 if (!stmt_list_stack->is_empty ())
cacfdc02 60 {
f1f41a6c 61 tree x = stmt_list_stack->last ();
cacfdc02 62 STATEMENT_LIST_HAS_LABEL (x) |= STATEMENT_LIST_HAS_LABEL (u);
63 }
2363ef00 64 if (t == u)
65 break;
2363ef00 66 }
cacfdc02 67
68 gcc_assert (u != NULL_TREE);
2363ef00 69
70 /* If the statement list is completely empty, just return it. This is
a0c938f0 71 just as good small as build_empty_stmt, with the advantage that
2363ef00 72 statement lists are merged when they appended to one another. So
73 using the STATEMENT_LIST avoids pathological buildup of EMPTY_STMT_P
74 statements. */
75 if (TREE_SIDE_EFFECTS (t))
76 {
77 tree_stmt_iterator i = tsi_start (t);
78
79 /* If the statement list contained exactly one statement, then
80 extract it immediately. */
81 if (tsi_one_before_end_p (i))
82 {
83 u = tsi_stmt (i);
84 tsi_delink (&i);
85 free_stmt_list (t);
86 t = u;
87 }
88 }
89
90 return t;
a08e60ae 91}
92
389acd0a 93/* Build a generic statement based on the given type of node and
94 arguments. Similar to `build_nt', except that we set
e60a6f7b 95 EXPR_LOCATION to LOC. */
7cad36f4 96/* ??? This should be obsolete with the lineno_stmt productions
97 in the grammar. */
389acd0a 98
99tree
e60a6f7b 100build_stmt (location_t loc, enum tree_code code, ...)
389acd0a 101{
4ee9c684 102 tree ret;
103 int length, i;
ee582a61 104 va_list p;
4ee9c684 105 bool side_effects;
2b30d46c 106
c2f47e15 107 /* This function cannot be used to construct variably-sized nodes. */
108 gcc_assert (TREE_CODE_CLASS (code) != tcc_vl_exp);
109
ee582a61 110 va_start (p, code);
389acd0a 111
4ee9c684 112 ret = make_node (code);
daf6dff5 113 TREE_TYPE (ret) = void_type_node;
389acd0a 114 length = TREE_CODE_LENGTH (code);
e60a6f7b 115 SET_EXPR_LOCATION (ret, loc);
389acd0a 116
db8577ff 117 /* TREE_SIDE_EFFECTS will already be set for statements with
118 implicit side effects. Here we make sure it is set for other
119 expressions by checking whether the parameters have side
120 effects. */
5c3247a9 121
db8577ff 122 side_effects = false;
4ee9c684 123 for (i = 0; i < length; i++)
5c3247a9 124 {
4ee9c684 125 tree t = va_arg (p, tree);
5dd4318b 126 if (t && !TYPE_P (t))
a0c938f0 127 side_effects |= TREE_SIDE_EFFECTS (t);
4ee9c684 128 TREE_OPERAND (ret, i) = t;
5c3247a9 129 }
4ee9c684 130
db8577ff 131 TREE_SIDE_EFFECTS (ret) |= side_effects;
4ee9c684 132
133 va_end (p);
134 return ret;
5c3247a9 135}
136
0b5fc5d6 137/* Build a REALPART_EXPR or IMAGPART_EXPR, according to CODE, from ARG. */
138
139tree
140build_real_imag_expr (location_t location, enum tree_code code, tree arg)
141{
142 tree ret;
143 tree arg_type = TREE_TYPE (arg);
144
145 gcc_assert (code == REALPART_EXPR || code == IMAGPART_EXPR);
146
147 if (TREE_CODE (arg_type) == COMPLEX_TYPE)
148 {
149 ret = build1 (code, TREE_TYPE (TREE_TYPE (arg)), arg);
150 SET_EXPR_LOCATION (ret, location);
151 }
152 else if (INTEGRAL_TYPE_P (arg_type) || SCALAR_FLOAT_TYPE_P (arg_type))
153 {
154 ret = (code == REALPART_EXPR
155 ? arg
156 : omit_one_operand_loc (location, arg_type,
157 integer_zero_node, arg));
158 }
159 else
160 {
161 error_at (location, "wrong type argument to %s",
162 code == REALPART_EXPR ? "__real" : "__imag");
163 ret = error_mark_node;
164 }
165
166 return ret;
167}