| 1 |
736 |
fengzhou |
/*
|
| 2 |
2322 |
dcoakley |
* Copyright (C) 2009 Advanced Micro Devices, Inc. All Rights Reserved.
|
| 3 |
|
|
*/
|
| 4 |
|
|
|
| 5 |
|
|
/*
|
| 6 |
1411 |
laijx |
* Copyright (C) 2007 Pathscale, LLC. All Rights Reserved.
|
| 7 |
|
|
*/
|
| 8 |
|
|
|
| 9 |
|
|
/*
|
| 10 |
860 |
hucheng |
* Copyright (C) 2006, 2007. QLogic Corporation. All Rights Reserved.
|
| 11 |
736 |
fengzhou |
*/
|
| 12 |
|
|
|
| 13 |
|
|
/*
|
| 14 |
|
|
Copyright 2003, 2004, 2005, 2006 PathScale, Inc. All Rights Reserved.
|
| 15 |
|
|
File modified October 9, 2003 by PathScale, Inc. to update Open64 C/C++
|
| 16 |
|
|
front-ends to GNU 3.3.1 release.
|
| 17 |
|
|
*/
|
| 18 |
|
|
|
| 19 |
|
|
/*
|
| 20 |
|
|
Copyright (C) 2002 Tensilica, Inc. All Rights Reserved.
|
| 21 |
|
|
Revised to support Tensilica processors and to improve overall performance
|
| 22 |
|
|
*/
|
| 23 |
|
|
|
| 24 |
|
|
/*
|
| 25 |
|
|
|
| 26 |
|
|
Copyright (C) 2000, 2001 Silicon Graphics, Inc. All Rights Reserved.
|
| 27 |
|
|
|
| 28 |
|
|
This program is free software; you can redistribute it and/or modify it
|
| 29 |
|
|
under the terms of version 2 of the GNU General Public License as
|
| 30 |
|
|
published by the Free Software Foundation.
|
| 31 |
|
|
|
| 32 |
|
|
This program is distributed in the hope that it would be useful, but
|
| 33 |
|
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
| 34 |
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
| 35 |
|
|
|
| 36 |
|
|
Further, this software is distributed without any warranty that it is
|
| 37 |
|
|
free of the rightful claim of any third person regarding infringement
|
| 38 |
|
|
or the like. Any license provided herein, whether implied or
|
| 39 |
|
|
otherwise, applies only to this software file. Patent licenses, if
|
| 40 |
|
|
any, provided herein do not apply to combinations of this program with
|
| 41 |
|
|
other software, or any other product whatsoever.
|
| 42 |
|
|
|
| 43 |
|
|
You should have received a copy of the GNU General Public License along
|
| 44 |
|
|
with this program; if not, write the Free Software Foundation, Inc., 59
|
| 45 |
|
|
Temple Place - Suite 330, Boston MA 02111-1307, USA.
|
| 46 |
|
|
|
| 47 |
|
|
Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pky,
|
| 48 |
|
|
Mountain View, CA 94043, or:
|
| 49 |
|
|
|
| 50 |
|
|
http://www.sgi.com
|
| 51 |
|
|
|
| 52 |
|
|
For further information regarding this notice, see:
|
| 53 |
|
|
|
| 54 |
|
|
http://oss.sgi.com/projects/GenInfo/NoticeExplan
|
| 55 |
|
|
|
| 56 |
|
|
*/
|
| 57 |
|
|
|
| 58 |
|
|
|
| 59 |
|
|
/* translate gnu decl trees to symtab references */
|
| 60 |
|
|
|
| 61 |
|
|
extern "C"{
|
| 62 |
|
|
#include "gspin-wgen-interface.h"
|
| 63 |
|
|
}
|
| 64 |
1950 |
laijx |
#if defined(BUILD_OS_DARWIN)
|
| 65 |
|
|
#include <limits.h>
|
| 66 |
|
|
#else /* defined(BUILD_OS_DARWIN) */
|
| 67 |
736 |
fengzhou |
#include <values.h>
|
| 68 |
1950 |
laijx |
#endif /* defined(BUILD_OS_DARWIN) */
|
| 69 |
2322 |
dcoakley |
#include "pathscale_defs.h"
|
| 70 |
736 |
fengzhou |
#include "defs.h"
|
| 71 |
|
|
#include "errors.h"
|
| 72 |
|
|
|
| 73 |
|
|
#include "symtab.h"
|
| 74 |
|
|
#include "strtab.h"
|
| 75 |
|
|
#include "wn.h"
|
| 76 |
|
|
#include "wgen_expr.h"
|
| 77 |
|
|
#include "wgen_decl.h"
|
| 78 |
|
|
#include "wgen_misc.h"
|
| 79 |
|
|
#include "wgen_dst.h"
|
| 80 |
|
|
#include "ir_reader.h"
|
| 81 |
|
|
#include "wgen_spin_symbol.h"
|
| 82 |
|
|
#include "wgen_stmt.h"
|
| 83 |
|
|
#include <map>
|
| 84 |
|
|
#include "erfe.h"
|
| 85 |
|
|
#ifdef TARG_X8664
|
| 86 |
|
|
#include <ctype.h>
|
| 87 |
|
|
#endif
|
| 88 |
|
|
//#include "tree_cmp.h"
|
| 89 |
2694 |
shenruifen |
#include <erglob.h>
|
| 90 |
1101 |
shiyao |
#include <ext/hash_set>
|
| 91 |
|
|
using __gnu_cxx::hash_set;
|
| 92 |
|
|
typedef struct {
|
| 93 |
|
|
size_t operator()(void* p) const { return reinterpret_cast<size_t>(p); }
|
| 94 |
|
|
} void_ptr_hash;
|
| 95 |
|
|
|
| 96 |
736 |
fengzhou |
extern int pstatic_as_global;
|
| 97 |
|
|
extern BOOL flag_no_common;
|
| 98 |
|
|
extern gs_t decl_arguments;
|
| 99 |
|
|
|
| 100 |
|
|
extern void Push_Deferred_Function(gs_t);
|
| 101 |
|
|
extern char *WGEN_Tree_Node_Name(gs_t op);
|
| 102 |
2694 |
shenruifen |
#if defined(TARG_SL)
|
| 103 |
|
|
extern char *Orig_Src_File_Name, *Src_File_Name;
|
| 104 |
|
|
#endif
|
| 105 |
860 |
hucheng |
#ifdef KEY
|
| 106 |
|
|
// =====================================================================
|
| 107 |
|
|
// bug 8346: A function's VLA argument types should only be expanded
|
| 108 |
|
|
// when necessary, to prevent size-expression-whirl from landing in an
|
| 109 |
|
|
// unintended location. If we attempt to expand such a type while
|
| 110 |
|
|
// generating a function's argument types, but are not expanding that
|
| 111 |
|
|
// specific function body, then we mark the TY as incomplete, to expand
|
| 112 |
|
|
// it later when we actually expand that function body.
|
| 113 |
|
|
// "expanding_function_definition" denotes when it is safe to process a
|
| 114 |
|
|
// function's VLA argument types.
|
| 115 |
|
|
// "processing_function_prototype" indicates when we are expanding
|
| 116 |
|
|
// function arguments (as opposed to other VLA variable occurrences).
|
| 117 |
|
|
// =====================================================================
|
| 118 |
|
|
BOOL processing_function_prototype = FALSE;
|
| 119 |
|
|
#endif
|
| 120 |
|
|
|
| 121 |
736 |
fengzhou |
// Map duplicate gcc nodes that refer to the same function.
|
| 122 |
|
|
std::multimap<gs_t, gs_t> duplicate_of;
|
| 123 |
|
|
void
|
| 124 |
|
|
add_duplicates (gs_t newdecl, gs_t olddecl)
|
| 125 |
|
|
{
|
| 126 |
|
|
duplicate_of.insert (pair<gs_t, gs_t>(newdecl, olddecl));
|
| 127 |
|
|
duplicate_of.insert (pair<gs_t, gs_t>(olddecl, newdecl));
|
| 128 |
|
|
}
|
| 129 |
|
|
|
| 130 |
|
|
// Remove all references to DECL from the map.
|
| 131 |
|
|
void
|
| 132 |
|
|
erase_duplicates (gs_t decl)
|
| 133 |
|
|
{
|
| 134 |
|
|
int i, j;
|
| 135 |
|
|
int count = duplicate_of.count (decl);
|
| 136 |
|
|
|
| 137 |
|
|
for (i=0; i<count; i++) {
|
| 138 |
|
|
std::multimap<gs_t, gs_t>::iterator iter = duplicate_of.find(decl);
|
| 139 |
|
|
gs_t t = (*iter).second;
|
| 140 |
|
|
|
| 141 |
|
|
// Erase entries with DECL as the data, i.e., <..., DECL>.
|
| 142 |
|
|
int count2 = duplicate_of.count(t);
|
| 143 |
|
|
for (j=0; j<count2; j++) {
|
| 144 |
|
|
std::multimap<gs_t, gs_t>::iterator iter2 = duplicate_of.find(t);
|
| 145 |
|
|
gs_t t2 = (*iter2).second;
|
| 146 |
|
|
if (t2 == decl) {
|
| 147 |
|
|
duplicate_of.erase (iter2);
|
| 148 |
|
|
}
|
| 149 |
|
|
}
|
| 150 |
|
|
|
| 151 |
|
|
// Erase entry with DECL as the key, i.e., <DECL, ...>.
|
| 152 |
|
|
duplicate_of.erase (iter);
|
| 153 |
|
|
}
|
| 154 |
|
|
}
|
| 155 |
|
|
|
| 156 |
|
|
static ST*
|
| 157 |
|
|
get_duplicate_st (gs_t decl)
|
| 158 |
|
|
{
|
| 159 |
|
|
int count = duplicate_of.count (decl);
|
| 160 |
|
|
|
| 161 |
|
|
for (int i=0; i<count; ++i) {
|
| 162 |
|
|
std::multimap<gs_t, gs_t>::iterator iter = duplicate_of.find(decl);
|
| 163 |
|
|
gs_t t = (*iter).second;
|
| 164 |
|
|
// The node t could have been garbage-collected by gcc. This is a crude
|
| 165 |
|
|
// test to see if t is still valid.
|
| 166 |
|
|
if (gs_tree_code(t) == GS_FUNCTION_DECL &&
|
| 167 |
|
|
gs_decl_name(t) == gs_decl_name(decl) &&
|
| 168 |
|
|
gs_decl_assembler_name_set_p(t) == gs_decl_assembler_name_set_p(decl) &&
|
| 169 |
|
|
(!gs_decl_assembler_name_set_p(t) ||
|
| 170 |
|
|
gs_decl_assembler_name(t) == gs_decl_assembler_name(decl))) {
|
| 171 |
|
|
// Return the ST previously allocated, if any.
|
| 172 |
|
|
ST *st = DECL_ST(t);
|
| 173 |
|
|
if (st != NULL)
|
| 174 |
|
|
return st;
|
| 175 |
|
|
}
|
| 176 |
|
|
duplicate_of.erase (iter);
|
| 177 |
|
|
}
|
| 178 |
|
|
return NULL;
|
| 179 |
|
|
}
|
| 180 |
|
|
|
| 181 |
|
|
static char*
|
| 182 |
|
|
Get_Name (gs_t node)
|
| 183 |
|
|
{
|
| 184 |
|
|
static UINT anon_num = 0;
|
| 185 |
|
|
static char buf[64];
|
| 186 |
|
|
|
| 187 |
|
|
if (node == NULL) {
|
| 188 |
|
|
++anon_num;
|
| 189 |
|
|
sprintf(buf, ".anonymous.%d", anon_num);
|
| 190 |
|
|
return buf;
|
| 191 |
|
|
}
|
| 192 |
|
|
else if (gs_tree_code (node) == GS_IDENTIFIER_NODE)
|
| 193 |
|
|
return ((char *) gs_identifier_pointer (node));
|
| 194 |
|
|
else if (gs_tree_code (node) == GS_TYPE_DECL)
|
| 195 |
|
|
// If type has a typedef-name, the TYPE_NAME is a TYPE_DECL.
|
| 196 |
1950 |
laijx |
#ifdef FE_GNU_4_2_0 // bug 14137
|
| 197 |
|
|
if (gs_decl_name(node) == NULL) {
|
| 198 |
|
|
++anon_num;
|
| 199 |
|
|
sprintf(buf, ".anonymous.%d", anon_num);
|
| 200 |
|
|
return buf;
|
| 201 |
|
|
}
|
| 202 |
|
|
else
|
| 203 |
|
|
#endif
|
| 204 |
736 |
fengzhou |
return ((char *) gs_identifier_pointer (gs_decl_name (node)));
|
| 205 |
|
|
else
|
| 206 |
|
|
FmtAssert(FALSE, ("Get_Name unexpected tree"));
|
| 207 |
|
|
return NULL;
|
| 208 |
|
|
}
|
| 209 |
|
|
|
| 210 |
|
|
static void
|
| 211 |
|
|
dump_field(gs_t field)
|
| 212 |
|
|
{
|
| 213 |
|
|
printf("%s: ", Get_Name(gs_decl_name(field)));
|
| 214 |
|
|
printf("%d\n", DECL_FIELD_ID(field));
|
| 215 |
|
|
}
|
| 216 |
|
|
|
| 217 |
|
|
// =================================================================
|
| 218 |
|
|
// KEY: If there is a vtable pointer, then number it as the first
|
| 219 |
|
|
// field in the record. GNU 4.x provides the same field for a vptr
|
| 220 |
|
|
// to a base class, and its inherited classes. So we consistenly
|
| 221 |
|
|
// number the vptr as field_id 1.
|
| 222 |
|
|
// =================================================================
|
| 223 |
|
|
gs_t
|
| 224 |
|
|
get_first_real_or_virtual_field (gs_t type_tree)
|
| 225 |
|
|
{
|
| 226 |
|
|
// return vfield only if the type contains fields (bug 10787)
|
| 227 |
|
|
// bug 11227: C_TYPE_INCOMPLETE_VARS for C is the same as TYPE_VFIELD,
|
| 228 |
|
|
// make sure we do not use it for C.
|
| 229 |
|
|
if (lang_cplus && gs_type_fields(type_tree) && gs_type_vfield(type_tree))
|
| 230 |
|
|
return gs_type_vfield(type_tree);
|
| 231 |
|
|
|
| 232 |
|
|
return gs_type_fields(type_tree);
|
| 233 |
|
|
}
|
| 234 |
|
|
|
| 235 |
|
|
gs_t
|
| 236 |
|
|
get_virtual_field (gs_t type_tree)
|
| 237 |
|
|
{
|
| 238 |
|
|
gs_t vfield;
|
| 239 |
|
|
|
| 240 |
|
|
// return vfield only if the type contains fields (bug 10787)
|
| 241 |
|
|
if (lang_cplus &&
|
| 242 |
|
|
gs_type_fields(type_tree) &&
|
| 243 |
|
|
(vfield = gs_type_vfield(type_tree)) != NULL)
|
| 244 |
|
|
return vfield;
|
| 245 |
|
|
return NULL;
|
| 246 |
|
|
}
|
| 247 |
|
|
|
| 248 |
|
|
gs_t
|
| 249 |
|
|
get_first_real_field (gs_t type_tree)
|
| 250 |
|
|
{
|
| 251 |
|
|
gs_t field = gs_type_fields(type_tree);
|
| 252 |
|
|
|
| 253 |
|
|
if (!field)
|
| 254 |
|
|
return NULL;
|
| 255 |
|
|
|
| 256 |
|
|
// If there is a pointer to the virtual function table, it is always at the
|
| 257 |
|
|
// first field.
|
| 258 |
|
|
if (field == gs_type_vfield(type_tree))
|
| 259 |
|
|
{
|
| 260 |
|
|
Is_True (lang_cplus, ("get_first_real_field: TYPE_VFIELD used for C"));
|
| 261 |
|
|
return gs_tree_chain(field);
|
| 262 |
|
|
}
|
| 263 |
|
|
return field;
|
| 264 |
|
|
}
|
| 265 |
|
|
|
| 266 |
|
|
gs_t
|
| 267 |
|
|
next_real_field (gs_t type_tree, gs_t field)
|
| 268 |
|
|
{
|
| 269 |
|
|
BOOL first_real_field = FALSE;
|
| 270 |
|
|
|
| 271 |
|
|
if (field == gs_type_vfield(type_tree))
|
| 272 |
|
|
{
|
| 273 |
1411 |
laijx |
#if 0 // bug 13102
|
| 274 |
736 |
fengzhou |
Is_True (lang_cplus, ("next_real_field: TYPE_VFIELD used for C"));
|
| 275 |
1150 |
rhundt |
#endif
|
| 276 |
736 |
fengzhou |
first_real_field = TRUE; // return first real field
|
| 277 |
|
|
}
|
| 278 |
|
|
|
| 279 |
|
|
// If vptr is not in the list of fields, then return the first field
|
| 280 |
|
|
if (first_real_field && field != gs_type_fields (type_tree))
|
| 281 |
|
|
return gs_type_fields (type_tree);
|
| 282 |
|
|
|
| 283 |
|
|
// Else return the next field.
|
| 284 |
|
|
return gs_tree_chain (field);
|
| 285 |
|
|
}
|
| 286 |
|
|
|
| 287 |
|
|
static void
|
| 288 |
|
|
Do_Base_Types (gs_t type_tree)
|
| 289 |
|
|
{
|
| 290 |
|
|
gs_t binfo = gs_type_binfo(type_tree);
|
| 291 |
|
|
gs_t basetypes = binfo ? gs_binfo_base_binfos(binfo) : 0;
|
| 292 |
|
|
gs_t list;
|
| 293 |
|
|
if (basetypes) {
|
| 294 |
|
|
for (list = basetypes; gs_code(list) != EMPTY; list = gs_operand(list, 1))
|
| 295 |
|
|
(void) Get_TY (gs_binfo_type(gs_operand(list, 0)));
|
| 296 |
|
|
}
|
| 297 |
|
|
}
|
| 298 |
|
|
|
| 299 |
|
|
size_t
|
| 300 |
|
|
Roundup (size_t offset, int alignment)
|
| 301 |
|
|
{
|
| 302 |
|
|
return (offset % alignment) ? offset + alignment - offset % alignment
|
| 303 |
|
|
: offset;
|
| 304 |
|
|
}
|
| 305 |
|
|
|
| 306 |
|
|
size_t
|
| 307 |
|
|
Type_Size_Without_Vbases (gs_t type_tree)
|
| 308 |
|
|
{
|
| 309 |
|
|
gs_t field;
|
| 310 |
|
|
gs_t last_field_decl = 0;
|
| 311 |
|
|
|
| 312 |
|
|
for (field = get_first_real_or_virtual_field(type_tree);
|
| 313 |
|
|
field;
|
| 314 |
|
|
field = next_real_field (type_tree, field)) {
|
| 315 |
|
|
if (gs_tree_code(field) == GS_FIELD_DECL)
|
| 316 |
|
|
last_field_decl = field;
|
| 317 |
|
|
}
|
| 318 |
|
|
|
| 319 |
|
|
if (last_field_decl == 0)
|
| 320 |
|
|
return 0;
|
| 321 |
|
|
|
| 322 |
|
|
return
|
| 323 |
|
|
gs_get_integer_value (gs_decl_field_offset(last_field_decl)) +
|
| 324 |
|
|
gs_get_integer_value (gs_decl_field_bit_offset(last_field_decl)) / BITSPERBYTE +
|
| 325 |
|
|
gs_get_integer_value (gs_decl_size(last_field_decl)) / BITSPERBYTE;
|
| 326 |
|
|
}
|
| 327 |
|
|
|
| 328 |
|
|
bool
|
| 329 |
|
|
is_empty_base_class (gs_t type_tree)
|
| 330 |
|
|
{
|
| 331 |
|
|
gs_t field = gs_type_fields(type_tree);
|
| 332 |
|
|
return gs_tree_code(field) == GS_TYPE_DECL && gs_tree_chain(field) == 0;
|
| 333 |
|
|
}
|
| 334 |
|
|
|
| 335 |
|
|
// look up the attribute given by attr_name in the attribute list
|
| 336 |
1950 |
laijx |
gs_t
|
| 337 |
736 |
fengzhou |
lookup_attribute(char *attr_name, gs_t attr_list)
|
| 338 |
|
|
{
|
| 339 |
|
|
gs_t nd;
|
| 340 |
|
|
for (nd = attr_list; nd; nd = gs_tree_chain(nd)) {
|
| 341 |
|
|
Is_True(gs_tree_code(nd) == GS_TREE_LIST,
|
| 342 |
|
|
("lookup_attributes: TREE_LIST node not found"));
|
| 343 |
|
|
gs_t attr = gs_tree_purpose(nd);
|
| 344 |
1950 |
laijx |
if (is_attribute(attr_name, attr))
|
| 345 |
|
|
return nd;
|
| 346 |
736 |
fengzhou |
}
|
| 347 |
1950 |
laijx |
return NULL;
|
| 348 |
736 |
fengzhou |
}
|
| 349 |
|
|
|
| 350 |
|
|
// idx is non-zero only for RECORD and UNION, when there is forward declaration
|
| 351 |
|
|
extern TY_IDX
|
| 352 |
|
|
Create_TY_For_Tree (gs_t type_tree, TY_IDX idx)
|
| 353 |
|
|
{
|
| 354 |
|
|
|
| 355 |
|
|
if(gs_tree_code(type_tree) == GS_ERROR_MARK)
|
| 356 |
|
|
return idx;
|
| 357 |
|
|
|
| 358 |
|
|
TY_IDX orig_idx = idx;
|
| 359 |
|
|
if(gs_tree_code_class(type_tree) != GS_TCC_TYPE) {
|
| 360 |
|
|
DevWarn("Bad tree class passed to Create_TY_For_Tree %c",
|
| 361 |
|
|
gs_tree_code_class(type_tree));
|
| 362 |
|
|
return idx;
|
| 363 |
|
|
}
|
| 364 |
|
|
|
| 365 |
|
|
|
| 366 |
|
|
#ifdef KEY
|
| 367 |
|
|
UINT align = gs_type_align(type_tree) / BITSPERBYTE;
|
| 368 |
|
|
#endif
|
| 369 |
|
|
// for typedefs get the information from the base type
|
| 370 |
|
|
if (gs_type_name(type_tree) &&
|
| 371 |
|
|
idx == 0 &&
|
| 372 |
|
|
(gs_tree_code(type_tree) == GS_RECORD_TYPE ||
|
| 373 |
|
|
gs_tree_code(type_tree) == GS_UNION_TYPE) &&
|
| 374 |
|
|
gs_tree_code(gs_type_name(type_tree)) == GS_TYPE_DECL &&
|
| 375 |
|
|
gs_type_main_variant(type_tree) != type_tree) {
|
| 376 |
|
|
idx = Get_TY (gs_type_main_variant(type_tree));
|
| 377 |
|
|
if (gs_type_readonly(type_tree))
|
| 378 |
|
|
Set_TY_is_const (idx);
|
| 379 |
|
|
if (gs_type_volatile(type_tree))
|
| 380 |
|
|
Set_TY_is_volatile (idx);
|
| 381 |
|
|
#ifdef KEY
|
| 382 |
|
|
if (gs_type_restrict(type_tree))
|
| 383 |
|
|
Set_TY_is_restrict (idx);
|
| 384 |
|
|
Set_TY_align (idx, align); // bug 10533
|
| 385 |
|
|
#endif
|
| 386 |
|
|
TYPE_TY_IDX(type_tree) = idx;
|
| 387 |
|
|
if(Debug_Level >= 2) {
|
| 388 |
860 |
hucheng |
#ifdef KEY // bug 11782
|
| 389 |
|
|
defer_DST_type(type_tree, idx, orig_idx);
|
| 390 |
|
|
#else
|
| 391 |
736 |
fengzhou |
DST_INFO_IDX dst = Create_DST_type_For_Tree(type_tree,
|
| 392 |
|
|
idx,orig_idx);
|
| 393 |
|
|
TYPE_DST_IDX(type_tree) = dst;
|
| 394 |
860 |
hucheng |
#endif
|
| 395 |
736 |
fengzhou |
}
|
| 396 |
|
|
TYPE_FIELD_IDS_USED(type_tree) =
|
| 397 |
|
|
TYPE_FIELD_IDS_USED(gs_type_main_variant(type_tree));
|
| 398 |
|
|
return idx;
|
| 399 |
|
|
}
|
| 400 |
|
|
|
| 401 |
|
|
TYPE_ID mtype;
|
| 402 |
|
|
INT64 tsize;
|
| 403 |
|
|
BOOL variable_size = FALSE;
|
| 404 |
|
|
gs_t type_size = gs_type_size(type_tree);
|
| 405 |
|
|
#ifndef KEY
|
| 406 |
|
|
UINT align = gs_type_align(type_tree) / BITSPERBYTE;
|
| 407 |
|
|
#endif
|
| 408 |
|
|
if (type_size == NULL) {
|
| 409 |
|
|
// incomplete structs have 0 size. Similarly, 'void' is
|
| 410 |
|
|
// an incomplete type that can never be completed.
|
| 411 |
|
|
FmtAssert(gs_tree_code(type_tree) == GS_ARRAY_TYPE
|
| 412 |
|
|
|| gs_tree_code(type_tree) == GS_ENUMERAL_TYPE
|
| 413 |
|
|
|| gs_tree_code(type_tree) == GS_UNION_TYPE
|
| 414 |
|
|
|| gs_tree_code(type_tree) == GS_RECORD_TYPE
|
| 415 |
|
|
|| gs_tree_code(type_tree) == GS_LANG_TYPE
|
| 416 |
|
|
|| gs_tree_code(type_tree) == GS_FUNCTION_TYPE
|
| 417 |
|
|
|| gs_tree_code(type_tree) == GS_VOID_TYPE,
|
| 418 |
|
|
("Create_TY_For_Tree: type_size NULL for non ARRAY/RECORD/VOID, type is %d",
|
| 419 |
|
|
(int) gs_tree_code(type_tree)));
|
| 420 |
|
|
tsize = 0;
|
| 421 |
|
|
}
|
| 422 |
|
|
else {
|
| 423 |
|
|
if (gs_tree_code(type_size) != GS_INTEGER_CST) {
|
| 424 |
|
|
if (gs_tree_code(type_tree) == GS_ARRAY_TYPE)
|
| 425 |
|
|
DevWarn ("Encountered VLA at line %d", lineno);
|
| 426 |
|
|
else
|
| 427 |
|
|
#ifndef KEY
|
| 428 |
|
|
Fail_FmtAssertion ("VLA at line %d not currently implemented", lineno);
|
| 429 |
|
|
#else
|
| 430 |
|
|
// bugs 943, 11277, 10506
|
| 431 |
2694 |
shenruifen |
#if defined(TARG_SL)
|
| 432 |
|
|
ErrMsg(EC_Unimplemented_Feature, "variable-length structure",
|
| 433 |
|
|
Orig_Src_File_Name?Orig_Src_File_Name:Src_File_Name, lineno);
|
| 434 |
|
|
#else
|
| 435 |
|
|
ErrMsg(EC_Unimplemented_Feature, "variable-length structure");
|
| 436 |
736 |
fengzhou |
#endif
|
| 437 |
2694 |
shenruifen |
#endif
|
| 438 |
736 |
fengzhou |
variable_size = TRUE;
|
| 439 |
|
|
tsize = 0;
|
| 440 |
|
|
}
|
| 441 |
|
|
else
|
| 442 |
|
|
#ifdef KEY // bug 3045
|
| 443 |
|
|
tsize = (gs_get_integer_value(type_size) + BITSPERBYTE - 1)
|
| 444 |
|
|
/ BITSPERBYTE;
|
| 445 |
|
|
#else
|
| 446 |
|
|
tsize = gs_get_integer_value(type_size) / BITSPERBYTE;
|
| 447 |
|
|
#endif
|
| 448 |
|
|
}
|
| 449 |
|
|
switch (gs_tree_code(type_tree)) {
|
| 450 |
|
|
case GS_VOID_TYPE:
|
| 451 |
|
|
case GS_LANG_TYPE: // unknown type
|
| 452 |
|
|
idx = MTYPE_To_TY (MTYPE_V); // use predefined type
|
| 453 |
|
|
break;
|
| 454 |
|
|
case GS_BOOLEAN_TYPE:
|
| 455 |
|
|
case GS_INTEGER_TYPE:
|
| 456 |
|
|
case GS_OFFSET_TYPE:
|
| 457 |
|
|
switch (tsize) {
|
| 458 |
|
|
case 1: mtype = MTYPE_I1; break;
|
| 459 |
|
|
case 2: mtype = MTYPE_I2; break;
|
| 460 |
|
|
case 4: mtype = MTYPE_I4; break;
|
| 461 |
|
|
case 8: mtype = MTYPE_I8; break;
|
| 462 |
1411 |
laijx |
#if !defined(TARG_X8664) && !defined(TARG_MIPS) // Bug 12358
|
| 463 |
736 |
fengzhou |
#ifdef _LP64
|
| 464 |
|
|
case 16: mtype = MTYPE_I8; break;
|
| 465 |
|
|
#endif /* _LP64 */
|
| 466 |
|
|
#else
|
| 467 |
|
|
// needed for compiling variable length array
|
| 468 |
|
|
// as in gcc.c-torture/execute/920929-1.c
|
| 469 |
|
|
// we need to fix the rest of the compiler
|
| 470 |
|
|
// with _LP64 but seems to work fine without.
|
| 471 |
|
|
case 16: mtype = MTYPE_I8; break;
|
| 472 |
|
|
#endif /* KEY */
|
| 473 |
|
|
default: FmtAssert(FALSE,
|
| 474 |
|
|
("Get_TY unexpected size %d", tsize));
|
| 475 |
|
|
}
|
| 476 |
|
|
if (gs_decl_unsigned(type_tree)) {
|
| 477 |
|
|
mtype = MTYPE_complement(mtype);
|
| 478 |
|
|
}
|
| 479 |
|
|
#ifdef KEY
|
| 480 |
1950 |
laijx |
if (lookup_attribute("may_alias",gs_type_attributes(type_tree)))
|
| 481 |
736 |
fengzhou |
{
|
| 482 |
|
|
// bug 9975: Handle may_alias attribute, we need to create
|
| 483 |
|
|
// a new type to which we can attach the flag.
|
| 484 |
|
|
TY &ty = New_TY (idx);
|
| 485 |
|
|
TY_Init (ty, tsize, KIND_SCALAR, mtype,
|
| 486 |
|
|
Save_Str(Get_Name(gs_type_name(type_tree))) );
|
| 487 |
|
|
Set_TY_no_ansi_alias (ty);
|
| 488 |
2694 |
shenruifen |
#if defined(TARG_SL)
|
| 489 |
|
|
// for -m32, it is not the predefined type, alignment shoule be set.
|
| 490 |
|
|
// Corresponding to following code about bug#2932.
|
| 491 |
|
|
if (!TARGET_64BIT)
|
| 492 |
|
|
Set_TY_align (idx, align);
|
| 493 |
|
|
#endif
|
| 494 |
736 |
fengzhou |
} else
|
| 495 |
|
|
#endif
|
| 496 |
|
|
idx = MTYPE_To_TY (mtype); // use predefined type
|
| 497 |
2694 |
shenruifen |
#if defined(TARG_X8664) || defined(TARG_SL)
|
| 498 |
736 |
fengzhou |
/* At least for -m32, the alignment is not the same as the data
|
| 499 |
|
|
type's natural size. (bug#2932)
|
| 500 |
|
|
*/
|
| 501 |
|
|
if( TARGET_64BIT )
|
| 502 |
|
|
#endif // TARG_X8664
|
| 503 |
|
|
Set_TY_align (idx, align);
|
| 504 |
|
|
break;
|
| 505 |
|
|
case GS_CHAR_TYPE:
|
| 506 |
|
|
mtype = (gs_decl_unsigned(type_tree) ? MTYPE_U1 : MTYPE_I1);
|
| 507 |
|
|
idx = MTYPE_To_TY (mtype); // use predefined type
|
| 508 |
|
|
break;
|
| 509 |
|
|
case GS_ENUMERAL_TYPE:
|
| 510 |
|
|
#ifdef KEY
|
| 511 |
1950 |
laijx |
switch (tsize) {
|
| 512 |
|
|
case 1: // bug 14445
|
| 513 |
|
|
mtype = (gs_decl_unsigned(type_tree) ? MTYPE_U1 :
|
| 514 |
|
|
MTYPE_I1);
|
| 515 |
|
|
break;
|
| 516 |
|
|
case 2: // bug 14445
|
| 517 |
|
|
mtype = (gs_decl_unsigned(type_tree) ? MTYPE_U2 :
|
| 518 |
|
|
MTYPE_I2);
|
| 519 |
|
|
break;
|
| 520 |
|
|
case 8: // bug 500
|
| 521 |
|
|
mtype = (gs_decl_unsigned(type_tree) ? MTYPE_U8 :
|
| 522 |
|
|
MTYPE_I8);
|
| 523 |
|
|
break;
|
| 524 |
|
|
default:
|
| 525 |
|
|
mtype = (gs_decl_unsigned(type_tree) ? MTYPE_U4 :
|
| 526 |
|
|
MTYPE_I4);
|
| 527 |
736 |
fengzhou |
}
|
| 528 |
1950 |
laijx |
#else
|
| 529 |
|
|
mtype = (gs_decl_unsigned(type_tree) ? MTYPE_U4 : MTYPE_I4);
|
| 530 |
736 |
fengzhou |
#endif
|
| 531 |
|
|
idx = MTYPE_To_TY (mtype); // use predefined type
|
| 532 |
|
|
break;
|
| 533 |
|
|
case GS_REAL_TYPE:
|
| 534 |
|
|
switch (tsize) {
|
| 535 |
|
|
case 4: mtype = MTYPE_F4; break;
|
| 536 |
|
|
case 8: mtype = MTYPE_F8; break;
|
| 537 |
866 |
hucheng |
#ifdef TARG_IA64
|
| 538 |
|
|
case 12:
|
| 539 |
|
|
case 16: mtype = MTYPE_F10; break;
|
| 540 |
|
|
#endif
|
| 541 |
736 |
fengzhou |
#ifdef TARG_X8664
|
| 542 |
|
|
case 12: mtype = MTYPE_FQ; break;
|
| 543 |
|
|
#endif
|
| 544 |
|
|
#if defined(TARG_MIPS) || defined(TARG_IA32) || defined(TARG_X8664)
|
| 545 |
|
|
case 16: mtype = MTYPE_FQ; break;
|
| 546 |
|
|
#endif /* TARG_MIPS */
|
| 547 |
|
|
default: FmtAssert(FALSE, ("Get_TY unexpected size"));
|
| 548 |
|
|
}
|
| 549 |
|
|
idx = MTYPE_To_TY (mtype); // use predefined type
|
| 550 |
|
|
break;
|
| 551 |
|
|
case GS_COMPLEX_TYPE:
|
| 552 |
|
|
switch (tsize) {
|
| 553 |
|
|
case 2:
|
| 554 |
|
|
case 4: ErrMsg (EC_Unsupported_Type, "Complex integer");
|
| 555 |
|
|
case 8: mtype = MTYPE_C4; break;
|
| 556 |
|
|
case 16: mtype = MTYPE_C8; break;
|
| 557 |
866 |
hucheng |
#ifdef TARG_IA64
|
| 558 |
|
|
case 32: mtype = MTYPE_C10; break;
|
| 559 |
|
|
#endif
|
| 560 |
736 |
fengzhou |
#ifdef TARG_X8664
|
| 561 |
|
|
case 24: mtype = MTYPE_CQ; break;
|
| 562 |
|
|
#endif
|
| 563 |
|
|
#if defined(TARG_MIPS) || defined(TARG_IA32) || defined(TARG_X8664)
|
| 564 |
|
|
case 32: mtype = MTYPE_CQ; break;
|
| 565 |
|
|
#endif /* TARG_MIPS */
|
| 566 |
|
|
default: FmtAssert(FALSE, ("Get_TY unexpected size"));
|
| 567 |
|
|
}
|
| 568 |
|
|
idx = MTYPE_To_TY (mtype); // use predefined type
|
| 569 |
|
|
break;
|
| 570 |
|
|
case GS_POINTER_TYPE:
|
| 571 |
|
|
if (gs_type_ptrmem_p(type_tree)) {
|
| 572 |
|
|
// pointer to member
|
| 573 |
|
|
idx = Be_Type_Tbl(Pointer_Size == 8 ? MTYPE_I8 : MTYPE_I4);
|
| 574 |
|
|
break;
|
| 575 |
|
|
}
|
| 576 |
|
|
/* FALLTHRU */
|
| 577 |
|
|
case GS_REFERENCE_TYPE:
|
| 578 |
|
|
idx = Make_Pointer_Type (Get_TY (gs_tree_type(type_tree)));
|
| 579 |
|
|
Set_TY_align (idx, align);
|
| 580 |
|
|
break;
|
| 581 |
|
|
case GS_ARRAY_TYPE:
|
| 582 |
|
|
{ // new scope for local vars
|
| 583 |
860 |
hucheng |
#ifdef KEY /* bug 8346 */
|
| 584 |
|
|
TY &ty = (idx == TY_IDX_ZERO) ? New_TY(idx) : Ty_Table[idx];
|
| 585 |
|
|
Clear_TY_is_incomplete (idx);
|
| 586 |
|
|
#else
|
| 587 |
736 |
fengzhou |
TY &ty = New_TY (idx);
|
| 588 |
860 |
hucheng |
#endif
|
| 589 |
736 |
fengzhou |
TY_Init (ty, tsize, KIND_ARRAY, MTYPE_M,
|
| 590 |
|
|
Save_Str(Get_Name(gs_type_name(type_tree))) );
|
| 591 |
979 |
shiyao |
// for the anonymoust array
|
| 592 |
|
|
if (gs_type_name(type_tree) == NULL)
|
| 593 |
|
|
Set_TY_anonymous(ty);
|
| 594 |
736 |
fengzhou |
Set_TY_etype (ty, Get_TY (gs_tree_type(type_tree)));
|
| 595 |
|
|
Set_TY_align (idx, TY_align(TY_etype(ty)));
|
| 596 |
|
|
// assumes 1 dimension
|
| 597 |
|
|
// nested arrays are treated as arrays of arrays
|
| 598 |
|
|
ARB_HANDLE arb = New_ARB ();
|
| 599 |
|
|
ARB_Init (arb, 0, 0, 0);
|
| 600 |
|
|
Set_TY_arb (ty, arb);
|
| 601 |
|
|
Set_ARB_first_dimen (arb);
|
| 602 |
|
|
Set_ARB_last_dimen (arb);
|
| 603 |
|
|
Set_ARB_dimension (arb, 1);
|
| 604 |
|
|
if (gs_type_size(gs_tree_type(type_tree)) == 0)
|
| 605 |
|
|
break; // anomaly: type will never be needed
|
| 606 |
860 |
hucheng |
|
| 607 |
|
|
// =================== Array stride ======================
|
| 608 |
736 |
fengzhou |
if (gs_tree_code(gs_type_size(gs_tree_type(type_tree))) == GS_INTEGER_CST) {
|
| 609 |
|
|
Set_ARB_const_stride (arb);
|
| 610 |
|
|
Set_ARB_stride_val (arb,
|
| 611 |
2694 |
shenruifen |
gs_get_integer_value (gs_type_size_unit(gs_tree_type(type_tree))));
|
| 612 |
736 |
fengzhou |
}
|
| 613 |
860 |
hucheng |
#ifdef KEY /* bug 8346 */
|
| 614 |
|
|
else if (!expanding_function_definition &&
|
| 615 |
|
|
processing_function_prototype)
|
| 616 |
|
|
{
|
| 617 |
|
|
Set_ARB_const_stride (arb);
|
| 618 |
|
|
// dummy stride val 4
|
| 619 |
|
|
Set_ARB_stride_val (arb, 4);
|
| 620 |
|
|
Set_TY_is_incomplete (idx);
|
| 621 |
|
|
}
|
| 622 |
|
|
#endif
|
| 623 |
736 |
fengzhou |
else {
|
| 624 |
|
|
WN *swn;
|
| 625 |
2694 |
shenruifen |
swn = WGEN_Expand_Expr (gs_type_size_unit(gs_tree_type(type_tree)));
|
| 626 |
736 |
fengzhou |
if (WN_opcode (swn) == OPC_U4I4CVT ||
|
| 627 |
|
|
WN_opcode (swn) == OPC_U8I8CVT) {
|
| 628 |
|
|
swn = WN_kid0 (swn);
|
| 629 |
|
|
}
|
| 630 |
|
|
#ifdef KEY
|
| 631 |
|
|
// In the event that swn operator is not
|
| 632 |
|
|
// OPR_LDID, save expr node swn
|
| 633 |
|
|
// and use LDID of that stored address as swn.
|
| 634 |
|
|
// Copied from Wfe_Save_Expr in wfe_expr.cxx
|
| 635 |
|
|
if (WN_operator (swn) != OPR_LDID) {
|
| 636 |
2694 |
shenruifen |
|
| 637 |
|
|
TYPE_ID mtype = WN_rtype(swn);
|
| 638 |
|
|
TY_IDX ty_idx = MTYPE_To_TY(mtype);
|
| 639 |
736 |
fengzhou |
ST *st;
|
| 640 |
|
|
st = Gen_Temp_Symbol (ty_idx, "__save_expr");
|
| 641 |
1411 |
laijx |
#ifdef FE_GNU_4_2_0
|
| 642 |
|
|
WGEN_add_pragma_to_enclosing_regions (WN_PRAGMA_LOCAL, st);
|
| 643 |
|
|
#endif
|
| 644 |
736 |
fengzhou |
WGEN_Set_ST_Addr_Saved (swn);
|
| 645 |
|
|
swn = WN_Stid (mtype, 0, st, ty_idx, swn);
|
| 646 |
|
|
WGEN_Stmt_Append (swn, Get_Srcpos());
|
| 647 |
|
|
swn = WN_Ldid (mtype, 0, st, ty_idx);
|
| 648 |
|
|
}
|
| 649 |
|
|
#endif /* KEY */
|
| 650 |
|
|
FmtAssert (WN_operator (swn) == OPR_LDID,
|
| 651 |
|
|
("stride operator for VLA not LDID"));
|
| 652 |
|
|
ST *st = WN_st (swn);
|
| 653 |
|
|
TY_IDX ty_idx = ST_type (st);
|
| 654 |
|
|
WN *wn = WN_CreateXpragma (WN_PRAGMA_COPYIN_BOUND,
|
| 655 |
|
|
(ST_IDX) NULL, 1);
|
| 656 |
|
|
WN_kid0 (wn) = WN_Ldid (TY_mtype (ty_idx), 0, st, ty_idx);
|
| 657 |
|
|
WGEN_Stmt_Append (wn, Get_Srcpos());
|
| 658 |
|
|
Clear_ARB_const_stride (arb);
|
| 659 |
|
|
Set_ARB_stride_var (arb, (ST_IDX) ST_st_idx (st));
|
| 660 |
860 |
hucheng |
#ifdef KEY /* bug 8346 */
|
| 661 |
|
|
Clear_TY_is_incomplete (idx);
|
| 662 |
|
|
#endif
|
| 663 |
736 |
fengzhou |
}
|
| 664 |
860 |
hucheng |
|
| 665 |
|
|
// ================= Array lower bound =================
|
| 666 |
736 |
fengzhou |
Set_ARB_const_lbnd (arb);
|
| 667 |
|
|
Set_ARB_lbnd_val (arb, 0);
|
| 668 |
860 |
hucheng |
|
| 669 |
|
|
// ================= Array upper bound =================
|
| 670 |
736 |
fengzhou |
if (type_size) {
|
| 671 |
|
|
#ifdef KEY
|
| 672 |
|
|
// For Zero-length arrays, TYPE_MAX_VALUE tree is NULL
|
| 673 |
|
|
if (!gs_type_max_value (gs_type_domain (type_tree))) {
|
| 674 |
|
|
Set_ARB_const_ubnd (arb);
|
| 675 |
|
|
Set_ARB_ubnd_val (arb, 0xffffffff);
|
| 676 |
|
|
} else
|
| 677 |
|
|
#endif /* KEY */
|
| 678 |
|
|
if (gs_tree_code(gs_type_max_value (gs_type_domain (type_tree))) ==
|
| 679 |
|
|
GS_INTEGER_CST) {
|
| 680 |
|
|
Set_ARB_const_ubnd (arb);
|
| 681 |
|
|
Set_ARB_ubnd_val (arb, gs_get_integer_value (
|
| 682 |
|
|
gs_type_max_value (gs_type_domain (type_tree)) ));
|
| 683 |
|
|
}
|
| 684 |
860 |
hucheng |
#ifdef KEY /* bug 8346 */
|
| 685 |
|
|
else if (!expanding_function_definition &&
|
| 686 |
|
|
processing_function_prototype) {
|
| 687 |
|
|
Set_ARB_const_ubnd (arb);
|
| 688 |
|
|
// dummy upper bound 8
|
| 689 |
|
|
Set_ARB_ubnd_val (arb, 8);
|
| 690 |
|
|
Set_TY_is_incomplete (idx);
|
| 691 |
|
|
}
|
| 692 |
|
|
#endif
|
| 693 |
736 |
fengzhou |
else {
|
| 694 |
|
|
WN *uwn = WGEN_Expand_Expr (gs_type_max_value (gs_type_domain (type_tree)) );
|
| 695 |
|
|
if (WN_opcode (uwn) == OPC_U4I4CVT ||
|
| 696 |
|
|
WN_opcode (uwn) == OPC_U8I8CVT) {
|
| 697 |
|
|
uwn = WN_kid0 (uwn);
|
| 698 |
|
|
}
|
| 699 |
|
|
ST *st;
|
| 700 |
|
|
TY_IDX ty_idx;
|
| 701 |
|
|
WN *wn;
|
| 702 |
|
|
if (WN_operator (uwn) != OPR_LDID) {
|
| 703 |
2694 |
shenruifen |
ty_idx = MTYPE_To_TY(WN_rtype(uwn));
|
| 704 |
736 |
fengzhou |
st = Gen_Temp_Symbol (ty_idx, "__vla_bound");
|
| 705 |
1411 |
laijx |
#ifdef FE_GNU_4_2_0
|
| 706 |
|
|
WGEN_add_pragma_to_enclosing_regions (WN_PRAGMA_LOCAL, st);
|
| 707 |
736 |
fengzhou |
#endif
|
| 708 |
|
|
wn = WN_Stid (TY_mtype (ty_idx), 0, st, ty_idx, uwn);
|
| 709 |
|
|
WGEN_Stmt_Append (wn, Get_Srcpos());
|
| 710 |
|
|
}
|
| 711 |
|
|
else {
|
| 712 |
|
|
st = WN_st (uwn);
|
| 713 |
|
|
ty_idx = ST_type (st);
|
| 714 |
|
|
}
|
| 715 |
|
|
wn = WN_CreateXpragma (WN_PRAGMA_COPYIN_BOUND, (ST_IDX) NULL, 1);
|
| 716 |
|
|
WN_kid0 (wn) = WN_Ldid (TY_mtype (ty_idx), 0, st, ty_idx);
|
| 717 |
|
|
WGEN_Stmt_Append (wn, Get_Srcpos());
|
| 718 |
|
|
Clear_ARB_const_ubnd (arb);
|
| 719 |
|
|
Set_ARB_ubnd_var (arb, ST_st_idx (st));
|
| 720 |
860 |
hucheng |
#ifdef KEY /* bug 8346 */
|
| 721 |
|
|
Clear_TY_is_incomplete (idx);
|
| 722 |
|
|
#endif
|
| 723 |
736 |
fengzhou |
}
|
| 724 |
|
|
}
|
| 725 |
|
|
else {
|
| 726 |
|
|
Clear_ARB_const_ubnd (arb);
|
| 727 |
|
|
Set_ARB_ubnd_val (arb, 0);
|
| 728 |
|
|
}
|
| 729 |
860 |
hucheng |
|
| 730 |
|
|
// ==================== Array size ====================
|
| 731 |
736 |
fengzhou |
if (variable_size) {
|
| 732 |
860 |
hucheng |
#ifdef KEY /* bug 8346 */
|
| 733 |
|
|
if (!expanding_function_definition &&
|
| 734 |
|
|
processing_function_prototype) {
|
| 735 |
|
|
Set_TY_is_incomplete (idx);
|
| 736 |
|
|
}
|
| 737 |
|
|
else
|
| 738 |
|
|
#endif
|
| 739 |
|
|
{
|
| 740 |
736 |
fengzhou |
WN *swn, *wn;
|
| 741 |
2694 |
shenruifen |
swn = WGEN_Expand_Expr (gs_type_size_unit(type_tree));
|
| 742 |
736 |
fengzhou |
if (TY_size(TY_etype(ty))) {
|
| 743 |
|
|
if (WN_opcode (swn) == OPC_U4I4CVT ||
|
| 744 |
|
|
WN_opcode (swn) == OPC_U8I8CVT) {
|
| 745 |
|
|
swn = WN_kid0 (swn);
|
| 746 |
|
|
}
|
| 747 |
|
|
#ifdef KEY
|
| 748 |
|
|
// In the event that swn operator is not
|
| 749 |
|
|
// OPR_LDID, save expr node swn
|
| 750 |
|
|
// and use LDID of that stored address as swn.
|
| 751 |
|
|
// Copied from Wfe_Save_Expr in wfe_expr.cxx
|
| 752 |
|
|
if (WN_operator (swn) != OPR_LDID) {
|
| 753 |
2694 |
shenruifen |
TYPE_ID mtype = WN_rtype(swn);
|
| 754 |
|
|
TY_IDX ty_idx = MTYPE_To_TY(mtype);
|
| 755 |
736 |
fengzhou |
ST *st;
|
| 756 |
|
|
st = Gen_Temp_Symbol (ty_idx, "__save_expr");
|
| 757 |
1411 |
laijx |
#ifdef FE_GNU_4_2_0
|
| 758 |
|
|
WGEN_add_pragma_to_enclosing_regions (WN_PRAGMA_LOCAL, st);
|
| 759 |
|
|
#endif
|
| 760 |
736 |
fengzhou |
WGEN_Set_ST_Addr_Saved (swn);
|
| 761 |
|
|
swn = WN_Stid (mtype, 0, st, ty_idx, swn);
|
| 762 |
|
|
WGEN_Stmt_Append (swn, Get_Srcpos());
|
| 763 |
|
|
swn = WN_Ldid (mtype, 0, st, ty_idx);
|
| 764 |
|
|
}
|
| 765 |
|
|
#endif /* KEY */
|
| 766 |
|
|
FmtAssert (WN_operator (swn) == OPR_LDID,
|
| 767 |
|
|
("size operator for VLA not LDID"));
|
| 768 |
|
|
ST *st = WN_st (swn);
|
| 769 |
|
|
TY_IDX ty_idx = ST_type (st);
|
| 770 |
|
|
TYPE_ID mtype = TY_mtype (ty_idx);
|
| 771 |
2694 |
shenruifen |
|
| 772 |
736 |
fengzhou |
wn = WN_Stid (mtype, 0, st, ty_idx, swn);
|
| 773 |
|
|
WGEN_Stmt_Append (wn, Get_Srcpos());
|
| 774 |
|
|
}
|
| 775 |
860 |
hucheng |
#ifdef KEY /* bug 8346 */
|
| 776 |
|
|
Clear_TY_is_incomplete (idx);
|
| 777 |
|
|
#endif
|
| 778 |
|
|
}
|
| 779 |
736 |
fengzhou |
}
|
| 780 |
|
|
} // end array scope
|
| 781 |
|
|
break;
|
| 782 |
|
|
case GS_RECORD_TYPE:
|
| 783 |
|
|
case GS_UNION_TYPE:
|
| 784 |
|
|
{ // new scope for local vars
|
| 785 |
|
|
|
| 786 |
|
|
TY &ty = (idx == TY_IDX_ZERO) ? New_TY(idx) : Ty_Table[idx];
|
| 787 |
|
|
#ifdef KEY
|
| 788 |
|
|
// Must create DSTs in the order that the records are declared,
|
| 789 |
|
|
// in order to preserve their scope. Bug 4168.
|
| 790 |
|
|
if (Debug_Level >= 2)
|
| 791 |
|
|
defer_DST_type(type_tree, idx, orig_idx);
|
| 792 |
|
|
|
| 793 |
|
|
// GCC 3.2 pads empty structures with a fake 1-byte field.
|
| 794 |
|
|
// These structures should have tsize = 0.
|
| 795 |
|
|
if (tsize != 0 &&
|
| 796 |
|
|
// is_empty_class assumes non-null CLASSTYPE_SIZE
|
| 797 |
|
|
// check if it has lang-specific data
|
| 798 |
|
|
gs_type_lang_specific(type_tree) &&
|
| 799 |
|
|
// check if it has its base version set
|
| 800 |
|
|
gs_classtype_as_base(type_tree) &&
|
| 801 |
|
|
gs_classtype_size(type_tree) &&
|
| 802 |
|
|
gs_is_empty_class(type_tree))
|
| 803 |
|
|
tsize = 0;
|
| 804 |
|
|
#endif // KEY
|
| 805 |
|
|
TY_Init (ty, tsize, KIND_STRUCT, MTYPE_M,
|
| 806 |
|
|
Save_Str(Get_Name(gs_type_name(type_tree))) );
|
| 807 |
962 |
shiyao |
|
| 808 |
|
|
if (gs_type_name(type_tree) == NULL)
|
| 809 |
|
|
Set_TY_anonymous(ty);
|
| 810 |
|
|
|
| 811 |
736 |
fengzhou |
if (gs_tree_code(type_tree) == GS_UNION_TYPE) {
|
| 812 |
|
|
Set_TY_is_union(idx);
|
| 813 |
|
|
}
|
| 814 |
|
|
#ifdef KEY
|
| 815 |
|
|
if (gs_aggregate_value_p(type_tree)) {
|
| 816 |
|
|
Set_TY_return_in_mem(idx);
|
| 817 |
|
|
}
|
| 818 |
|
|
#endif
|
| 819 |
|
|
if (align == 0) align = 1; // in case incomplete type
|
| 820 |
|
|
Set_TY_align (idx, align);
|
| 821 |
|
|
// set idx now in case recurse thru fields
|
| 822 |
|
|
TYPE_TY_IDX(type_tree) = idx;
|
| 823 |
|
|
Do_Base_Types (type_tree);
|
| 824 |
|
|
|
| 825 |
|
|
// Process nested structs and static data members first
|
| 826 |
|
|
|
| 827 |
|
|
for (gs_t field = get_first_real_or_virtual_field (type_tree);
|
| 828 |
|
|
field;
|
| 829 |
|
|
field = next_real_field(type_tree, field)) {
|
| 830 |
|
|
Set_TY_content_seen(idx); // bug 10851
|
| 831 |
|
|
if (gs_tree_code(field) == GS_TYPE_DECL ||
|
| 832 |
|
|
gs_tree_code(field) == GS_FIELD_DECL) {
|
| 833 |
|
|
gs_t field_type = gs_tree_type(field);
|
| 834 |
|
|
if ((gs_tree_code(field_type) == GS_RECORD_TYPE ||
|
| 835 |
|
|
gs_tree_code(field_type) == GS_UNION_TYPE) &&
|
| 836 |
|
|
field_type != type_tree) {
|
| 837 |
|
|
#ifdef KEY
|
| 838 |
|
|
// Defer typedefs within class
|
| 839 |
|
|
// declarations to avoid circular
|
| 840 |
|
|
// declaration dependences. See
|
| 841 |
|
|
// example in bug 5134.
|
| 842 |
|
|
if (gs_tree_code(field) == GS_TYPE_DECL)
|
| 843 |
|
|
defer_decl(field_type);
|
| 844 |
|
|
else
|
| 845 |
|
|
#endif
|
| 846 |
|
|
Get_TY(field_type);
|
| 847 |
|
|
}
|
| 848 |
|
|
}
|
| 849 |
|
|
#ifdef KEY // Defer expansion of static vars until all the fields in
|
| 850 |
|
|
// _every_ struct are laid out. Consider this code (see
|
| 851 |
|
|
// bug 3044):
|
| 852 |
|
|
// struct A
|
| 853 |
|
|
// struct B *p
|
| 854 |
|
|
// struct B
|
| 855 |
|
|
// static struct A *q = ... // static data member with
|
| 856 |
|
|
// // initializer
|
| 857 |
|
|
// We cannot expand static member vars while expanding the
|
| 858 |
|
|
// enclosing stuct, for the following reason: Expansion of
|
| 859 |
|
|
// struct A leads to expansion of p, which leads to the
|
| 860 |
|
|
// expansion of struct B, which leads to the expansion of q and
|
| 861 |
|
|
// q's initializer. The code that expands the initializer goes
|
| 862 |
|
|
// through the fields of struct A, but these fields are not yet
|
| 863 |
|
|
// completely defined, and this will cause kg++fe to die.
|
| 864 |
|
|
//
|
| 865 |
|
|
// The solution is the delay all static var expansions until
|
| 866 |
|
|
// the very end.
|
| 867 |
|
|
else if (gs_tree_code(field) == GS_VAR_DECL)
|
| 868 |
|
|
defer_decl(field);
|
| 869 |
|
|
#else
|
| 870 |
|
|
else if (gs_tree_code(field) == GS_VAR_DECL)
|
| 871 |
860 |
hucheng |
WGEN_Expand_Decl(field, TRUE);
|
| 872 |
736 |
fengzhou |
#endif
|
| 873 |
|
|
else if (gs_tree_code(field) == GS_TEMPLATE_DECL)
|
| 874 |
860 |
hucheng |
WGEN_Expand_Decl(field, TRUE);
|
| 875 |
736 |
fengzhou |
}
|
| 876 |
|
|
|
| 877 |
|
|
Set_TY_fld (ty, FLD_HANDLE());
|
| 878 |
|
|
FLD_IDX first_field_idx = Fld_Table.Size ();
|
| 879 |
|
|
gs_t field;
|
| 880 |
|
|
gs_t method = gs_type_methods(type_tree);
|
| 881 |
|
|
FLD_HANDLE fld;
|
| 882 |
|
|
INT32 next_field_id = 1;
|
| 883 |
|
|
|
| 884 |
|
|
#ifdef KEY
|
| 885 |
|
|
// In GCC 4, the same tree node representing a vtable ptr field
|
| 886 |
|
|
// can appear in different derived classes. As a result,
|
| 887 |
|
|
// DECL_FIELD_ID(field) can't be used to map its field ID. As
|
| 888 |
|
|
// a fix, always allocate field ID 1 to the vtable ptr field.
|
| 889 |
|
|
// Do this before allocating IDs to any other field.
|
| 890 |
|
|
gs_t vfield = get_virtual_field(type_tree);
|
| 891 |
|
|
if (vfield) {
|
| 892 |
|
|
Is_True(gs_tree_code(vfield) == GS_FIELD_DECL,
|
| 893 |
|
|
("Create_TY_For_Tree: bad vfield code"));
|
| 894 |
|
|
Is_True(gs_decl_name(vfield) &&
|
| 895 |
|
|
!strncmp(Get_Name(gs_decl_name(vfield)),"_vptr", 5),
|
| 896 |
|
|
("Create_TY_For_Tree: bad vfield name"));
|
| 897 |
|
|
// The vfield field ID is either not set, or was set to 1.
|
| 898 |
|
|
Is_True(DECL_FIELD_ID(vfield) <= 1,
|
| 899 |
|
|
("Create_TY_For_Tree: invalid vfield field ID"));
|
| 900 |
|
|
|
| 901 |
|
|
DECL_FIELD_ID(vfield) = next_field_id; // must be 1
|
| 902 |
|
|
next_field_id += TYPE_FIELD_IDS_USED(gs_tree_type(vfield)) +1;
|
| 903 |
|
|
fld = New_FLD ();
|
| 904 |
|
|
FLD_Init(fld, Save_Str(Get_Name(gs_decl_name(vfield))),
|
| 905 |
|
|
0, // type
|
| 906 |
|
|
gs_get_integer_value(gs_decl_field_offset(vfield))
|
| 907 |
|
|
+ gs_get_integer_value(gs_decl_field_bit_offset(vfield))
|
| 908 |
|
|
/ BITSPERBYTE);
|
| 909 |
|
|
}
|
| 910 |
|
|
#endif
|
| 911 |
|
|
|
| 912 |
|
|
// Generate an anonymous field for every direct, nonempty,
|
| 913 |
|
|
// nonvirtual base class.
|
| 914 |
|
|
|
| 915 |
|
|
INT32 offset = 0;
|
| 916 |
|
|
INT32 anonymous_fields = 0;
|
| 917 |
860 |
hucheng |
#ifndef KEY // g++'s class.c already laid out the base types. Bug 11622.
|
| 918 |
736 |
fengzhou |
gs_t type_binfo, basetypes;
|
| 919 |
|
|
if ((type_binfo = gs_type_binfo(type_tree)) != NULL &&
|
| 920 |
|
|
(basetypes = gs_binfo_base_binfos(type_binfo)) != NULL) {
|
| 921 |
|
|
gs_t list;
|
| 922 |
|
|
for (list = basetypes; gs_code(list) != EMPTY;
|
| 923 |
|
|
list = gs_operand(list, 1)) {
|
| 924 |
|
|
gs_t binfo = gs_operand(list, 0);
|
| 925 |
|
|
gs_t basetype = gs_binfo_type(binfo);
|
| 926 |
|
|
offset = Roundup (offset,
|
| 927 |
|
|
gs_type_align(basetype) / BITSPERBYTE);
|
| 928 |
|
|
if (!is_empty_base_class(basetype) ||
|
| 929 |
|
|
!gs_binfo_virtual_p(binfo)) {
|
| 930 |
|
|
++next_field_id;
|
| 931 |
|
|
++anonymous_fields;
|
| 932 |
|
|
next_field_id += TYPE_FIELD_IDS_USED(basetype);
|
| 933 |
|
|
fld = New_FLD();
|
| 934 |
|
|
FLD_Init (fld, Save_Str(Get_Name(0)),
|
| 935 |
|
|
Get_TY(basetype), offset);
|
| 936 |
|
|
offset += Type_Size_Without_Vbases (basetype);
|
| 937 |
962 |
shiyao |
Set_FLD_is_anonymous(fld);
|
| 938 |
736 |
fengzhou |
#ifdef KEY
|
| 939 |
|
|
// temporary hack for a bug in gcc
|
| 940 |
|
|
// Details: From layout_class_type(), it turns out that for this
|
| 941 |
|
|
// type, gcc is apparently sending wrong type info, they have 2 fields
|
| 942 |
|
|
// each 8 bytes in a 'record', with the type size == 8 bytes also!
|
| 943 |
|
|
// So we take care of it here...
|
| 944 |
|
|
if (offset > tsize)
|
| 945 |
|
|
{
|
| 946 |
|
|
tsize = offset;
|
| 947 |
|
|
Set_TY_size (ty, tsize);
|
| 948 |
|
|
}
|
| 949 |
|
|
#endif // KEY
|
| 950 |
|
|
}
|
| 951 |
|
|
}
|
| 952 |
|
|
}
|
| 953 |
860 |
hucheng |
#endif // KEY
|
| 954 |
736 |
fengzhou |
|
| 955 |
1101 |
shiyao |
hash_set <gs_t, void_ptr_hash> anonymous_base;
|
| 956 |
|
|
gs_t type_binfo, basetypes;
|
| 957 |
|
|
|
| 958 |
|
|
// find all base classes
|
| 959 |
|
|
if ((type_binfo = gs_type_binfo(type_tree)) != NULL &&
|
| 960 |
|
|
(basetypes = gs_binfo_base_binfos(type_binfo)) != NULL) {
|
| 961 |
|
|
gs_t list;
|
| 962 |
|
|
for (list = basetypes; gs_code(list) != EMPTY;
|
| 963 |
|
|
list = gs_operand(list, 1)) {
|
| 964 |
|
|
gs_t binfo = gs_operand(list, 0);
|
| 965 |
|
|
gs_t basetype = gs_binfo_type(binfo);
|
| 966 |
|
|
anonymous_base.insert(basetype);
|
| 967 |
|
|
}
|
| 968 |
|
|
}
|
| 969 |
|
|
|
| 970 |
736 |
fengzhou |
// Assign IDs to real fields. The vtable ptr field is already
|
| 971 |
|
|
// assigned ID 1.
|
| 972 |
|
|
for (field = get_first_real_field(type_tree);
|
| 973 |
|
|
field;
|
| 974 |
|
|
field = next_real_field(type_tree, field) )
|
| 975 |
|
|
{
|
| 976 |
|
|
if (gs_tree_code(field) == GS_TYPE_DECL) {
|
| 977 |
|
|
continue;
|
| 978 |
|
|
}
|
| 979 |
|
|
if (gs_tree_code(field) == GS_CONST_DECL) {
|
| 980 |
|
|
DevWarn ("got CONST_DECL in field list");
|
| 981 |
|
|
continue;
|
| 982 |
|
|
}
|
| 983 |
|
|
if (gs_tree_code(field) == GS_VAR_DECL) {
|
| 984 |
|
|
continue;
|
| 985 |
|
|
}
|
| 986 |
|
|
if (gs_tree_code(field) == GS_TEMPLATE_DECL) {
|
| 987 |
|
|
continue;
|
| 988 |
|
|
}
|
| 989 |
|
|
|
| 990 |
|
|
// Either the DECL_FIELD_ID is not yet set, or is
|
| 991 |
|
|
// already set to the same field ID. The latter
|
| 992 |
|
|
// happens when GCC 4 duplicates the type tree and the
|
| 993 |
|
|
// same field node appears in both type nodes.
|
| 994 |
|
|
Is_True(DECL_FIELD_ID(field) == 0 ||
|
| 995 |
|
|
DECL_FIELD_ID(field) == next_field_id,
|
| 996 |
|
|
("Create_TY_For_Tree: field ID already set"));
|
| 997 |
|
|
|
| 998 |
|
|
DECL_FIELD_ID(field) = next_field_id;
|
| 999 |
|
|
next_field_id +=
|
| 1000 |
|
|
TYPE_FIELD_IDS_USED(gs_tree_type(field)) + 1;
|
| 1001 |
|
|
fld = New_FLD ();
|
| 1002 |
|
|
FLD_Init (fld, Save_Str(Get_Name(gs_decl_name(field))),
|
| 1003 |
|
|
0, // type
|
| 1004 |
|
|
gs_get_integer_value(gs_decl_field_offset(field)) +
|
| 1005 |
|
|
gs_get_integer_value(gs_decl_field_bit_offset(field))
|
| 1006 |
|
|
/ BITSPERBYTE);
|
| 1007 |
962 |
shiyao |
if (gs_decl_name(field) == NULL)
|
| 1008 |
|
|
Set_FLD_is_anonymous(fld);
|
| 1009 |
1101 |
shiyao |
if (anonymous_base.find(gs_tree_type(field)) != anonymous_base.end())
|
| 1010 |
|
|
Set_FLD_is_base_class(fld);
|
| 1011 |
736 |
fengzhou |
}
|
| 1012 |
|
|
|
| 1013 |
|
|
TYPE_FIELD_IDS_USED(type_tree) = next_field_id - 1;
|
| 1014 |
|
|
FLD_IDX last_field_idx = Fld_Table.Size () - 1;
|
| 1015 |
|
|
if (last_field_idx >= first_field_idx) {
|
| 1016 |
|
|
Set_TY_fld (ty, FLD_HANDLE (first_field_idx));
|
| 1017 |
|
|
Set_FLD_last_field (FLD_HANDLE (last_field_idx));
|
| 1018 |
|
|
}
|
| 1019 |
|
|
|
| 1020 |
|
|
// now set the fld types.
|
| 1021 |
|
|
fld = TY_fld(ty);
|
| 1022 |
|
|
#ifdef KEY
|
| 1023 |
|
|
// Handle the vtable ptr field if it exists.
|
| 1024 |
|
|
if (vfield) {
|
| 1025 |
|
|
Is_True(gs_tree_code(gs_tree_type(vfield)) == GS_POINTER_TYPE,
|
| 1026 |
|
|
("Create_TY_For_Tree: vtable ptr should be GS_POINTER_TYPE"));
|
| 1027 |
|
|
|
| 1028 |
|
|
// As mentioned below, don't expand pointer-type fields to
|
| 1029 |
|
|
// avoid circular dependences. Defer expanding the field
|
| 1030 |
|
|
// type.
|
| 1031 |
|
|
fld = TY_fld(ty);
|
| 1032 |
|
|
TY_IDX p_idx = Make_Pointer_Type(MTYPE_To_TY(MTYPE_U8),FALSE);
|
| 1033 |
|
|
Set_FLD_type(fld, p_idx);
|
| 1034 |
|
|
defer_field(vfield, fld);
|
| 1035 |
|
|
fld = FLD_next(fld);
|
| 1036 |
|
|
}
|
| 1037 |
|
|
#endif
|
| 1038 |
|
|
// first skip the anonymous fields, whose types are already
|
| 1039 |
|
|
// set.
|
| 1040 |
|
|
while (anonymous_fields--)
|
| 1041 |
|
|
fld = FLD_next(fld);
|
| 1042 |
|
|
|
| 1043 |
|
|
for (field = get_first_real_field(type_tree);
|
| 1044 |
|
|
/* ugly hack follows; traversing the fields isn't
|
| 1045 |
|
|
the same from run-to-run. fwa? */
|
| 1046 |
|
|
field && fld.Entry();
|
| 1047 |
|
|
field = next_real_field(type_tree, field))
|
| 1048 |
|
|
{
|
| 1049 |
|
|
#ifdef KEY
|
| 1050 |
|
|
const int FLD_BIT_FIELD_SIZE = 64;
|
| 1051 |
|
|
#endif
|
| 1052 |
|
|
if (gs_tree_code(field) == GS_TYPE_DECL)
|
| 1053 |
|
|
continue;
|
| 1054 |
|
|
if (gs_tree_code(field) == GS_CONST_DECL)
|
| 1055 |
|
|
continue;
|
| 1056 |
|
|
if (gs_tree_code(field) == GS_VAR_DECL)
|
| 1057 |
|
|
continue;
|
| 1058 |
|
|
if (gs_tree_code(field) == GS_TEMPLATE_DECL)
|
| 1059 |
|
|
continue;
|
| 1060 |
|
|
#ifdef KEY
|
| 1061 |
|
|
// Don't expand the field's type if it's a pointer
|
| 1062 |
|
|
// type, in order to avoid circular dependences
|
| 1063 |
|
|
// involving member object types and base types. See
|
| 1064 |
|
|
// example in bug 4954.
|
| 1065 |
|
|
if (gs_tree_code(gs_tree_type(field)) == GS_POINTER_TYPE) {
|
| 1066 |
|
|
// Defer expanding the field's type. Put in a
|
| 1067 |
|
|
// generic pointer type for now.
|
| 1068 |
|
|
TY_IDX p_idx =
|
| 1069 |
|
|
Make_Pointer_Type(MTYPE_To_TY(MTYPE_U8),
|
| 1070 |
|
|
FALSE);
|
| 1071 |
|
|
Set_FLD_type(fld, p_idx);
|
| 1072 |
|
|
defer_field(field, fld);
|
| 1073 |
|
|
fld = FLD_next(fld);
|
| 1074 |
|
|
continue;
|
| 1075 |
|
|
}
|
| 1076 |
|
|
#endif
|
| 1077 |
|
|
TY_IDX fty_idx = Get_TY(gs_tree_type(field));
|
| 1078 |
|
|
|
| 1079 |
|
|
if ((TY_align (fty_idx) > align) || (TY_is_packed (fty_idx)))
|
| 1080 |
|
|
Set_TY_is_packed (ty);
|
| 1081 |
|
|
#if 1 // wgen bug 10470
|
| 1082 |
|
|
if (! gs_tree_this_volatile(field))
|
| 1083 |
|
|
Clear_TY_is_volatile (fty_idx);
|
| 1084 |
|
|
#endif
|
| 1085 |
|
|
Set_FLD_type(fld, fty_idx);
|
| 1086 |
|
|
|
| 1087 |
|
|
if ( ! gs_decl_bit_field(field)
|
| 1088 |
|
|
#if 1 // wgen bug 10901
|
| 1089 |
|
|
&& gs_tree_code(gs_tree_type(field)) != GS_RECORD_TYPE
|
| 1090 |
|
|
&& gs_tree_code(gs_tree_type(field)) != GS_UNION_TYPE
|
| 1091 |
|
|
#endif
|
| 1092 |
|
|
&& gs_decl_size(field) // bug 10305
|
| 1093 |
|
|
&& gs_get_integer_value(gs_decl_size(field)) > 0
|
| 1094 |
|
|
#ifdef KEY
|
| 1095 |
|
|
// We don't handle bit-fields > 64 bits. For an INT field of 128 bits, we
|
| 1096 |
|
|
// make it 64 bits. But then don't set it as FLD_IS_BIT_FIELD.
|
| 1097 |
|
|
&& gs_get_integer_value(gs_decl_size(field)) <=
|
| 1098 |
|
|
FLD_BIT_FIELD_SIZE
|
| 1099 |
|
|
// bug 2401
|
| 1100 |
|
|
&& TY_size(Get_TY(gs_tree_type(field))) != 0
|
| 1101 |
|
|
#endif
|
| 1102 |
|
|
&& gs_get_integer_value(gs_decl_size(field))
|
| 1103 |
|
|
!= (TY_size(Get_TY(gs_tree_type(field)))
|
| 1104 |
|
|
* BITSPERBYTE) )
|
| 1105 |
|
|
{
|
| 1106 |
|
|
#ifdef KEY
|
| 1107 |
|
|
FmtAssert( gs_get_integer_value(gs_decl_size(field)) <=
|
| 1108 |
|
|
FLD_BIT_FIELD_SIZE,
|
| 1109 |
|
|
("field size too big") );
|
| 1110 |
|
|
#endif
|
| 1111 |
|
|
// for some reason gnu doesn't set bit field
|
| 1112 |
|
|
// when have bit-field of standard size
|
| 1113 |
|
|
// (e.g. int f: 16;). But we need it set
|
| 1114 |
|
|
// so we know how to pack it, because
|
| 1115 |
|
|
// otherwise the field type is wrong.
|
| 1116 |
|
|
DevWarn("field size %lld doesn't match type size %lld",
|
| 1117 |
|
|
gs_get_integer_value(gs_decl_size(field)),
|
| 1118 |
|
|
TY_size(Get_TY(gs_tree_type(field)))
|
| 1119 |
|
|
* BITSPERBYTE );
|
| 1120 |
|
|
gs_set_decl_bit_field(field, 1);
|
| 1121 |
|
|
}
|
| 1122 |
|
|
if (gs_decl_bit_field(field)) {
|
| 1123 |
|
|
Set_FLD_is_bit_field (fld);
|
| 1124 |
|
|
// bofst is remaining bits from byte offset
|
| 1125 |
|
|
Set_FLD_bofst (fld,
|
| 1126 |
|
|
gs_get_integer_value(
|
| 1127 |
|
|
gs_decl_field_bit_offset(field))
|
| 1128 |
|
|
% BITSPERBYTE);
|
| 1129 |
|
|
Set_FLD_bsize (fld, gs_get_integer_value(
|
| 1130 |
|
|
gs_decl_size(field)));
|
| 1131 |
|
|
}
|
| 1132 |
|
|
fld = FLD_next(fld);
|
| 1133 |
|
|
}
|
| 1134 |
|
|
|
| 1135 |
|
|
#ifndef KEY // Don't expand methods by going through TYPE_METHODS,
|
| 1136 |
|
|
// because:
|
| 1137 |
|
|
// 1) It is incorrect to translate all methods in
|
| 1138 |
|
|
// TYPE_METHODS to WHIRL because some of the methods are
|
| 1139 |
|
|
// never used, and generating the assembly code for them
|
| 1140 |
|
|
// might lead to undefined symbol references. Instead,
|
| 1141 |
|
|
// consult the gxx_emitted_decls list, which has all the
|
| 1142 |
|
|
// functions (including methods) that g++ has ever emitted
|
| 1143 |
|
|
// to assembly.
|
| 1144 |
|
|
// 2) Expanding the methods here will cause error when the
|
| 1145 |
|
|
// methods are for a class B that appears as a field in an
|
| 1146 |
|
|
// enclosing class A. When Get_TY is run for A, it will
|
| 1147 |
|
|
// call Get_TY for B in order to calculate A's field ID's.
|
| 1148 |
|
|
// (Need Get_TY to find B's TYPE_FIELD_IDS_USED.) If
|
| 1149 |
|
|
// Get_TY uses the code below to expand B's methods, it
|
| 1150 |
|
|
// will lead to error because the expansion requires the
|
| 1151 |
|
|
// field ID's of the enclosing record (A), and these field
|
| 1152 |
|
|
// ID's are not yet defined.
|
| 1153 |
|
|
|
| 1154 |
|
|
// process methods
|
| 1155 |
|
|
if (!Enable_WGEN_DFE) {
|
| 1156 |
|
|
if (cp_type_quals(type_tree) == TYPE_UNQUALIFIED) {
|
| 1157 |
|
|
while (method != NULL_TREE) {
|
| 1158 |
860 |
hucheng |
WGEN_Expand_Decl (method, TRUE);
|
| 1159 |
736 |
fengzhou |
method = TREE_CHAIN(method);
|
| 1160 |
|
|
}
|
| 1161 |
|
|
}
|
| 1162 |
|
|
}
|
| 1163 |
|
|
#endif // KEY
|
| 1164 |
|
|
} //end record scope
|
| 1165 |
|
|
break;
|
| 1166 |
|
|
case GS_METHOD_TYPE:
|
| 1167 |
|
|
//DevWarn ("Encountered METHOD_TYPE at line %d", lineno);
|
| 1168 |
|
|
case GS_FUNCTION_TYPE:
|
| 1169 |
|
|
{ // new scope for local vars
|
| 1170 |
|
|
gs_t arg;
|
| 1171 |
|
|
INT32 num_args, i;
|
| 1172 |
860 |
hucheng |
#ifdef KEY /* bug 8346 */
|
| 1173 |
|
|
TY &ty = (idx == TY_IDX_ZERO) ? New_TY(idx) : Ty_Table[idx];
|
| 1174 |
|
|
Clear_TY_is_incomplete (idx);
|
| 1175 |
|
|
#else
|
| 1176 |
736 |
fengzhou |
TY &ty = New_TY (idx);
|
| 1177 |
860 |
hucheng |
#endif
|
| 1178 |
736 |
fengzhou |
TY_Init (ty, 0, KIND_FUNCTION, MTYPE_UNKNOWN, 0);
|
| 1179 |
|
|
Set_TY_align (idx, 1);
|
| 1180 |
|
|
TY_IDX ret_ty_idx;
|
| 1181 |
|
|
TY_IDX arg_ty_idx;
|
| 1182 |
|
|
TYLIST tylist_idx;
|
| 1183 |
|
|
|
| 1184 |
|
|
// allocate TYs for return as well as parameters
|
| 1185 |
|
|
// this is needed to avoid mixing TYLISTs if one
|
| 1186 |
|
|
// of the parameters is a pointer to a function
|
| 1187 |
|
|
|
| 1188 |
|
|
ret_ty_idx = Get_TY(gs_tree_type(type_tree));
|
| 1189 |
|
|
for (arg = gs_type_arg_types(type_tree);
|
| 1190 |
|
|
arg;
|
| 1191 |
|
|
arg = gs_tree_chain(arg))
|
| 1192 |
860 |
hucheng |
{
|
| 1193 |
736 |
fengzhou |
arg_ty_idx = Get_TY(gs_tree_value(arg));
|
| 1194 |
860 |
hucheng |
#ifdef KEY /* bug 8346 */
|
| 1195 |
|
|
if (TY_is_incomplete (arg_ty_idx) ||
|
| 1196 |
|
|
(TY_kind(arg_ty_idx) == KIND_POINTER &&
|
| 1197 |
|
|
TY_is_incomplete(TY_pointed(arg_ty_idx))))
|
| 1198 |
|
|
Set_TY_is_incomplete (idx);
|
| 1199 |
|
|
#endif
|
| 1200 |
|
|
}
|
| 1201 |
736 |
fengzhou |
|
| 1202 |
|
|
// if return type is pointer to a zero length struct
|
| 1203 |
|
|
// convert it to void
|
| 1204 |
|
|
if (!WGEN_Keep_Zero_Length_Structs &&
|
| 1205 |
|
|
TY_mtype (ret_ty_idx) == MTYPE_M &&
|
| 1206 |
|
|
TY_size (ret_ty_idx) == 0) {
|
| 1207 |
|
|
// zero length struct being returned
|
| 1208 |
|
|
DevWarn ("function returning zero length struct at line %d", lineno);
|
| 1209 |
|
|
ret_ty_idx = Be_Type_Tbl (MTYPE_V);
|
| 1210 |
|
|
}
|
| 1211 |
|
|
|
| 1212 |
|
|
#ifdef KEY
|
| 1213 |
|
|
// If the front-end adds the fake first param, then convert the
|
| 1214 |
|
|
// function to return void.
|
| 1215 |
|
|
if (TY_return_in_mem(ret_ty_idx)) {
|
| 1216 |
|
|
ret_ty_idx = Be_Type_Tbl (MTYPE_V);
|
| 1217 |
|
|
Set_TY_return_to_param(idx); // bugs 2423 2424
|
| 1218 |
|
|
}
|
| 1219 |
|
|
#endif
|
| 1220 |
|
|
Set_TYLIST_type (New_TYLIST (tylist_idx), ret_ty_idx);
|
| 1221 |
|
|
Set_TY_tylist (ty, tylist_idx);
|
| 1222 |
|
|
for (num_args = 0, arg = gs_type_arg_types(type_tree);
|
| 1223 |
|
|
arg;
|
| 1224 |
|
|
num_args++, arg = gs_tree_chain(arg))
|
| 1225 |
|
|
{
|
| 1226 |
|
|
arg_ty_idx = Get_TY(gs_tree_value(arg));
|
| 1227 |
860 |
hucheng |
Is_True (!TY_is_incomplete (arg_ty_idx) ||
|
| 1228 |
|
|
TY_is_incomplete (idx),
|
| 1229 |
|
|
("Create_TY_For_Tree: unexpected TY flag"));
|
| 1230 |
736 |
fengzhou |
if (!WGEN_Keep_Zero_Length_Structs &&
|
| 1231 |
|
|
TY_mtype (arg_ty_idx) == MTYPE_M &&
|
| 1232 |
|
|
TY_size (arg_ty_idx) == 0) {
|
| 1233 |
|
|
// zero length struct passed as parameter
|
| 1234 |
|
|
DevWarn ("zero length struct encountered in function prototype at line %d", lineno);
|
| 1235 |
|
|
}
|
| 1236 |
|
|
else
|
| 1237 |
|
|
Set_TYLIST_type (New_TYLIST (tylist_idx), arg_ty_idx);
|
| 1238 |
|
|
}
|
| 1239 |
|
|
if (num_args)
|
| 1240 |
|
|
{
|
| 1241 |
|
|
Set_TY_has_prototype(idx);
|
| 1242 |
|
|
if (arg_ty_idx != Be_Type_Tbl(MTYPE_V))
|
| 1243 |
|
|
{
|
| 1244 |
|
|
Set_TYLIST_type (New_TYLIST (tylist_idx), 0);
|
| 1245 |
|
|
Set_TY_is_varargs(idx);
|
| 1246 |
|
|
}
|
| 1247 |
|
|
else
|
| 1248 |
|
|
Set_TYLIST_type (Tylist_Table [tylist_idx], 0);
|
| 1249 |
|
|
}
|
| 1250 |
|
|
else
|
| 1251 |
|
|
Set_TYLIST_type (New_TYLIST (tylist_idx), 0);
|
| 1252 |
1950 |
laijx |
#ifdef TARG_X8664
|
| 1253 |
|
|
if (!TARGET_64BIT && !TY_is_varargs(idx))
|
| 1254 |
|
|
{
|
| 1255 |
|
|
// Ignore m{sse}regparm and corresponding attributes at -m64.
|
| 1256 |
|
|
if (SSE_Reg_Parm ||
|
| 1257 |
|
|
lookup_attribute("sseregparm",
|
| 1258 |
|
|
gs_type_attributes(type_tree)))
|
| 1259 |
|
|
Set_TY_has_sseregister_parm (idx);
|
| 1260 |
|
|
if (gs_t attr = lookup_attribute("regparm",
|
| 1261 |
|
|
gs_type_attributes(type_tree)))
|
| 1262 |
|
|
{
|
| 1263 |
|
|
gs_t value = gs_tree_value (attr);
|
| 1264 |
|
|
Is_True (gs_tree_code(value) == GS_TREE_LIST,
|
| 1265 |
|
|
("Expected TREE_LIST"));
|
| 1266 |
|
|
value = gs_tree_value (value);
|
| 1267 |
|
|
if (gs_tree_code(value) == GS_INTEGER_CST)
|
| 1268 |
|
|
Set_TY_register_parm (idx, gs_get_integer_value (value));
|
| 1269 |
|
|
}
|
| 1270 |
|
|
else if (Reg_Parm_Count)
|
| 1271 |
|
|
Set_TY_register_parm (idx, Reg_Parm_Count);
|
| 1272 |
|
|
}
|
| 1273 |
|
|
#endif
|
| 1274 |
736 |
fengzhou |
} // end FUNCTION_TYPE scope
|
| 1275 |
|
|
break;
|
| 1276 |
|
|
#ifdef TARG_X8664
|
| 1277 |
|
|
// x86 gcc vector types
|
| 1278 |
|
|
case GS_VECTOR_TYPE:
|
| 1279 |
|
|
{
|
| 1280 |
|
|
char *p = gs_type_mode(type_tree);
|
| 1281 |
|
|
idx = 0;
|
| 1282 |
|
|
if (strcmp(p, "BLK") == 0) {
|
| 1283 |
|
|
TY_IDX elem_ty = Get_TY(gs_tree_type(type_tree));
|
| 1284 |
|
|
TYPE_ID elem_mtype = TY_mtype(elem_ty);
|
| 1285 |
|
|
switch (gs_n(gs_type_precision(type_tree))) {
|
| 1286 |
|
|
case 2: if (elem_mtype == MTYPE_I4)
|
| 1287 |
1411 |
laijx |
idx = MTYPE_To_TY(MTYPE_V8I4);
|
| 1288 |
736 |
fengzhou |
else if (elem_mtype == MTYPE_F4)
|
| 1289 |
|
|
idx = MTYPE_To_TY(MTYPE_V8F4);
|
| 1290 |
|
|
else if (elem_mtype == MTYPE_I8)
|
| 1291 |
|
|
idx = MTYPE_To_TY(MTYPE_V16I8);
|
| 1292 |
|
|
else if (elem_mtype == MTYPE_F8)
|
| 1293 |
|
|
idx = MTYPE_To_TY(MTYPE_V16F8);
|
| 1294 |
|
|
break;
|
| 1295 |
|
|
case 4: if (elem_mtype == MTYPE_I4)
|
| 1296 |
|
|
idx = MTYPE_To_TY(MTYPE_V16I4);
|
| 1297 |
|
|
else if (elem_mtype == MTYPE_F4)
|
| 1298 |
|
|
idx = MTYPE_To_TY(MTYPE_V16F4);
|
| 1299 |
|
|
else if (elem_mtype == MTYPE_I2)
|
| 1300 |
|
|
idx = MTYPE_To_TY(MTYPE_M8I2);
|
| 1301 |
|
|
break;
|
| 1302 |
|
|
case 8: if (elem_mtype == MTYPE_I1)
|
| 1303 |
|
|
idx = MTYPE_To_TY(MTYPE_M8I1);
|
| 1304 |
|
|
else if (elem_mtype == MTYPE_I2)
|
| 1305 |
|
|
idx = MTYPE_To_TY(MTYPE_V16I2);
|
| 1306 |
|
|
break;
|
| 1307 |
|
|
case 16: if (elem_mtype == MTYPE_I1)
|
| 1308 |
|
|
idx = MTYPE_To_TY(MTYPE_V16I1);
|
| 1309 |
|
|
break;
|
| 1310 |
|
|
default:
|
| 1311 |
|
|
Fail_FmtAssertion ("Get_TY: unexpected vector type element count");
|
| 1312 |
|
|
}
|
| 1313 |
|
|
}
|
| 1314 |
|
|
else { // use string emcoded in TYPE_MODE
|
| 1315 |
|
|
if (toupper(*p++) != 'V') {
|
| 1316 |
|
|
if (gs_type_name(type_tree)) {
|
| 1317 |
|
|
p = gs_identifier_pointer(gs_decl_name(gs_type_name(type_tree)));
|
| 1318 |
|
|
if (toupper(*p++) != 'V')
|
| 1319 |
|
|
Fail_FmtAssertion("Get_TY: NYI");
|
| 1320 |
|
|
}
|
| 1321 |
|
|
else Fail_FmtAssertion("Get_TY: NYI");
|
| 1322 |
|
|
}
|
| 1323 |
|
|
int num_elems = strtol(p, &p, 10);
|
| 1324 |
|
|
if (strncasecmp(p, "DI", 2) == 0)
|
| 1325 |
|
|
idx = MTYPE_To_TY(MTYPE_V16I8);
|
| 1326 |
|
|
else if (strncasecmp(p, "DF", 2) == 0)
|
| 1327 |
|
|
idx = MTYPE_To_TY(MTYPE_V16F8);
|
| 1328 |
|
|
else if (strncasecmp(p, "SI", 2) == 0) {
|
| 1329 |
|
|
if (num_elems == 2)
|
| 1330 |
2116 |
ycwu |
if ( Is_Target_64bit())
|
| 1331 |
|
|
idx = MTYPE_To_TY(MTYPE_V8I4);
|
| 1332 |
|
|
else
|
| 1333 |
|
|
idx = MTYPE_To_TY(MTYPE_M8I4);
|
| 1334 |
736 |
fengzhou |
else if (num_elems == 4)
|
| 1335 |
|
|
idx = MTYPE_To_TY(MTYPE_V16I4);
|
| 1336 |
|
|
}
|
| 1337 |
|
|
else if (strncasecmp(p, "SF", 2) == 0) {
|
| 1338 |
|
|
if (num_elems == 2)
|
| 1339 |
2116 |
ycwu |
if ( Is_Target_64bit())
|
| 1340 |
|
|
idx = MTYPE_To_TY(MTYPE_V8F4);
|
| 1341 |
|
|
else
|
| 1342 |
|
|
idx = MTYPE_To_TY(MTYPE_M8F4);
|
| 1343 |
736 |
fengzhou |
else if (num_elems == 4)
|
| 1344 |
|
|
idx = MTYPE_To_TY(MTYPE_V16F4);
|
| 1345 |
|
|
}
|
| 1346 |
|
|
else if (strncasecmp(p, "HI", 2) == 0) {
|
| 1347 |
|
|
if (num_elems == 4)
|
| 1348 |
|
|
idx = MTYPE_To_TY(MTYPE_M8I2);
|
| 1349 |
|
|
else if (num_elems == 8)
|
| 1350 |
|
|
idx = MTYPE_To_TY(MTYPE_V16I2);
|
| 1351 |
|
|
}
|
| 1352 |
|
|
else if (strncasecmp(p, "QI", 2) == 0) {
|
| 1353 |
|
|
if (num_elems == 8)
|
| 1354 |
|
|
idx = MTYPE_To_TY(MTYPE_M8I1);
|
| 1355 |
|
|
else if (num_elems == 16)
|
| 1356 |
|
|
idx = MTYPE_To_TY(MTYPE_V16I1);
|
| 1357 |
|
|
}
|
| 1358 |
|
|
}
|
| 1359 |
|
|
if (idx == 0)
|
| 1360 |
|
|
Fail_FmtAssertion ("Get_TY: unexpected vector type");
|
| 1361 |
|
|
}
|
| 1362 |
|
|
break;
|
| 1363 |
|
|
#endif // TARG_X8664
|
| 1364 |
|
|
default:
|
| 1365 |
|
|
FmtAssert(FALSE, ("Get_TY unexpected tree_type"));
|
| 1366 |
|
|
}
|
| 1367 |
|
|
if (gs_type_readonly(type_tree))
|
| 1368 |
|
|
Set_TY_is_const (idx);
|
| 1369 |
|
|
if (gs_type_volatile(type_tree))
|
| 1370 |
|
|
Set_TY_is_volatile (idx);
|
| 1371 |
|
|
#ifdef KEY
|
| 1372 |
|
|
if (gs_type_restrict(type_tree))
|
| 1373 |
|
|
Set_TY_is_restrict (idx);
|
| 1374 |
|
|
#endif
|
| 1375 |
|
|
TYPE_TY_IDX(type_tree) = idx;
|
| 1376 |
|
|
if(Debug_Level >= 2) {
|
| 1377 |
|
|
#ifdef KEY
|
| 1378 |
|
|
// DSTs for records were entered into the defer list in the order
|
| 1379 |
|
|
// that the records are declared, in order to preserve their scope.
|
| 1380 |
|
|
// Bug 4168.
|
| 1381 |
|
|
if (gs_tree_code(type_tree) != GS_RECORD_TYPE &&
|
| 1382 |
860 |
hucheng |
gs_tree_code(type_tree) != GS_UNION_TYPE &&
|
| 1383 |
|
|
// Bugs 8346, 11819: Insert a TY for DST processing only
|
| 1384 |
|
|
// when the TY is complete to ensure that when the DST info
|
| 1385 |
|
|
// are created, the TY will be valid.
|
| 1386 |
|
|
!TY_is_incomplete(idx) &&
|
| 1387 |
|
|
!(TY_kind(idx) == KIND_POINTER &&
|
| 1388 |
|
|
TY_is_incomplete(TY_pointed(idx)))) {
|
| 1389 |
736 |
fengzhou |
// Defer creating DST info until there are no partially constructed
|
| 1390 |
|
|
// types, in order to prevent Create_DST_type_For_Tree from calling
|
| 1391 |
|
|
// Get_TY, which in turn may use field IDs from partially created
|
| 1392 |
|
|
// structs. Such fields IDs are wrong. Bug 5658.
|
| 1393 |
|
|
defer_DST_type(type_tree, idx, orig_idx);
|
| 1394 |
|
|
}
|
| 1395 |
|
|
#else
|
| 1396 |
|
|
DST_INFO_IDX dst =
|
| 1397 |
|
|
Create_DST_type_For_Tree(type_tree,
|
| 1398 |
|
|
idx,orig_idx);
|
| 1399 |
|
|
TYPE_DST_IDX(type_tree) = dst;
|
| 1400 |
|
|
#endif
|
| 1401 |
|
|
}
|
| 1402 |
|
|
|
| 1403 |
|
|
return idx;
|
| 1404 |
|
|
}
|
| 1405 |
|
|
|
| 1406 |
|
|
void
|
| 1407 |
|
|
Create_DST_For_Tree (gs_t decl_node, ST* st)
|
| 1408 |
|
|
{
|
| 1409 |
|
|
DST_INFO_IDX dst =
|
| 1410 |
|
|
Create_DST_decl_For_Tree(decl_node,st);
|
| 1411 |
|
|
DECL_DST_IDX(decl_node) = dst;
|
| 1412 |
|
|
return;
|
| 1413 |
|
|
}
|
| 1414 |
|
|
|
| 1415 |
|
|
#if 1 // wgen
|
| 1416 |
|
|
// if there is a PARM_DECL with the same name (as opposed to same node),
|
| 1417 |
|
|
// use the ST created for it
|
| 1418 |
|
|
ST *
|
| 1419 |
|
|
Search_decl_arguments(char *name)
|
| 1420 |
|
|
{
|
| 1421 |
|
|
gs_t p;
|
| 1422 |
|
|
if (name) {
|
| 1423 |
|
|
for (p = decl_arguments; p; p = gs_tree_chain(p)) {
|
| 1424 |
|
|
if (gs_decl_name(p) == NULL) // matches with any parm with null name (sanity32.C)
|
| 1425 |
|
|
return DECL_ST(p);
|
| 1426 |
|
|
if (strcmp(name, (char *) gs_identifier_pointer(gs_decl_name(p))) == 0)
|
| 1427 |
|
|
return DECL_ST(p);
|
| 1428 |
|
|
}
|
| 1429 |
|
|
}
|
| 1430 |
|
|
else { // search for an argument with no name
|
| 1431 |
|
|
for (p = decl_arguments; p; p = gs_tree_chain(p)) {
|
| 1432 |
|
|
if (gs_decl_name(p) == NULL)
|
| 1433 |
|
|
return DECL_ST(p);
|
| 1434 |
|
|
}
|
| 1435 |
|
|
}
|
| 1436 |
|
|
return NULL;
|
| 1437 |
|
|
}
|
| 1438 |
|
|
#endif
|
| 1439 |
|
|
|
| 1440 |
991 |
rhundt |
#ifdef KEY // bug 12668
|
| 1441 |
|
|
static BOOL
|
| 1442 |
|
|
Has_label_decl(gs_t init)
|
| 1443 |
|
|
{
|
| 1444 |
|
|
if (gs_tree_code(init) == GS_LABEL_DECL)
|
| 1445 |
|
|
return TRUE;
|
| 1446 |
|
|
if (gs_tree_code(init) == GS_ADDR_EXPR)
|
| 1447 |
|
|
return Has_label_decl(gs_tree_operand(init,0));
|
| 1448 |
1411 |
laijx |
#ifdef FE_GNU_4_2_0 // bug 12699
|
| 1449 |
|
|
if (gs_tree_code(init) == GS_NOP_EXPR)
|
| 1450 |
|
|
return Has_label_decl(gs_tree_operand(init,0));
|
| 1451 |
|
|
#endif
|
| 1452 |
991 |
rhundt |
if (gs_tree_code(init) == GS_CONSTRUCTOR) {
|
| 1453 |
1411 |
laijx |
#ifdef FE_GNU_4_2_0
|
| 1454 |
|
|
INT length = gs_constructor_length(init);
|
| 1455 |
|
|
gs_t element_value;
|
| 1456 |
|
|
for (INT idx = 0; idx < length; idx++) {
|
| 1457 |
|
|
element_value = gs_constructor_elts_value(init, idx);
|
| 1458 |
|
|
if (Has_label_decl(element_value))
|
| 1459 |
|
|
return TRUE;
|
| 1460 |
|
|
}
|
| 1461 |
|
|
#else
|
| 1462 |
991 |
rhundt |
gs_t nd;
|
| 1463 |
|
|
for (nd = gs_constructor_elts(init); nd; nd = gs_tree_chain(nd)) {
|
| 1464 |
|
|
if (Has_label_decl(gs_tree_value(nd)))
|
| 1465 |
1411 |
laijx |
return TRUE;
|
| 1466 |
991 |
rhundt |
}
|
| 1467 |
1411 |
laijx |
#endif
|
| 1468 |
991 |
rhundt |
}
|
| 1469 |
|
|
return FALSE;
|
| 1470 |
|
|
}
|
| 1471 |
|
|
#endif
|
| 1472 |
|
|
|
| 1473 |
736 |
fengzhou |
ST*
|
| 1474 |
|
|
Create_ST_For_Tree (gs_t decl_node)
|
| 1475 |
|
|
{
|
| 1476 |
|
|
TY_IDX ty_idx;
|
| 1477 |
860 |
hucheng |
ST* st = NULL;
|
| 1478 |
736 |
fengzhou |
char *name;
|
| 1479 |
|
|
char tempname[32];
|
| 1480 |
|
|
ST_SCLASS sclass;
|
| 1481 |
|
|
ST_EXPORT eclass;
|
| 1482 |
|
|
SYMTAB_IDX level;
|
| 1483 |
|
|
static INT anon_count = 0;
|
| 1484 |
|
|
BOOL anon_st = FALSE;
|
| 1485 |
|
|
|
| 1486 |
|
|
|
| 1487 |
|
|
// If the decl is a function decl, and there are duplicate decls for the
|
| 1488 |
|
|
// function, then use a ST already allocated for the function, if such ST
|
| 1489 |
|
|
// exists.
|
| 1490 |
|
|
if (gs_tree_code(decl_node) == GS_FUNCTION_DECL) {
|
| 1491 |
|
|
st = get_duplicate_st (decl_node);
|
| 1492 |
|
|
if (st) {
|
| 1493 |
|
|
set_DECL_ST(decl_node, st);
|
| 1494 |
|
|
return st;
|
| 1495 |
|
|
}
|
| 1496 |
|
|
}
|
| 1497 |
|
|
|
| 1498 |
|
|
// For variables with asm register assignments, don't use the assembler
|
| 1499 |
|
|
// names because they are of the form "%rbx".
|
| 1500 |
|
|
if (gs_tree_code(decl_node) == GS_RESULT_DECL) {
|
| 1501 |
|
|
sprintf(tempname, ".result_decl_%d", gs_decl_uid(decl_node));
|
| 1502 |
|
|
name = tempname;
|
| 1503 |
|
|
anon_st = TRUE;
|
| 1504 |
|
|
}
|
| 1505 |
|
|
else if ((gs_tree_code(decl_node) == GS_FUNCTION_DECL ||
|
| 1506 |
|
|
gs_tree_code(decl_node) == GS_PARM_DECL ||
|
| 1507 |
|
|
(gs_tree_code(decl_node) == GS_VAR_DECL &&
|
| 1508 |
1950 |
laijx |
gs_decl_asmreg(decl_node) >= 0)) &&
|
| 1509 |
736 |
fengzhou |
gs_decl_name(decl_node) != 0)
|
| 1510 |
|
|
name = (char *) gs_identifier_pointer (gs_decl_name (decl_node));
|
| 1511 |
2308 |
ycwu |
else if (gs_decl_assembler_name (decl_node) && gs_decl_name (decl_node))
|
| 1512 |
736 |
fengzhou |
name = (char *) gs_identifier_pointer (gs_decl_assembler_name (decl_node));
|
| 1513 |
2119 |
laijx |
else if (gs_decl_name (decl_node))
|
| 1514 |
|
|
name = (char *) gs_identifier_pointer (gs_decl_name (decl_node));
|
| 1515 |
736 |
fengzhou |
else {
|
| 1516 |
|
|
sprintf(tempname, "anon%d", ++anon_count);
|
| 1517 |
|
|
name = tempname;
|
| 1518 |
|
|
anon_st = TRUE;
|
| 1519 |
|
|
}
|
| 1520 |
|
|
|
| 1521 |
|
|
#ifdef KEY
|
| 1522 |
|
|
BOOL guard_var = FALSE;
|
| 1523 |
|
|
// See if variable is a guard variable.
|
| 1524 |
|
|
if (strncmp("_ZGV", name, 4) == 0) {
|
| 1525 |
|
|
guard_var = TRUE;
|
| 1526 |
|
|
}
|
| 1527 |
|
|
#endif
|
| 1528 |
|
|
|
| 1529 |
|
|
switch (gs_tree_code(decl_node)) {
|
| 1530 |
|
|
|
| 1531 |
|
|
case GS_FUNCTION_DECL:
|
| 1532 |
|
|
{
|
| 1533 |
|
|
if (Enable_WFE_DFE) {
|
| 1534 |
|
|
gs_t body = gs_decl_saved_tree(decl_node);
|
| 1535 |
|
|
if (gs_decl_thunk_p(decl_node) &&
|
| 1536 |
|
|
gs_tree_code(gs_cp_decl_context(decl_node)) != GS_NAMESPACE_DECL)
|
| 1537 |
|
|
Push_Deferred_Function (decl_node);
|
| 1538 |
|
|
/*
|
| 1539 |
|
|
else
|
| 1540 |
|
|
if (DECL_TINFO_FN_P(decl_node))
|
| 1541 |
|
|
Push_Deferred_Function (decl_node);
|
| 1542 |
|
|
*/
|
| 1543 |
|
|
else
|
| 1544 |
|
|
if (body != NULL && !gs_decl_external(decl_node) &&
|
| 1545 |
|
|
(gs_decl_template_info(decl_node) == NULL ||
|
| 1546 |
|
|
gs_decl_friend_pseudo_template_instantiation(decl_node) ||
|
| 1547 |
|
|
gs_decl_template_instantiated(decl_node) ||
|
| 1548 |
|
|
gs_decl_template_specialization(decl_node))) {
|
| 1549 |
|
|
Push_Deferred_Function (decl_node);
|
| 1550 |
|
|
}
|
| 1551 |
|
|
}
|
| 1552 |
|
|
|
| 1553 |
860 |
hucheng |
#ifdef KEY /* bug 8346 */
|
| 1554 |
|
|
Is_True (!processing_function_prototype,
|
| 1555 |
|
|
("Create_ST_For_Tree: processing another function prototype?"));
|
| 1556 |
|
|
processing_function_prototype = TRUE;
|
| 1557 |
736 |
fengzhou |
TY_IDX func_ty_idx = Get_TY(gs_tree_type(decl_node));
|
| 1558 |
860 |
hucheng |
processing_function_prototype = FALSE;
|
| 1559 |
|
|
#else
|
| 1560 |
|
|
TY_IDX func_ty_idx = Get_TY(gs_tree_type(decl_node));
|
| 1561 |
|
|
#endif
|
| 1562 |
736 |
fengzhou |
|
| 1563 |
|
|
sclass = SCLASS_EXTERN;
|
| 1564 |
|
|
eclass = gs_tree_public(decl_node) || gs_decl_weak(decl_node) ?
|
| 1565 |
|
|
EXPORT_PREEMPTIBLE :
|
| 1566 |
|
|
EXPORT_LOCAL;
|
| 1567 |
|
|
level = GLOBAL_SYMTAB+1;
|
| 1568 |
|
|
|
| 1569 |
|
|
PU_IDX pu_idx;
|
| 1570 |
|
|
PU& pu = New_PU (pu_idx);
|
| 1571 |
|
|
|
| 1572 |
|
|
PU_Init (pu, func_ty_idx, level);
|
| 1573 |
|
|
|
| 1574 |
1950 |
laijx |
#ifdef KEY
|
| 1575 |
|
|
st = New_ST (level - 1);
|
| 1576 |
|
|
#else
|
| 1577 |
736 |
fengzhou |
st = New_ST (GLOBAL_SYMTAB);
|
| 1578 |
1950 |
laijx |
#endif
|
| 1579 |
736 |
fengzhou |
|
| 1580 |
|
|
// Fix bug # 34, 3356
|
| 1581 |
|
|
// gcc sometimes adds a '*' and itself handles it this way while outputing
|
| 1582 |
860 |
hucheng |
char *p;
|
| 1583 |
|
|
if (gs_decl_assembler_name(decl_node) == NULL)
|
| 1584 |
|
|
p = name;
|
| 1585 |
|
|
else p = gs_identifier_pointer (gs_decl_assembler_name (decl_node));
|
| 1586 |
736 |
fengzhou |
if (*p == '*')
|
| 1587 |
|
|
p++;
|
| 1588 |
|
|
ST_Init (st, Save_Str(p),
|
| 1589 |
|
|
CLASS_FUNC, sclass, eclass, TY_IDX (pu_idx));
|
| 1590 |
1101 |
shiyao |
|
| 1591 |
|
|
// St is a constructor
|
| 1592 |
|
|
if (gs_decl_complete_constructor_p(decl_node) && !gs_decl_copy_constructor_p(decl_node))
|
| 1593 |
|
|
Set_PU_is_constructor(pu);
|
| 1594 |
|
|
// St is a pure virual function
|
| 1595 |
|
|
if (gs_decl_pure_virtual_p(decl_node) || strncmp(p, "__cxa_pure_virtual", 18) == 0)
|
| 1596 |
|
|
Set_ST_is_pure_vfunc(st);
|
| 1597 |
|
|
|
| 1598 |
1411 |
laijx |
if (gs_tree_code(gs_tree_type(decl_node)) == GS_METHOD_TYPE) {
|
| 1599 |
|
|
TY_IDX base = Get_TY(gs_type_method_basetype(gs_tree_type(decl_node)));
|
| 1600 |
|
|
Set_PU_base_class(pu, base);
|
| 1601 |
|
|
}
|
| 1602 |
|
|
|
| 1603 |
736 |
fengzhou |
if (gs_decl_thunk_p(decl_node) &&
|
| 1604 |
1466 |
dehao |
gs_tree_code(gs_cp_decl_context(decl_node)) != GS_NAMESPACE_DECL &&
|
| 1605 |
|
|
eclass != EXPORT_LOCAL &&
|
| 1606 |
|
|
eclass != EXPORT_LOCAL_INTERNAL)
|
| 1607 |
736 |
fengzhou |
Set_ST_is_weak_symbol(st);
|
| 1608 |
|
|
}
|
| 1609 |
|
|
break;
|
| 1610 |
|
|
|
| 1611 |
|
|
#ifdef KEY
|
| 1612 |
|
|
case GS_RESULT_DECL: // bug 3878
|
| 1613 |
|
|
#if 0
|
| 1614 |
|
|
// wgen clean-up: These codes, needed to handle gimplified GNU tree
|
| 1615 |
|
|
should not be needed any more.
|
| 1616 |
|
|
if (TY_return_in_mem
|
| 1617 |
|
|
(Get_TY
|
| 1618 |
|
|
(gs_tree_type
|
| 1619 |
|
|
(gs_tree_type
|
| 1620 |
|
|
(Current_Function_Decl()) ) ) ) )
|
| 1621 |
|
|
{
|
| 1622 |
|
|
// We should have already set up the first formal for holding
|
| 1623 |
|
|
// the return object.
|
| 1624 |
|
|
WN *first_formal = WN_formal(Current_Entry_WN(), 0);
|
| 1625 |
|
|
if (!get_DECL_ST(decl_node))
|
| 1626 |
|
|
set_DECL_ST(decl_node, WN_st(first_formal));
|
| 1627 |
|
|
return get_DECL_ST(decl_node);
|
| 1628 |
|
|
}
|
| 1629 |
|
|
// fall through
|
| 1630 |
|
|
#endif
|
| 1631 |
|
|
#endif
|
| 1632 |
|
|
case GS_PARM_DECL:
|
| 1633 |
|
|
case GS_VAR_DECL:
|
| 1634 |
|
|
{
|
| 1635 |
|
|
if (gs_tree_code(decl_node) == GS_PARM_DECL) {
|
| 1636 |
860 |
hucheng |
#ifdef KEY
|
| 1637 |
|
|
// wgen fix for C++ and also for C, as in bug 8346.
|
| 1638 |
|
|
if (decl_arguments) {
|
| 1639 |
736 |
fengzhou |
st = Search_decl_arguments(gs_decl_name(decl_node) ? name : NULL);
|
| 1640 |
|
|
if (st) {
|
| 1641 |
|
|
set_DECL_ST(decl_node, st); // created now
|
| 1642 |
|
|
return st;
|
| 1643 |
|
|
}
|
| 1644 |
|
|
}
|
| 1645 |
|
|
#endif
|
| 1646 |
|
|
sclass = SCLASS_FORMAL;
|
| 1647 |
|
|
eclass = EXPORT_LOCAL;
|
| 1648 |
|
|
level = CURRENT_SYMTAB;
|
| 1649 |
|
|
}
|
| 1650 |
|
|
else {
|
| 1651 |
|
|
if (gs_decl_context (decl_node) == 0 ||
|
| 1652 |
|
|
gs_tree_code (gs_decl_context (decl_node)) == GS_NAMESPACE_DECL ||
|
| 1653 |
|
|
gs_tree_code (gs_decl_context (decl_node)) == GS_RECORD_TYPE ) {
|
| 1654 |
|
|
if (gs_tree_public (decl_node)) {
|
| 1655 |
|
|
// GCC 3.2
|
| 1656 |
|
|
if (gs_decl_external(decl_node) ||
|
| 1657 |
|
|
(gs_decl_lang_specific(decl_node) &&
|
| 1658 |
|
|
gs_decl_really_extern(decl_node)))
|
| 1659 |
|
|
sclass = SCLASS_EXTERN;
|
| 1660 |
|
|
else
|
| 1661 |
|
|
if (gs_decl_initial(decl_node))
|
| 1662 |
|
|
sclass = SCLASS_UGLOBAL;
|
| 1663 |
|
|
else if (gs_tree_static(decl_node)) {
|
| 1664 |
|
|
#ifdef KEY
|
| 1665 |
|
|
// bugs 340, 3717
|
| 1666 |
1950 |
laijx |
if (flag_no_common || !gs_decl_common (decl_node) ||
|
| 1667 |
|
|
(!lang_cplus /* bug 14187 */ &&
|
| 1668 |
|
|
gs_decl_section_name (decl_node) /* bug 14181 */))
|
| 1669 |
736 |
fengzhou |
#else
|
| 1670 |
|
|
if (flag_no_common)
|
| 1671 |
|
|
#endif
|
| 1672 |
|
|
sclass = SCLASS_UGLOBAL;
|
| 1673 |
|
|
else
|
| 1674 |
|
|
sclass = SCLASS_COMMON;
|
| 1675 |
|
|
}
|
| 1676 |
|
|
else
|
| 1677 |
|
|
sclass = SCLASS_EXTERN;
|
| 1678 |
|
|
eclass = EXPORT_PREEMPTIBLE;
|
| 1679 |
|
|
}
|
| 1680 |
|
|
else {
|
| 1681 |
|
|
sclass = SCLASS_FSTATIC;
|
| 1682 |
|
|
eclass = EXPORT_LOCAL;
|
| 1683 |
|
|
}
|
| 1684 |
|
|
level = GLOBAL_SYMTAB;
|
| 1685 |
|
|
}
|
| 1686 |
|
|
else {
|
| 1687 |
|
|
#ifdef KEY
|
| 1688 |
|
|
// .gnu.linkonce.b is .bss with DECL_ONE_ONLY set. Bug 10876.
|
| 1689 |
|
|
gs_t section_name = gs_decl_section_name(decl_node);
|
| 1690 |
|
|
if (section_name &&
|
| 1691 |
|
|
!strncmp(gs_tree_string_pointer(section_name),
|
| 1692 |
|
|
".gnu.linkonce.", 14)) {
|
| 1693 |
|
|
if (!strncmp(gs_tree_string_pointer(section_name),
|
| 1694 |
1411 |
laijx |
".gnu.linkonce.b.", 16)
|
| 1695 |
|
|
// bug 13054
|
| 1696 |
|
|
|| !strncmp(gs_tree_string_pointer(section_name),
|
| 1697 |
|
|
".gnu.linkonce.sb.", 17)) {
|
| 1698 |
736 |
fengzhou |
sclass = SCLASS_UGLOBAL;
|
| 1699 |
|
|
level = GLOBAL_SYMTAB;
|
| 1700 |
|
|
eclass = EXPORT_PREEMPTIBLE;
|
| 1701 |
|
|
} else {
|
| 1702 |
|
|
// Add support as needed.
|
| 1703 |
|
|
Fail_FmtAssertion("Create_ST_For_Tree: %s section NYI",
|
| 1704 |
|
|
gs_tree_string_pointer(section_name));
|
| 1705 |
|
|
}
|
| 1706 |
1411 |
laijx |
}
|
| 1707 |
|
|
// bug 13090 and 13245
|
| 1708 |
|
|
// Bug 13047 shows that the gnu42 front-end (specifically
|
| 1709 |
|
|
// the gcc/g++ part) behaves differently when built on a gnu3
|
| 1710 |
|
|
// system, than when built on a gnu4 system. If the compiler
|
| 1711 |
|
|
// is built on a gnu4 system, default_unique_section() in
|
| 1712 |
|
|
// varasm.c will never generate a linkonce section because
|
| 1713 |
|
|
// starting GNU42, this also depends on whether the host
|
| 1714 |
|
|
// compiling system has COMDAT groups.
|
| 1715 |
|
|
else if (section_name &&
|
| 1716 |
|
|
(!strncmp(gs_tree_string_pointer(section_name),
|
| 1717 |
|
|
".sbss.", 6) ||
|
| 1718 |
|
|
!strncmp(gs_tree_string_pointer(section_name),
|
| 1719 |
|
|
".bss.", 5))) {
|
| 1720 |
|
|
sclass = SCLASS_UGLOBAL;
|
| 1721 |
|
|
level = GLOBAL_SYMTAB;
|
| 1722 |
|
|
eclass = EXPORT_PREEMPTIBLE;
|
| 1723 |
|
|
}
|
| 1724 |
|
|
else
|
| 1725 |
736 |
fengzhou |
#endif
|
| 1726 |
961 |
laijx |
if (gs_decl_external(decl_node) || gs_decl_weak(decl_node)) {
|
| 1727 |
|
|
// OSP_255
|
| 1728 |
|
|
// Not all weak symbols are EXTERN: COMMON&WEAK, STATIC&WEAK
|
| 1729 |
|
|
if (!flag_no_common && gs_decl_common (decl_node)) {
|
| 1730 |
|
|
// COMMON & WEAK:
|
| 1731 |
|
|
// static vars in exported inline/template functions(IA64)
|
| 1732 |
|
|
sclass = SCLASS_COMMON;
|
| 1733 |
|
|
}
|
| 1734 |
|
|
else if (gs_tree_static (decl_node)) {
|
| 1735 |
|
|
// STATIC & WEAK:
|
| 1736 |
|
|
// static vars in exported inline/template function(X8664)
|
| 1737 |
|
|
sclass = SCLASS_UGLOBAL;
|
| 1738 |
|
|
}
|
| 1739 |
|
|
else {
|
| 1740 |
|
|
// OTHERS:
|
| 1741 |
|
|
// treat it EXTERN ( will not allocate space )
|
| 1742 |
|
|
sclass = SCLASS_EXTERN;
|
| 1743 |
|
|
}
|
| 1744 |
736 |
fengzhou |
level = GLOBAL_SYMTAB;
|
| 1745 |
|
|
eclass = EXPORT_PREEMPTIBLE;
|
| 1746 |
|
|
}
|
| 1747 |
|
|
#ifdef KEY
|
| 1748 |
|
|
// Bug 8652: If GNU marks it as COMMON, we should the same.
|
| 1749 |
987 |
hucheng |
else if (!flag_no_common &&
|
| 1750 |
|
|
gs_tree_static (decl_node) &&
|
| 1751 |
|
|
gs_decl_common (decl_node) &&
|
| 1752 |
|
|
gs_tree_public (decl_node)) {
|
| 1753 |
736 |
fengzhou |
sclass = SCLASS_COMMON;
|
| 1754 |
|
|
level = GLOBAL_SYMTAB;
|
| 1755 |
|
|
eclass = EXPORT_PREEMPTIBLE;
|
| 1756 |
|
|
}
|
| 1757 |
|
|
#endif
|
| 1758 |
|
|
else {
|
| 1759 |
|
|
if (gs_tree_static (decl_node)) {
|
| 1760 |
|
|
sclass = SCLASS_PSTATIC;
|
| 1761 |
991 |
rhundt |
if (pstatic_as_global
|
| 1762 |
|
|
#ifdef KEY // bug 12668
|
| 1763 |
|
|
&& ! (gs_decl_initial(decl_node) &&
|
| 1764 |
|
|
!gs_decl_external(decl_node) &&
|
| 1765 |
|
|
Has_label_decl(gs_decl_initial(decl_node)))
|
| 1766 |
|
|
#endif
|
| 1767 |
|
|
)
|
| 1768 |
736 |
fengzhou |
level = GLOBAL_SYMTAB;
|
| 1769 |
|
|
else
|
| 1770 |
|
|
level = CURRENT_SYMTAB;
|
| 1771 |
|
|
}
|
| 1772 |
|
|
else {
|
| 1773 |
|
|
sclass = SCLASS_AUTO;
|
| 1774 |
|
|
level = DECL_SYMTAB_IDX(decl_node) ?
|
| 1775 |
|
|
DECL_SYMTAB_IDX(decl_node) : CURRENT_SYMTAB;
|
| 1776 |
|
|
}
|
| 1777 |
|
|
eclass = EXPORT_LOCAL;
|
| 1778 |
|
|
}
|
| 1779 |
|
|
}
|
| 1780 |
|
|
}
|
| 1781 |
2314 |
laijx |
// Make g++ guard variables local unless it's weak.
|
| 1782 |
736 |
fengzhou |
if (guard_var) {
|
| 1783 |
|
|
level = GLOBAL_SYMTAB;
|
| 1784 |
2314 |
laijx |
if ( gs_decl_weak(decl_node) ) {
|
| 1785 |
|
|
sclass = SCLASS_UGLOBAL;
|
| 1786 |
|
|
eclass = EXPORT_PREEMPTIBLE;
|
| 1787 |
|
|
}
|
| 1788 |
|
|
else {
|
| 1789 |
|
|
sclass = SCLASS_PSTATIC;
|
| 1790 |
|
|
eclass = EXPORT_LOCAL;
|
| 1791 |
|
|
}
|
| 1792 |
736 |
fengzhou |
}
|
| 1793 |
|
|
|
| 1794 |
|
|
// The tree under DECL_ARG_TYPE(decl_node) could reference decl_node.
|
| 1795 |
|
|
// If that's the case, the Get_TY would create the ST for decl_node.
|
| 1796 |
|
|
// As a result, call GET_TY first, then check if the ST is already
|
| 1797 |
|
|
// created, and create ST only if it isn't created.
|
| 1798 |
|
|
ty_idx = Get_TY (gs_tree_type(decl_node));
|
| 1799 |
|
|
st = DECL_ST(decl_node);
|
| 1800 |
|
|
if (st)
|
| 1801 |
|
|
return st;
|
| 1802 |
|
|
st = New_ST (level);
|
| 1803 |
|
|
if (TY_kind (ty_idx) == KIND_ARRAY &&
|
| 1804 |
|
|
gs_tree_static (decl_node) &&
|
| 1805 |
|
|
gs_decl_initial (decl_node) == FALSE &&
|
| 1806 |
|
|
TY_size (ty_idx) == 0) {
|
| 1807 |
|
|
Set_TY_size (ty_idx, TY_size (Get_TY (gs_tree_type (gs_tree_type (decl_node)))));
|
| 1808 |
|
|
}
|
| 1809 |
|
|
#ifndef KEY
|
| 1810 |
|
|
// bug 3735: the compiler cannot arbitrarily change the alignment of
|
| 1811 |
|
|
// individual structures
|
| 1812 |
|
|
if (TY_mtype (ty_idx) == MTYPE_M &&
|
| 1813 |
|
|
Aggregate_Alignment > 0 &&
|
| 1814 |
|
|
Aggregate_Alignment > TY_align (ty_idx))
|
| 1815 |
|
|
Set_TY_align (ty_idx, Aggregate_Alignment);
|
| 1816 |
|
|
#endif // !KEY
|
| 1817 |
|
|
// qualifiers are set on decl nodes
|
| 1818 |
|
|
if (gs_tree_readonly(decl_node))
|
| 1819 |
|
|
Set_TY_is_const (ty_idx);
|
| 1820 |
|
|
if (gs_tree_this_volatile(decl_node))
|
| 1821 |
|
|
Set_TY_is_volatile (ty_idx);
|
| 1822 |
|
|
#if 1 // wgen bug 10470
|
| 1823 |
|
|
else Clear_TY_is_volatile (ty_idx);
|
| 1824 |
|
|
#endif
|
| 1825 |
|
|
#ifdef KEY
|
| 1826 |
|
|
// Handle aligned attribute (bug 7331)
|
| 1827 |
|
|
if (gs_decl_user_align (decl_node))
|
| 1828 |
|
|
Set_TY_align (ty_idx, gs_decl_align_unit(decl_node));
|
| 1829 |
|
|
// NOTE: we do not update the ty_idx value in the TYPE_TREE. So
|
| 1830 |
|
|
// if any of the above properties are set, the next time we get into
|
| 1831 |
|
|
// Get_ST, the ty_idx in the TYPE_TREE != ty_idx in st. The solution
|
| 1832 |
|
|
// is either to update TYPE_TREE now, or compare the ty_idx_index
|
| 1833 |
|
|
// in Get_ST (instead of ty_idx). Currently we do the latter
|
| 1834 |
|
|
#endif // KEY
|
| 1835 |
|
|
// bug 34 3356 10892: gcc sometimes adds a '*' and itself handles it
|
| 1836 |
|
|
// this way while outputing
|
| 1837 |
|
|
char *p = name;
|
| 1838 |
|
|
if (*p == '*')
|
| 1839 |
|
|
p++;
|
| 1840 |
|
|
ST_Init (st, Save_Str(p), CLASS_VAR, sclass, eclass, ty_idx);
|
| 1841 |
|
|
#ifdef KEY
|
| 1842 |
1411 |
laijx |
#ifdef FE_GNU_4_2_0
|
| 1843 |
|
|
if (gs_tree_code (decl_node) == GS_VAR_DECL &&
|
| 1844 |
|
|
// Bug 12968: just checking for threadprivate flag is not
|
| 1845 |
|
|
// sufficient, because for C the flag is basically
|
| 1846 |
|
|
// gs_decl_lang_flag_3.
|
| 1847 |
|
|
gs_decl_thread_local (decl_node) &&
|
| 1848 |
|
|
((!lang_cplus && gs_c_decl_threadprivate_p (decl_node)) ||
|
| 1849 |
|
|
(lang_cplus && gs_cp_decl_threadprivate_p (decl_node))))
|
| 1850 |
736 |
fengzhou |
Set_ST_is_thread_private (st);
|
| 1851 |
1411 |
laijx |
|
| 1852 |
736 |
fengzhou |
if (gs_tree_code (decl_node) == GS_VAR_DECL && anon_st)
|
| 1853 |
|
|
WGEN_add_pragma_to_enclosing_regions (WN_PRAGMA_LOCAL, st);
|
| 1854 |
|
|
#endif
|
| 1855 |
|
|
|
| 1856 |
|
|
if (gs_decl_size_unit (decl_node) &&
|
| 1857 |
|
|
gs_tree_code (gs_decl_size_unit (decl_node)) != GS_INTEGER_CST)
|
| 1858 |
|
|
{
|
| 1859 |
|
|
// if this is the first alloca, save sp.
|
| 1860 |
|
|
int idx;
|
| 1861 |
|
|
if (!Set_Current_Scope_Has_Alloca (idx))
|
| 1862 |
|
|
{
|
| 1863 |
|
|
ST * save_st = WGEN_Alloca_0 ();
|
| 1864 |
|
|
Set_Current_Scope_Alloca_St (save_st, idx);
|
| 1865 |
|
|
}
|
| 1866 |
|
|
WN * size = WGEN_Expand_Expr (gs_decl_size_unit (decl_node));
|
| 1867 |
|
|
// mimic WGEN_Alloca_ST
|
| 1868 |
|
|
ST * alloca_st = New_ST (CURRENT_SYMTAB);
|
| 1869 |
|
|
ST_Init (alloca_st, Save_Str (name),
|
| 1870 |
|
|
CLASS_VAR, SCLASS_AUTO, EXPORT_LOCAL,
|
| 1871 |
|
|
Make_Pointer_Type (ty_idx, FALSE));
|
| 1872 |
|
|
Set_ST_is_temp_var (alloca_st);
|
| 1873 |
|
|
Set_ST_pt_to_unique_mem (alloca_st);
|
| 1874 |
|
|
Set_ST_base_idx (st, ST_st_idx (alloca_st));
|
| 1875 |
|
|
WN *wn = WN_CreateAlloca (size);
|
| 1876 |
|
|
wn = WN_Stid (Pointer_Mtype, 0, alloca_st, ST_type (alloca_st), wn);
|
| 1877 |
|
|
WGEN_Stmt_Append (wn, Get_Srcpos());
|
| 1878 |
|
|
Set_PU_has_alloca (Get_Current_PU());
|
| 1879 |
|
|
// For kids 1..n of DEALLOCA
|
| 1880 |
|
|
Add_Current_Scope_Alloca_St (alloca_st, idx);
|
| 1881 |
|
|
}
|
| 1882 |
|
|
#endif // KEY
|
| 1883 |
|
|
if (gs_tree_code(decl_node) == GS_PARM_DECL) {
|
| 1884 |
|
|
Set_ST_is_value_parm(st);
|
| 1885 |
|
|
}
|
| 1886 |
|
|
}
|
| 1887 |
|
|
break;
|
| 1888 |
|
|
default:
|
| 1889 |
|
|
{
|
| 1890 |
|
|
Fail_FmtAssertion ("Create_ST_For_Tree: unexpected tree type %s",
|
| 1891 |
|
|
WGEN_Tree_Node_Name(decl_node));
|
| 1892 |
|
|
}
|
| 1893 |
|
|
break;
|
| 1894 |
|
|
}
|
| 1895 |
|
|
|
| 1896 |
|
|
set_DECL_ST(decl_node, st); // created now
|
| 1897 |
|
|
|
| 1898 |
|
|
// If VAR_DECL has a non-zero DECL_ASMREG, then DECL_ASMREG-1 is the register
|
| 1899 |
|
|
// number assigned by an "asm".
|
| 1900 |
1411 |
laijx |
if (gs_tree_code(decl_node) == GS_VAR_DECL && gs_decl_register(decl_node) &&
|
| 1901 |
1950 |
laijx |
gs_decl_asmreg(decl_node) >= 0) {
|
| 1902 |
736 |
fengzhou |
extern PREG_NUM Map_Reg_To_Preg []; // defined in common/com/arch/config_targ.cxx
|
| 1903 |
1411 |
laijx |
int reg = gs_decl_asmreg(decl_node);
|
| 1904 |
736 |
fengzhou |
PREG_NUM preg = Map_Reg_To_Preg [reg];
|
| 1905 |
2694 |
shenruifen |
#if defined(TARG_SL)
|
| 1906 |
|
|
if (preg < 0 || preg > 31)
|
| 1907 |
|
|
ErrMsg (EC_Unimplemented_Feature, "Variable in Special register",
|
| 1908 |
|
|
Orig_Src_File_Name?Orig_Src_File_Name:Src_File_Name, lineno);
|
| 1909 |
|
|
#endif
|
| 1910 |
|
|
|
| 1911 |
736 |
fengzhou |
FmtAssert (preg >= 0,
|
| 1912 |
|
|
("mapping register %d to preg failed\n", reg));
|
| 1913 |
|
|
TY_IDX ty_idx = ST_type (st);
|
| 1914 |
|
|
Set_TY_is_volatile (ty_idx);
|
| 1915 |
|
|
Set_ST_type (st, ty_idx);
|
| 1916 |
|
|
Set_ST_assigned_to_dedicated_preg (st);
|
| 1917 |
|
|
ST_ATTR_IDX st_attr_idx;
|
| 1918 |
1064 |
laijx |
// OSP_325, change CURRENT_SYMTAB to level to
|
| 1919 |
|
|
// make the level of the ST and ST_ATTR the same.
|
| 1920 |
|
|
ST_ATTR& st_attr = New_ST_ATTR (level, st_attr_idx);
|
| 1921 |
736 |
fengzhou |
ST_ATTR_Init (st_attr, ST_st_idx (st), ST_ATTR_DEDICATED_REGISTER, preg);
|
| 1922 |
|
|
}
|
| 1923 |
|
|
|
| 1924 |
1411 |
laijx |
if (gs_tree_code(decl_node) == GS_VAR_DECL) {
|
| 1925 |
|
|
if (gs_decl_context(decl_node) &&
|
| 1926 |
|
|
gs_tree_code(gs_decl_context(decl_node)) == GS_RECORD_TYPE) {
|
| 1927 |
|
|
Get_TY(gs_decl_context(decl_node));
|
| 1928 |
|
|
}
|
| 1929 |
|
|
if (gs_decl_thread_local(decl_node)
|
| 1930 |
|
|
#ifdef FE_GNU_4_2_0
|
| 1931 |
|
|
// Bug 12891: threadprivate variables are also marked thread-local
|
| 1932 |
|
|
// by GNU, but we don't want to tell our backend such variables are
|
| 1933 |
|
|
// thread-local.
|
| 1934 |
|
|
&& ((!lang_cplus && !gs_c_decl_threadprivate_p(decl_node)) ||
|
| 1935 |
|
|
(lang_cplus && !gs_cp_decl_threadprivate_p(decl_node)))
|
| 1936 |
|
|
#endif
|
| 1937 |
|
|
) {
|
| 1938 |
|
|
Set_ST_is_thread_local(st);
|
| 1939 |
|
|
}
|
| 1940 |
1104 |
paulyuan |
}
|
| 1941 |
736 |
fengzhou |
|
| 1942 |
|
|
if (Enable_WFE_DFE) {
|
| 1943 |
|
|
if (gs_tree_code(decl_node) == GS_VAR_DECL &&
|
| 1944 |
|
|
level == GLOBAL_SYMTAB &&
|
| 1945 |
|
|
!gs_decl_external (decl_node) &&
|
| 1946 |
|
|
gs_decl_initial (decl_node)) {
|
| 1947 |
|
|
Push_Deferred_Function (decl_node);
|
| 1948 |
|
|
}
|
| 1949 |
|
|
}
|
| 1950 |
|
|
|
| 1951 |
|
|
if (gs_decl_weak (decl_node) &&
|
| 1952 |
|
|
(!gs_decl_external (decl_node)
|
| 1953 |
|
|
#ifdef KEY
|
| 1954 |
|
|
// Make weak symbols for:
|
| 1955 |
|
|
// extern "C" int bar() __attribute__ ((weak, alias("foo")))
|
| 1956 |
|
|
// Bug 3841.
|
| 1957 |
|
|
|| gs_decl_alias_target(decl_node))
|
| 1958 |
|
|
#endif
|
| 1959 |
|
|
) {
|
| 1960 |
|
|
Set_ST_is_weak_symbol (st);
|
| 1961 |
|
|
}
|
| 1962 |
|
|
|
| 1963 |
|
|
#ifdef KEY
|
| 1964 |
|
|
// Make all symbols referenced in cleanup code and try handler code weak.
|
| 1965 |
|
|
// This is to work around an implementation issue where kg++fe always emit
|
| 1966 |
|
|
// the code in a cleanup or try handler, regardless of whether such code is
|
| 1967 |
|
|
// emitted by g++. If the code calls a function foo that isn't emitted by
|
| 1968 |
|
|
// g++ into the RTL, then foo won't be tagged as needed, and the WHIRL for
|
| 1969 |
|
|
// foo won't be genterated. This leads to undefined symbol at link-time.
|
| 1970 |
|
|
//
|
| 1971 |
|
|
// The correct solution is to mimick g++ and generate the cleanup/handler
|
| 1972 |
|
|
// code only if the region can generate an exception. g++ does this in
|
| 1973 |
|
|
// except.c by checking for "(flag_non_call_exceptions ||
|
| 1974 |
|
|
// region->may_contain_throw)". This checking isn't done in kg++fe because
|
| 1975 |
|
|
// the equivalent of "region->may_contain_throw" isn't (yet) implemented.
|
| 1976 |
|
|
// For now, work around the problem by making all symbols refereced in
|
| 1977 |
|
|
// cleanups and try handlers as weak.
|
| 1978 |
|
|
if (make_symbols_weak) {
|
| 1979 |
|
|
if (eclass != EXPORT_LOCAL &&
|
| 1980 |
|
|
eclass != EXPORT_LOCAL_INTERNAL &&
|
| 1981 |
|
|
// Don't make symbol weak if it is defined in current file. Workaround
|
| 1982 |
|
|
// for SLES 8 linker. Bug 3758.
|
| 1983 |
|
|
WEAK_WORKAROUND(st) != WEAK_WORKAROUND_dont_make_weak &&
|
| 1984 |
|
|
// Don't make builtin functions weak. Bug 9534.
|
| 1985 |
|
|
!(gs_tree_code(decl_node) == GS_FUNCTION_DECL &&
|
| 1986 |
|
|
gs_decl_built_in(decl_node))) {
|
| 1987 |
|
|
Set_ST_is_weak_symbol (st);
|
| 1988 |
|
|
WEAK_WORKAROUND(st) = WEAK_WORKAROUND_made_weak;
|
| 1989 |
|
|
}
|
| 1990 |
|
|
}
|
| 1991 |
|
|
// See comment above about guard variables.
|
| 1992 |
|
|
else if (guard_var) {
|
| 1993 |
2314 |
laijx |
if ( gs_decl_weak(decl_node) ) {
|
| 1994 |
|
|
Set_ST_is_weak_symbol (st);
|
| 1995 |
|
|
}
|
| 1996 |
736 |
fengzhou |
Set_ST_init_value_zero (st);
|
| 1997 |
|
|
Set_ST_is_initialized (st);
|
| 1998 |
|
|
}
|
| 1999 |
|
|
#endif
|
| 2000 |
|
|
|
| 2001 |
1950 |
laijx |
if (gs_decl_section_name (decl_node)) {
|
| 2002 |
1532 |
laijx |
if (strncmp(gs_tree_string_pointer (gs_decl_section_name (decl_node)),
|
| 2003 |
|
|
".gnu.linkonce.",
|
| 2004 |
|
|
14) != 0 ) {
|
| 2005 |
|
|
// OSP. only handle non-.gnu.linkonce.* section name
|
| 2006 |
1950 |
laijx |
DevWarn ("section %s specified for %s",
|
| 2007 |
|
|
gs_tree_string_pointer (gs_decl_section_name (decl_node)),
|
| 2008 |
|
|
ST_name (st));
|
| 2009 |
|
|
if (gs_tree_code (decl_node) == GS_FUNCTION_DECL)
|
| 2010 |
|
|
level = GLOBAL_SYMTAB;
|
| 2011 |
|
|
ST_ATTR_IDX st_attr_idx;
|
| 2012 |
|
|
ST_ATTR& st_attr = New_ST_ATTR (level, st_attr_idx);
|
| 2013 |
|
|
ST_ATTR_Init (st_attr, ST_st_idx (st), ST_ATTR_SECTION_NAME,
|
| 2014 |
|
|
Save_Str (gs_tree_string_pointer (gs_decl_section_name (decl_node))));
|
| 2015 |
|
|
if (!lang_cplus) // bug 14187
|
| 2016 |
1487 |
dehao |
Set_ST_has_named_section (st);
|
| 2017 |
1532 |
laijx |
}
|
| 2018 |
|
|
else {
|
| 2019 |
|
|
// OSP. Ignore .gnu.linkonce.* section name
|
| 2020 |
|
|
DevWarn ("Ignore section %s specified for %s",
|
| 2021 |
|
|
gs_tree_string_pointer (gs_decl_section_name (decl_node)),
|
| 2022 |
|
|
ST_name (st));
|
| 2023 |
|
|
}
|
| 2024 |
736 |
fengzhou |
}
|
| 2025 |
988 |
laijx |
|
| 2026 |
2360 |
laijx |
#if defined(TARG_IA64)
|
| 2027 |
988 |
laijx |
//lookup syscall_linkage attribute for FUNCTION_DECL
|
| 2028 |
|
|
if (gs_tree_code (decl_node) == GS_FUNCTION_DECL)
|
| 2029 |
|
|
{
|
| 2030 |
|
|
// Iterate the attributes of the type of the decl
|
| 2031 |
|
|
gs_t type_attr_list = gs_type_attributes(gs_tree_type(decl_node));
|
| 2032 |
|
|
gs_t type_attr;
|
| 2033 |
|
|
for ( type_attr = type_attr_list; type_attr; type_attr = gs_tree_chain(type_attr)) {
|
| 2034 |
|
|
|
| 2035 |
|
|
if (gs_tree_purpose(type_attr) != NULL &&
|
| 2036 |
|
|
gs_code(gs_tree_purpose(type_attr)) == GS_IDENTIFIER_NODE ) {
|
| 2037 |
|
|
const char * attr_name = gs_tree_string_pointer(gs_tree_purpose(type_attr));
|
| 2038 |
|
|
if( strcmp("syscall_linkage", attr_name) == 0 ) {
|
| 2039 |
|
|
// this function has attribute "syscall_linkage"
|
| 2040 |
|
|
DevWarn("Encounter syscall_linkage attribute!!!");
|
| 2041 |
|
|
Set_PU_has_syscall_linkage (Pu_Table [ST_pu(st)]);
|
| 2042 |
|
|
// We only handle the "syscall_linkage" so far
|
| 2043 |
|
|
break;
|
| 2044 |
|
|
}
|
| 2045 |
|
|
}
|
| 2046 |
|
|
}
|
| 2047 |
|
|
}
|
| 2048 |
|
|
#endif
|
| 2049 |
|
|
|
| 2050 |
2360 |
laijx |
if (gs_tree_code (decl_node) == GS_VAR_DECL)
|
| 2051 |
|
|
{
|
| 2052 |
|
|
#if !defined(TARG_NVISA)
|
| 2053 |
|
|
gs_tls_model_kind_t tlsk =
|
| 2054 |
|
|
(gs_tls_model_kind_t) gs_decl_tls_model(decl_node);
|
| 2055 |
|
|
enum ST_TLS_MODEL tls_model = TLS_NONE;
|
| 2056 |
|
|
switch (tlsk) {
|
| 2057 |
|
|
case GS_TLS_MODEL_GLOBAL_DYNAMIC:
|
| 2058 |
|
|
tls_model = TLS_GLOBAL_DYNAMIC;
|
| 2059 |
|
|
break;
|
| 2060 |
|
|
case GS_TLS_MODEL_LOCAL_DYNAMIC:
|
| 2061 |
|
|
tls_model = TLS_LOCAL_DYNAMIC;
|
| 2062 |
|
|
break;
|
| 2063 |
|
|
case GS_TLS_MODEL_INITIAL_EXEC:
|
| 2064 |
|
|
tls_model = TLS_INITIAL_EXEC;
|
| 2065 |
|
|
break;
|
| 2066 |
|
|
case GS_TLS_MODEL_LOCAL_EXEC:
|
| 2067 |
|
|
tls_model = TLS_LOCAL_EXEC;
|
| 2068 |
|
|
break;
|
| 2069 |
|
|
}
|
| 2070 |
|
|
Set_ST_tls_model(st, tls_model);
|
| 2071 |
|
|
#endif
|
| 2072 |
|
|
}
|
| 2073 |
988 |
laijx |
|
| 2074 |
736 |
fengzhou |
if(Debug_Level >= 2) {
|
| 2075 |
|
|
// Bug 559
|
| 2076 |
|
|
if (ST_sclass(st) != SCLASS_EXTERN) {
|
| 2077 |
|
|
// Add DSTs for all types seen so far.
|
| 2078 |
|
|
add_deferred_DST_types();
|
| 2079 |
|
|
|
| 2080 |
|
|
DST_INFO_IDX dst = Create_DST_decl_For_Tree(decl_node,st);
|
| 2081 |
|
|
DECL_DST_IDX(decl_node) = dst;
|
| 2082 |
|
|
}
|
| 2083 |
|
|
}
|
| 2084 |
|
|
|
| 2085 |
|
|
#ifdef KEY
|
| 2086 |
|
|
// Bug 11352: For C++, expand any initializations decl_node may have,
|
| 2087 |
|
|
// after the ST is fully formed. The decl may be in gxx_emitted_decls
|
| 2088 |
|
|
// list, and WGEN_Process_Var_Decl may have decided not to expand it.
|
| 2089 |
|
|
// Now that we are here, we are sure to need any initialization it
|
| 2090 |
|
|
// may have.
|
| 2091 |
|
|
if (lang_cplus && gs_tree_code(decl_node) == GS_VAR_DECL &&
|
| 2092 |
|
|
!expanded_decl(decl_node))
|
| 2093 |
860 |
hucheng |
WGEN_Expand_Decl(decl_node, TRUE);
|
| 2094 |
736 |
fengzhou |
#endif
|
| 2095 |
|
|
|
| 2096 |
|
|
return st;
|
| 2097 |
|
|
}
|
| 2098 |
|
|
|
| 2099 |
|
|
#include <ext/hash_map>
|
| 2100 |
|
|
|
| 2101 |
|
|
namespace {
|
| 2102 |
|
|
|
| 2103 |
|
|
using __gnu_cxx::hash_map;
|
| 2104 |
|
|
|
| 2105 |
|
|
struct ptrhash {
|
| 2106 |
|
|
size_t operator()(void* p) const { return reinterpret_cast<size_t>(p); }
|
| 2107 |
|
|
};
|
| 2108 |
|
|
|
| 2109 |
|
|
hash_map<gs_t, TY_IDX, ptrhash> ty_idx_map;
|
| 2110 |
|
|
hash_map<gs_t, ST*, ptrhash> st_map;
|
| 2111 |
|
|
hash_map<gs_t, SYMTAB_IDX, ptrhash> symtab_idx_map;
|
| 2112 |
|
|
hash_map<gs_t, LABEL_IDX, ptrhash> label_idx_map;
|
| 2113 |
|
|
hash_map<gs_t, ST*, ptrhash> string_st_map;
|
| 2114 |
|
|
hash_map<gs_t, BOOL, ptrhash> bool_map;
|
| 2115 |
|
|
hash_map<gs_t, INT32, ptrhash> field_id_map;
|
| 2116 |
|
|
hash_map<gs_t, INT32, ptrhash> type_field_ids_used_map;
|
| 2117 |
|
|
hash_map<gs_t, INT32, ptrhash> scope_number_map;
|
| 2118 |
|
|
hash_map<gs_t, gs_t, ptrhash> label_scope_map;
|
| 2119 |
|
|
hash_map<gs_t, DST_INFO_IDX,ptrhash> decl_idx_map;
|
| 2120 |
|
|
hash_map<gs_t, DST_INFO_IDX,ptrhash> decl_field_idx_map;
|
| 2121 |
|
|
hash_map<gs_t, DST_INFO_IDX,ptrhash> decl_specification_idx_map;
|
| 2122 |
|
|
hash_map<gs_t, DST_INFO_IDX,ptrhash> type_idx_map;
|
| 2123 |
|
|
hash_map<gs_t, LABEL_IDX, ptrhash> handler_label_map;
|
| 2124 |
|
|
hash_map<gs_t, DST_INFO_IDX,ptrhash> abstract_root_map;
|
| 2125 |
|
|
#ifdef KEY
|
| 2126 |
|
|
// Map PU to the PU-specific st_map.
|
| 2127 |
|
|
hash_map<PU*, hash_map<gs_t, ST*, ptrhash>*, ptrhash> pu_map;
|
| 2128 |
|
|
// TRUE if ST is a decl that is being/already been expanded.
|
| 2129 |
|
|
hash_map<gs_t, BOOL, ptrhash> expanded_decl_map;
|
| 2130 |
|
|
// TRUE if TREE is a DECL_FUNCTION whose PU should have PU_uplevel set.
|
| 2131 |
|
|
hash_map<gs_t, BOOL, ptrhash> func_PU_uplevel_map;
|
| 2132 |
|
|
hash_map<gs_t, gs_t, ptrhash> parent_scope_map;
|
| 2133 |
|
|
// Record whether a symbol referenced in a cleanup should be marked weak as a
|
| 2134 |
|
|
// workaround to the fact that kg++fe may emit cleanups that g++ won't emit
|
| 2135 |
|
|
// because g++ knows that are not needed. The linker will complain if these
|
| 2136 |
|
|
// symbols are not defined.
|
| 2137 |
|
|
hash_map<ST*, INT32, ptrhash> weak_workaround_map;
|
| 2138 |
|
|
#endif
|
| 2139 |
|
|
hash_map<gs_t, ST*, ptrhash> decl_st2_map;
|
| 2140 |
|
|
}
|
| 2141 |
|
|
|
| 2142 |
|
|
TY_IDX& TYPE_TY_IDX(gs_t t) { return ty_idx_map[t]; }
|
| 2143 |
|
|
|
| 2144 |
|
|
BOOL& expanded_decl(gs_t t) {
|
| 2145 |
|
|
FmtAssert (t, ("func_expanded: not a decl"));
|
| 2146 |
|
|
return expanded_decl_map[t];
|
| 2147 |
|
|
}
|
| 2148 |
|
|
|
| 2149 |
|
|
// Put ST in a map based on the tree node T and the current PU.
|
| 2150 |
|
|
void
|
| 2151 |
|
|
set_DECL_ST(gs_t t, ST* st) {
|
| 2152 |
|
|
|
| 2153 |
|
|
// Find the tree node to use as index into st_map.
|
| 2154 |
|
|
gs_t t_index;
|
| 2155 |
|
|
if (gs_tree_code(t) == GS_VAR_DECL &&
|
| 2156 |
|
|
(gs_decl_context(t) == 0 ||
|
| 2157 |
|
|
gs_tree_code(gs_decl_context(t)) == GS_NAMESPACE_DECL) &&
|
| 2158 |
|
|
gs_decl_name (t) && gs_decl_assembler_name(t))
|
| 2159 |
|
|
t_index = gs_decl_assembler_name(t);
|
| 2160 |
|
|
else
|
| 2161 |
|
|
t_index = t;
|
| 2162 |
|
|
|
| 2163 |
|
|
// If ST is 1, then the caller only wants to pretend that there is a symbol
|
| 2164 |
|
|
// for T. Later on, the caller will reset the ST to NULL and assign a real
|
| 2165 |
|
|
// symbol to T.
|
| 2166 |
|
|
if (st == (ST *) 1) {
|
| 2167 |
|
|
st_map[t_index] = st;
|
| 2168 |
|
|
return;
|
| 2169 |
|
|
}
|
| 2170 |
|
|
|
| 2171 |
|
|
// If ST is a symbol that should be shared across functions, then put ST in
|
| 2172 |
|
|
// the st_map, which maps T directly to ST. Otherwise, put ST in the
|
| 2173 |
|
|
// PU-specific st_map.
|
| 2174 |
|
|
//
|
| 2175 |
|
|
// It is observed that g++ uses the same tree for different functions, such
|
| 2176 |
|
|
// as inline functions. As a result, we cannot attach PU-specific ST's
|
| 2177 |
|
|
// directly to the tree nodes.
|
| 2178 |
|
|
//
|
| 2179 |
|
|
// If Current_scope is 0, then the symbol table has not been initialized, and
|
| 2180 |
|
|
// we are being called by WFE_Add_Weak to handle a weak symbol. In that
|
| 2181 |
|
|
// case, use the non-PU-specific st_map.
|
| 2182 |
|
|
if (Current_scope != 0 &&
|
| 2183 |
|
|
(gs_tree_code(t) == GS_PARM_DECL ||
|
| 2184 |
|
|
(gs_tree_code(t) == GS_VAR_DECL &&
|
| 2185 |
|
|
(ST_sclass(st) == SCLASS_AUTO ||
|
| 2186 |
|
|
(! pstatic_as_global &&
|
| 2187 |
|
|
ST_sclass(st) == SCLASS_PSTATIC))))) {
|
| 2188 |
|
|
// ST is PU-specific. Use pu_map[pu] to get the PU-specific st_map, then
|
| 2189 |
|
|
// use st_map[t] to get the ST for the tree node t.
|
| 2190 |
|
|
//
|
| 2191 |
|
|
// We can access pu_map[pu] only if Scope_tab[Current_scope].st is valid
|
| 2192 |
|
|
// because we need to get the current PU, but Get_Current_PU requires a
|
| 2193 |
|
|
// valid Scope_tab[Current_scope].st. If Scope_tab[Current_scope].st is
|
| 2194 |
|
|
// not set, then this means the caller is trying to create the ST for the
|
| 2195 |
|
|
// function symbol.
|
| 2196 |
|
|
if (Scope_tab[Current_scope].st != NULL) {
|
| 2197 |
|
|
// ok to call Get_Current_PU.
|
| 2198 |
|
|
PU *pu = &Get_Current_PU();
|
| 2199 |
|
|
hash_map<PU*, hash_map<gs_t, ST*, ptrhash>*, ptrhash>::iterator it =
|
| 2200 |
|
|
pu_map.find(pu);
|
| 2201 |
|
|
if (it == pu_map.end()) {
|
| 2202 |
|
|
// Create new PU-specific map.
|
| 2203 |
|
|
pu_map[pu] = new hash_map<gs_t, ST*, ptrhash>;
|
| 2204 |
|
|
}
|
| 2205 |
|
|
// Put the ST in the PU-specific st_map.
|
| 2206 |
|
|
(*(pu_map[pu]))[t_index] = st;
|
| 2207 |
|
|
}
|
| 2208 |
|
|
} else {
|
| 2209 |
|
|
#ifdef Is_True_On
|
| 2210 |
|
|
if (st_map[t_index]) {
|
| 2211 |
|
|
// The st_map is already set. This is ok only for weak ST.
|
| 2212 |
|
|
FmtAssert (ST_is_weak_symbol(st_map[t_index]),
|
| 2213 |
|
|
("set_DECL_ST: st_map already set"));
|
| 2214 |
|
|
}
|
| 2215 |
|
|
#endif
|
| 2216 |
|
|
// Put the ST in the non-PU-specific st_map.
|
| 2217 |
|
|
st_map[t_index] = st;
|
| 2218 |
|
|
}
|
| 2219 |
|
|
}
|
| 2220 |
|
|
|
| 2221 |
|
|
// Get ST associated with the tree node T.
|
| 2222 |
|
|
ST*&
|
| 2223 |
|
|
get_DECL_ST(gs_t t) {
|
| 2224 |
|
|
static ST *null_ST = (ST *) NULL;
|
| 2225 |
|
|
|
| 2226 |
|
|
// Find the tree node to use as index into st_map.
|
| 2227 |
|
|
gs_t t_index;
|
| 2228 |
|
|
if (gs_tree_code(t) == GS_VAR_DECL &&
|
| 2229 |
|
|
(gs_decl_context(t) == 0 ||
|
| 2230 |
|
|
gs_tree_code(gs_decl_context(t)) == GS_NAMESPACE_DECL) &&
|
| 2231 |
|
|
gs_decl_name (t) && gs_decl_assembler_name(t))
|
| 2232 |
|
|
t_index = gs_decl_assembler_name(t);
|
| 2233 |
|
|
else
|
| 2234 |
|
|
t_index = t;
|
| 2235 |
|
|
|
| 2236 |
|
|
// If Current_scope is 0, then the symbol table has not been initialized, and
|
| 2237 |
|
|
// we are being called by WFE_Add_Weak to handle a weak symbol. Use the
|
| 2238 |
|
|
// non-PU-specific st_map.
|
| 2239 |
|
|
if (Current_scope == 0)
|
| 2240 |
|
|
return st_map[t_index];
|
| 2241 |
|
|
|
| 2242 |
|
|
// See if the ST is in the non-PU-specific st_map.
|
| 2243 |
|
|
if (st_map[t_index]) {
|
| 2244 |
|
|
return st_map[t_index];
|
| 2245 |
|
|
}
|
| 2246 |
|
|
|
| 2247 |
1950 |
laijx |
// The ST is not in the non-PU-specific map. Look in the PU-specific maps.
|
| 2248 |
|
|
INT scope = Current_scope;
|
| 2249 |
|
|
do {
|
| 2250 |
|
|
// If Scope_tab[scope].st is NULL, then the function ST has not
|
| 2251 |
|
|
// been set yet, and there is no PU-specific map.
|
| 2252 |
|
|
if (Scope_tab[scope].st != NULL) {
|
| 2253 |
|
|
// See if there is a PU-specific map.
|
| 2254 |
|
|
PU *pu = &Get_Scope_PU(scope);
|
| 2255 |
|
|
hash_map<PU*, hash_map<gs_t, ST*, ptrhash>*, ptrhash>::iterator pu_map_it =
|
| 2256 |
|
|
pu_map.find(pu);
|
| 2257 |
|
|
if (pu_map_it != pu_map.end()) {
|
| 2258 |
|
|
// There is a PU-specific map. Get the ST from the map.
|
| 2259 |
|
|
hash_map<gs_t, ST*, ptrhash> *st_map2 = pu_map[pu];
|
| 2260 |
|
|
if ((*st_map2)[t_index])
|
| 2261 |
|
|
return (*st_map2)[t_index];
|
| 2262 |
|
|
}
|
| 2263 |
|
|
}
|
| 2264 |
|
|
scope--;
|
| 2265 |
|
|
} while (scope > 1);
|
| 2266 |
|
|
return null_ST;
|
| 2267 |
736 |
fengzhou |
}
|
| 2268 |
|
|
|
| 2269 |
|
|
BOOL&
|
| 2270 |
|
|
func_PU_uplevel(gs_t t) {
|
| 2271 |
|
|
FmtAssert (gs_tree_code(t) == GS_FUNCTION_DECL,
|
| 2272 |
|
|
("func_PU_uplevel: not a FUNCTION_DECL tree node"));
|
| 2273 |
|
|
return func_PU_uplevel_map[t];
|
| 2274 |
|
|
}
|
| 2275 |
|
|
|
| 2276 |
|
|
INT32& WEAK_WORKAROUND(ST *st) { return weak_workaround_map[st]; }
|
| 2277 |
|
|
|
| 2278 |
|
|
SYMTAB_IDX& DECL_SYMTAB_IDX(gs_t t) { return symtab_idx_map[t]; }
|
| 2279 |
|
|
LABEL_IDX& DECL_LABEL_IDX(gs_t t) { return label_idx_map[t]; }
|
| 2280 |
|
|
ST*& TREE_STRING_ST(gs_t t) { return string_st_map[t]; }
|
| 2281 |
|
|
BOOL& DECL_LABEL_DEFINED(gs_t t) { return bool_map[t]; }
|
| 2282 |
|
|
INT32& DECL_FIELD_ID(gs_t t) { return field_id_map[t]; }
|
| 2283 |
|
|
INT32 & TYPE_FIELD_IDS_USED(gs_t t) { return type_field_ids_used_map[t]; }
|
| 2284 |
|
|
INT32 & SCOPE_NUMBER(gs_t t) { return scope_number_map[t]; }
|
| 2285 |
|
|
#ifdef KEY
|
| 2286 |
|
|
gs_t & PARENT_SCOPE(gs_t t) { return parent_scope_map[t]; }
|
| 2287 |
|
|
#endif
|
| 2288 |
|
|
gs_t & LABEL_SCOPE(gs_t t) { return label_scope_map[t]; }
|
| 2289 |
|
|
ST* & DECL_ST2(gs_t t) { return decl_st2_map[t]; }
|
| 2290 |
|
|
|
| 2291 |
|
|
// This is for normal declarations.
|
| 2292 |
|
|
|
| 2293 |
|
|
// We do not know if the DST entry is filled in.
|
| 2294 |
|
|
// So check and ensure a real entry exists.
|
| 2295 |
|
|
|
| 2296 |
|
|
DST_INFO_IDX & DECL_DST_IDX(gs_t t)
|
| 2297 |
|
|
{
|
| 2298 |
|
|
hash_map<gs_t, DST_INFO_IDX,ptrhash>::iterator it =
|
| 2299 |
|
|
decl_idx_map.find(t);
|
| 2300 |
|
|
if(it == decl_idx_map.end()) {
|
| 2301 |
|
|
// substitute for lack of default constructor
|
| 2302 |
|
|
DST_INFO_IDX dsti = DST_INVALID_IDX;
|
| 2303 |
|
|
decl_idx_map[t] = dsti;
|
| 2304 |
|
|
}
|
| 2305 |
|
|
return decl_idx_map[t];
|
| 2306 |
|
|
}
|
| 2307 |
|
|
// This is for static class members and member functions.
|
| 2308 |
|
|
// We need a distinct DST record for a single ST.
|
| 2309 |
|
|
// Note that only the main record actually need be linked
|
| 2310 |
|
|
// to ST as only that one gets an address/location.
|
| 2311 |
|
|
|
| 2312 |
|
|
// We do not know if the DST entry is filled in.
|
| 2313 |
|
|
// So check and ensure a real entry exists.
|
| 2314 |
|
|
DST_INFO_IDX & DECL_DST_SPECIFICATION_IDX(gs_t t)
|
| 2315 |
|
|
{
|
| 2316 |
|
|
hash_map<gs_t, DST_INFO_IDX,ptrhash>::iterator it =
|
| 2317 |
|
|
decl_specification_idx_map.find(t);
|
| 2318 |
|
|
if(it == decl_specification_idx_map.end()) {
|
| 2319 |
|
|
// substitute for lack of default constructor
|
| 2320 |
|
|
DST_INFO_IDX dsti = DST_INVALID_IDX;
|
| 2321 |
|
|
decl_specification_idx_map[t] = dsti;
|
| 2322 |
|
|
}
|
| 2323 |
|
|
return decl_specification_idx_map[t];
|
| 2324 |
|
|
}
|
| 2325 |
|
|
|
| 2326 |
|
|
// This is for static class members and member functions.
|
| 2327 |
|
|
// We need a distinct DST record for a single ST.
|
| 2328 |
|
|
// Note that only the main record actually need be linked
|
| 2329 |
|
|
// to ST as only that one gets an address/location.
|
| 2330 |
|
|
|
| 2331 |
|
|
// We do not know if the DST entry is filled in.
|
| 2332 |
|
|
// So check and ensure a real entry exists.
|
| 2333 |
|
|
DST_INFO_IDX & DECL_DST_FIELD_IDX(gs_t t)
|
| 2334 |
|
|
{
|
| 2335 |
|
|
hash_map<gs_t, DST_INFO_IDX,ptrhash>::iterator it =
|
| 2336 |
|
|
decl_field_idx_map.find(t);
|
| 2337 |
|
|
if(it == decl_idx_map.end()) {
|
| 2338 |
|
|
// substitute for lack of default constructor
|
| 2339 |
|
|
DST_INFO_IDX dsti = DST_INVALID_IDX;
|
| 2340 |
|
|
decl_field_idx_map[t] = dsti;
|
| 2341 |
|
|
}
|
| 2342 |
|
|
return decl_field_idx_map[t];
|
| 2343 |
|
|
}
|
| 2344 |
|
|
|
| 2345 |
|
|
// We do not know if the DST entry is filled in.
|
| 2346 |
|
|
// So check and ensure a real entry exists.
|
| 2347 |
|
|
DST_INFO_IDX & TYPE_DST_IDX(gs_t t)
|
| 2348 |
|
|
{
|
| 2349 |
|
|
hash_map<gs_t, DST_INFO_IDX,ptrhash>::iterator it =
|
| 2350 |
|
|
type_idx_map.find(t);
|
| 2351 |
|
|
if(it == type_idx_map.end()) {
|
| 2352 |
|
|
// substitute for lack of default constructor
|
| 2353 |
|
|
DST_INFO_IDX dsti = DST_INVALID_IDX;
|
| 2354 |
|
|
type_idx_map[t] = dsti;
|
| 2355 |
|
|
}
|
| 2356 |
|
|
return type_idx_map[t];
|
| 2357 |
|
|
}
|
| 2358 |
|
|
|
| 2359 |
|
|
// We do not know if the DST entry is filled in.
|
| 2360 |
|
|
// So check and ensure a real entry exists.
|
| 2361 |
|
|
DST_INFO_IDX & DECL_DST_ABSTRACT_ROOT_IDX(gs_t t)
|
| 2362 |
|
|
{
|
| 2363 |
|
|
hash_map<gs_t, DST_INFO_IDX,ptrhash>::iterator it =
|
| 2364 |
|
|
abstract_root_map.find(t);
|
| 2365 |
|
|
if(it == abstract_root_map.end()) {
|
| 2366 |
|
|
// substitute for lack of default constructor
|
| 2367 |
|
|
DST_INFO_IDX dsti = DST_INVALID_IDX;
|
| 2368 |
|
|
abstract_root_map[t] = dsti;
|
| 2369 |
|
|
}
|
| 2370 |
|
|
return abstract_root_map[t];
|
| 2371 |
|
|
}
|
| 2372 |
|
|
|
| 2373 |
|
|
|
| 2374 |
|
|
LABEL_IDX& HANDLER_LABEL(gs_t t) { return handler_label_map[t]; }
|