1 1.1 mrg /* d-codegen.cc -- Code generation and routines for manipulation of GCC trees. 2 1.1.1.3 mrg Copyright (C) 2006-2022 Free Software Foundation, Inc. 3 1.1 mrg 4 1.1 mrg GCC is free software; you can redistribute it and/or modify 5 1.1 mrg it under the terms of the GNU General Public License as published by 6 1.1 mrg the Free Software Foundation; either version 3, or (at your option) 7 1.1 mrg any later version. 8 1.1 mrg 9 1.1 mrg GCC is distributed in the hope that it will be useful, 10 1.1 mrg but WITHOUT ANY WARRANTY; without even the implied warranty of 11 1.1 mrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 1.1 mrg GNU General Public License for more details. 13 1.1 mrg 14 1.1 mrg You should have received a copy of the GNU General Public License 15 1.1 mrg along with GCC; see the file COPYING3. If not see 16 1.1 mrg <http://www.gnu.org/licenses/>. */ 17 1.1 mrg 18 1.1 mrg #include "config.h" 19 1.1 mrg #include "system.h" 20 1.1 mrg #include "coretypes.h" 21 1.1 mrg 22 1.1 mrg #include "dmd/aggregate.h" 23 1.1 mrg #include "dmd/ctfe.h" 24 1.1 mrg #include "dmd/declaration.h" 25 1.1 mrg #include "dmd/identifier.h" 26 1.1.1.3 mrg #include "dmd/module.h" 27 1.1 mrg #include "dmd/target.h" 28 1.1 mrg #include "dmd/template.h" 29 1.1 mrg 30 1.1 mrg #include "tree.h" 31 1.1 mrg #include "tree-iterator.h" 32 1.1 mrg #include "fold-const.h" 33 1.1 mrg #include "diagnostic.h" 34 1.1 mrg #include "langhooks.h" 35 1.1 mrg #include "target.h" 36 1.1 mrg #include "stringpool.h" 37 1.1 mrg #include "varasm.h" 38 1.1 mrg #include "stor-layout.h" 39 1.1 mrg #include "attribs.h" 40 1.1 mrg #include "function.h" 41 1.1 mrg 42 1.1 mrg #include "d-tree.h" 43 1.1 mrg 44 1.1 mrg 45 1.1 mrg /* Return the GCC location for the D frontend location LOC. */ 46 1.1 mrg 47 1.1 mrg location_t 48 1.1.1.3 mrg make_location_t (const Loc &loc) 49 1.1 mrg { 50 1.1 mrg location_t gcc_location = input_location; 51 1.1 mrg 52 1.1 mrg if (loc.filename) 53 1.1 mrg { 54 1.1 mrg linemap_add (line_table, LC_ENTER, 0, loc.filename, loc.linnum); 55 1.1 mrg linemap_line_start (line_table, loc.linnum, 0); 56 1.1 mrg gcc_location = linemap_position_for_column (line_table, loc.charnum); 57 1.1 mrg linemap_add (line_table, LC_LEAVE, 0, NULL, 0); 58 1.1 mrg } 59 1.1 mrg 60 1.1 mrg return gcc_location; 61 1.1 mrg } 62 1.1 mrg 63 1.1 mrg /* Return the DECL_CONTEXT for symbol DSYM. */ 64 1.1 mrg 65 1.1 mrg tree 66 1.1 mrg d_decl_context (Dsymbol *dsym) 67 1.1 mrg { 68 1.1 mrg Dsymbol *parent = dsym; 69 1.1 mrg Declaration *decl = dsym->isDeclaration (); 70 1.1.1.2 mrg AggregateDeclaration *ad = dsym->isAggregateDeclaration (); 71 1.1 mrg 72 1.1 mrg while ((parent = parent->toParent2 ())) 73 1.1 mrg { 74 1.1 mrg /* We've reached the top-level module namespace. 75 1.1 mrg Set DECL_CONTEXT as the NAMESPACE_DECL of the enclosing module, 76 1.1 mrg but only for extern(D) symbols. */ 77 1.1 mrg if (parent->isModule ()) 78 1.1 mrg { 79 1.1.1.3 mrg if ((decl != NULL && decl->resolvedLinkage () != LINK::d) 80 1.1.1.2 mrg || (ad != NULL && ad->classKind != ClassKind::d)) 81 1.1 mrg return NULL_TREE; 82 1.1 mrg 83 1.1 mrg return build_import_decl (parent); 84 1.1 mrg } 85 1.1 mrg 86 1.1.1.3 mrg /* Declarations marked as `static' or `__gshared' are never 87 1.1 mrg part of any context except at module level. */ 88 1.1 mrg if (decl != NULL && decl->isDataseg ()) 89 1.1 mrg continue; 90 1.1 mrg 91 1.1 mrg /* Nested functions. */ 92 1.1 mrg FuncDeclaration *fd = parent->isFuncDeclaration (); 93 1.1 mrg if (fd != NULL) 94 1.1 mrg return get_symbol_decl (fd); 95 1.1 mrg 96 1.1 mrg /* Methods of classes or structs. */ 97 1.1 mrg AggregateDeclaration *ad = parent->isAggregateDeclaration (); 98 1.1 mrg if (ad != NULL) 99 1.1 mrg { 100 1.1 mrg tree context = build_ctype (ad->type); 101 1.1 mrg /* Want the underlying RECORD_TYPE. */ 102 1.1 mrg if (ad->isClassDeclaration ()) 103 1.1 mrg context = TREE_TYPE (context); 104 1.1 mrg 105 1.1 mrg return context; 106 1.1 mrg } 107 1.1 mrg } 108 1.1 mrg 109 1.1 mrg return NULL_TREE; 110 1.1 mrg } 111 1.1 mrg 112 1.1 mrg /* Return a copy of record TYPE but safe to modify in any way. */ 113 1.1 mrg 114 1.1 mrg tree 115 1.1 mrg copy_aggregate_type (tree type) 116 1.1 mrg { 117 1.1 mrg tree newtype = build_distinct_type_copy (type); 118 1.1 mrg TYPE_FIELDS (newtype) = copy_list (TYPE_FIELDS (type)); 119 1.1 mrg 120 1.1 mrg for (tree f = TYPE_FIELDS (newtype); f; f = DECL_CHAIN (f)) 121 1.1 mrg DECL_FIELD_CONTEXT (f) = newtype; 122 1.1 mrg 123 1.1 mrg return newtype; 124 1.1 mrg } 125 1.1 mrg 126 1.1 mrg /* Return TRUE if declaration DECL is a reference type. */ 127 1.1 mrg 128 1.1 mrg bool 129 1.1 mrg declaration_reference_p (Declaration *decl) 130 1.1 mrg { 131 1.1 mrg Type *tb = decl->type->toBasetype (); 132 1.1 mrg 133 1.1 mrg /* Declaration is a reference type. */ 134 1.1.1.3 mrg if (tb->ty == TY::Treference || decl->storage_class & (STCout | STCref)) 135 1.1 mrg return true; 136 1.1 mrg 137 1.1 mrg return false; 138 1.1 mrg } 139 1.1 mrg 140 1.1 mrg /* Returns the real type for declaration DECL. */ 141 1.1 mrg 142 1.1 mrg tree 143 1.1 mrg declaration_type (Declaration *decl) 144 1.1 mrg { 145 1.1 mrg /* Lazy declarations are converted to delegates. */ 146 1.1 mrg if (decl->storage_class & STClazy) 147 1.1 mrg { 148 1.1.1.3 mrg TypeFunction *tf = TypeFunction::create (NULL, decl->type, 149 1.1.1.3 mrg VARARGnone, LINK::d); 150 1.1 mrg TypeDelegate *t = TypeDelegate::create (tf); 151 1.1 mrg return build_ctype (t->merge2 ()); 152 1.1 mrg } 153 1.1 mrg 154 1.1 mrg /* Static array va_list have array->pointer conversions applied. */ 155 1.1 mrg if (decl->isParameter () && valist_array_p (decl->type)) 156 1.1 mrg { 157 1.1 mrg Type *valist = decl->type->nextOf ()->pointerTo (); 158 1.1 mrg valist = valist->castMod (decl->type->mod); 159 1.1 mrg return build_ctype (valist); 160 1.1 mrg } 161 1.1 mrg 162 1.1 mrg tree type = build_ctype (decl->type); 163 1.1 mrg 164 1.1 mrg /* Parameter is passed by reference. */ 165 1.1 mrg if (declaration_reference_p (decl)) 166 1.1 mrg return build_reference_type (type); 167 1.1 mrg 168 1.1.1.3 mrg /* The `this' parameter is always const. */ 169 1.1 mrg if (decl->isThisDeclaration ()) 170 1.1 mrg return insert_type_modifiers (type, MODconst); 171 1.1 mrg 172 1.1 mrg return type; 173 1.1 mrg } 174 1.1 mrg 175 1.1 mrg /* These should match the Declaration versions above 176 1.1 mrg Return TRUE if parameter ARG is a reference type. */ 177 1.1 mrg 178 1.1 mrg bool 179 1.1.1.2 mrg parameter_reference_p (Parameter *arg) 180 1.1 mrg { 181 1.1 mrg Type *tb = arg->type->toBasetype (); 182 1.1 mrg 183 1.1 mrg /* Parameter is a reference type. */ 184 1.1.1.3 mrg if (tb->ty == TY::Treference || arg->storageClass & (STCout | STCref)) 185 1.1 mrg return true; 186 1.1 mrg 187 1.1 mrg return false; 188 1.1 mrg } 189 1.1 mrg 190 1.1 mrg /* Returns the real type for parameter ARG. */ 191 1.1 mrg 192 1.1 mrg tree 193 1.1.1.2 mrg parameter_type (Parameter *arg) 194 1.1 mrg { 195 1.1 mrg /* Lazy parameters are converted to delegates. */ 196 1.1 mrg if (arg->storageClass & STClazy) 197 1.1 mrg { 198 1.1.1.3 mrg TypeFunction *tf = TypeFunction::create (NULL, arg->type, 199 1.1.1.3 mrg VARARGnone, LINK::d); 200 1.1 mrg TypeDelegate *t = TypeDelegate::create (tf); 201 1.1 mrg return build_ctype (t->merge2 ()); 202 1.1 mrg } 203 1.1 mrg 204 1.1 mrg /* Static array va_list have array->pointer conversions applied. */ 205 1.1 mrg if (valist_array_p (arg->type)) 206 1.1 mrg { 207 1.1 mrg Type *valist = arg->type->nextOf ()->pointerTo (); 208 1.1 mrg valist = valist->castMod (arg->type->mod); 209 1.1 mrg return build_ctype (valist); 210 1.1 mrg } 211 1.1 mrg 212 1.1 mrg tree type = build_ctype (arg->type); 213 1.1 mrg 214 1.1 mrg /* Parameter is passed by reference. */ 215 1.1.1.2 mrg if (parameter_reference_p (arg)) 216 1.1 mrg return build_reference_type (type); 217 1.1 mrg 218 1.1.1.2 mrg /* Pass non-POD structs by invisible reference. */ 219 1.1.1.2 mrg if (TREE_ADDRESSABLE (type)) 220 1.1.1.2 mrg { 221 1.1.1.2 mrg type = build_reference_type (type); 222 1.1.1.2 mrg /* There are no other pointer to this temporary. */ 223 1.1.1.2 mrg type = build_qualified_type (type, TYPE_QUAL_RESTRICT); 224 1.1.1.2 mrg } 225 1.1.1.2 mrg 226 1.1.1.2 mrg /* Front-end has already taken care of type promotions. */ 227 1.1 mrg return type; 228 1.1 mrg } 229 1.1 mrg 230 1.1 mrg /* Build INTEGER_CST of type TYPE with the value VALUE. */ 231 1.1 mrg 232 1.1 mrg tree 233 1.1 mrg build_integer_cst (dinteger_t value, tree type) 234 1.1 mrg { 235 1.1 mrg /* The type is error_mark_node, we can't do anything. */ 236 1.1 mrg if (error_operand_p (type)) 237 1.1 mrg return type; 238 1.1 mrg 239 1.1 mrg return build_int_cst_type (type, value); 240 1.1 mrg } 241 1.1 mrg 242 1.1 mrg /* Build REAL_CST of type TOTYPE with the value VALUE. */ 243 1.1 mrg 244 1.1 mrg tree 245 1.1.1.3 mrg build_float_cst (const real_t &value, Type *totype) 246 1.1 mrg { 247 1.1.1.3 mrg real_value new_value; 248 1.1 mrg TypeBasic *tb = totype->isTypeBasic (); 249 1.1 mrg 250 1.1 mrg gcc_assert (tb != NULL); 251 1.1 mrg 252 1.1 mrg tree type_node = build_ctype (tb); 253 1.1.1.3 mrg real_convert (&new_value, TYPE_MODE (type_node), &value.rv ()); 254 1.1 mrg 255 1.1.1.3 mrg return build_real (type_node, new_value); 256 1.1 mrg } 257 1.1 mrg 258 1.1 mrg /* Returns the .length component from the D dynamic array EXP. */ 259 1.1 mrg 260 1.1 mrg tree 261 1.1 mrg d_array_length (tree exp) 262 1.1 mrg { 263 1.1 mrg if (error_operand_p (exp)) 264 1.1 mrg return exp; 265 1.1 mrg 266 1.1 mrg gcc_assert (TYPE_DYNAMIC_ARRAY (TREE_TYPE (exp))); 267 1.1 mrg 268 1.1 mrg /* Get the back-end type for the array and pick out the array 269 1.1 mrg length field (assumed to be the first field). */ 270 1.1 mrg tree len_field = TYPE_FIELDS (TREE_TYPE (exp)); 271 1.1 mrg return component_ref (exp, len_field); 272 1.1 mrg } 273 1.1 mrg 274 1.1 mrg /* Returns the .ptr component from the D dynamic array EXP. */ 275 1.1 mrg 276 1.1 mrg tree 277 1.1 mrg d_array_ptr (tree exp) 278 1.1 mrg { 279 1.1 mrg if (error_operand_p (exp)) 280 1.1 mrg return exp; 281 1.1 mrg 282 1.1 mrg gcc_assert (TYPE_DYNAMIC_ARRAY (TREE_TYPE (exp))); 283 1.1 mrg 284 1.1 mrg /* Get the back-end type for the array and pick out the array 285 1.1 mrg data pointer field (assumed to be the second field). */ 286 1.1 mrg tree ptr_field = TREE_CHAIN (TYPE_FIELDS (TREE_TYPE (exp))); 287 1.1 mrg return component_ref (exp, ptr_field); 288 1.1 mrg } 289 1.1 mrg 290 1.1 mrg /* Returns a constructor for D dynamic array type TYPE of .length LEN 291 1.1 mrg and .ptr pointing to DATA. */ 292 1.1 mrg 293 1.1 mrg tree 294 1.1 mrg d_array_value (tree type, tree len, tree data) 295 1.1 mrg { 296 1.1 mrg tree len_field, ptr_field; 297 1.1.1.3 mrg vec <constructor_elt, va_gc> *ce = NULL; 298 1.1 mrg 299 1.1 mrg gcc_assert (TYPE_DYNAMIC_ARRAY (type)); 300 1.1 mrg len_field = TYPE_FIELDS (type); 301 1.1 mrg ptr_field = TREE_CHAIN (len_field); 302 1.1 mrg 303 1.1 mrg len = convert (TREE_TYPE (len_field), len); 304 1.1 mrg data = convert (TREE_TYPE (ptr_field), data); 305 1.1 mrg 306 1.1 mrg CONSTRUCTOR_APPEND_ELT (ce, len_field, len); 307 1.1 mrg CONSTRUCTOR_APPEND_ELT (ce, ptr_field, data); 308 1.1 mrg 309 1.1 mrg return build_constructor (type, ce); 310 1.1 mrg } 311 1.1 mrg 312 1.1 mrg /* Returns value representing the array length of expression EXP. 313 1.1 mrg TYPE could be a dynamic or static array. */ 314 1.1 mrg 315 1.1 mrg tree 316 1.1 mrg get_array_length (tree exp, Type *type) 317 1.1 mrg { 318 1.1 mrg Type *tb = type->toBasetype (); 319 1.1 mrg 320 1.1 mrg switch (tb->ty) 321 1.1 mrg { 322 1.1.1.3 mrg case TY::Tsarray: 323 1.1.1.3 mrg return size_int (tb->isTypeSArray ()->dim->toUInteger ()); 324 1.1 mrg 325 1.1.1.3 mrg case TY::Tarray: 326 1.1 mrg return d_array_length (exp); 327 1.1 mrg 328 1.1 mrg default: 329 1.1.1.2 mrg error ("cannot determine the length of a %qs", type->toChars ()); 330 1.1 mrg return error_mark_node; 331 1.1 mrg } 332 1.1 mrg } 333 1.1 mrg 334 1.1 mrg /* Create BINFO for a ClassDeclaration's inheritance tree. 335 1.1 mrg InterfaceDeclaration's are not included. */ 336 1.1 mrg 337 1.1 mrg tree 338 1.1 mrg build_class_binfo (tree super, ClassDeclaration *cd) 339 1.1 mrg { 340 1.1 mrg tree binfo = make_tree_binfo (1); 341 1.1 mrg tree ctype = build_ctype (cd->type); 342 1.1 mrg 343 1.1 mrg /* Want RECORD_TYPE, not POINTER_TYPE. */ 344 1.1 mrg BINFO_TYPE (binfo) = TREE_TYPE (ctype); 345 1.1 mrg BINFO_INHERITANCE_CHAIN (binfo) = super; 346 1.1 mrg BINFO_OFFSET (binfo) = integer_zero_node; 347 1.1 mrg 348 1.1 mrg if (cd->baseClass) 349 1.1 mrg BINFO_BASE_APPEND (binfo, build_class_binfo (binfo, cd->baseClass)); 350 1.1 mrg 351 1.1 mrg return binfo; 352 1.1 mrg } 353 1.1 mrg 354 1.1 mrg /* Create BINFO for an InterfaceDeclaration's inheritance tree. 355 1.1 mrg In order to access all inherited methods in the debugger, 356 1.1 mrg the entire tree must be described. 357 1.1 mrg This function makes assumptions about interface layout. */ 358 1.1 mrg 359 1.1 mrg tree 360 1.1.1.3 mrg build_interface_binfo (tree super, ClassDeclaration *cd, unsigned &offset) 361 1.1 mrg { 362 1.1.1.3 mrg tree binfo = make_tree_binfo (cd->baseclasses->length); 363 1.1 mrg tree ctype = build_ctype (cd->type); 364 1.1 mrg 365 1.1 mrg /* Want RECORD_TYPE, not POINTER_TYPE. */ 366 1.1 mrg BINFO_TYPE (binfo) = TREE_TYPE (ctype); 367 1.1 mrg BINFO_INHERITANCE_CHAIN (binfo) = super; 368 1.1.1.3 mrg BINFO_OFFSET (binfo) = size_int (offset * target.ptrsize); 369 1.1 mrg BINFO_VIRTUAL_P (binfo) = 1; 370 1.1 mrg 371 1.1.1.3 mrg for (size_t i = 0; i < cd->baseclasses->length; i++, offset++) 372 1.1 mrg { 373 1.1 mrg BaseClass *bc = (*cd->baseclasses)[i]; 374 1.1 mrg BINFO_BASE_APPEND (binfo, build_interface_binfo (binfo, bc->sym, offset)); 375 1.1 mrg } 376 1.1 mrg 377 1.1 mrg return binfo; 378 1.1 mrg } 379 1.1 mrg 380 1.1 mrg /* Returns the .funcptr component from the D delegate EXP. */ 381 1.1 mrg 382 1.1 mrg tree 383 1.1 mrg delegate_method (tree exp) 384 1.1 mrg { 385 1.1 mrg /* Get the back-end type for the delegate and pick out the funcptr field 386 1.1 mrg (assumed to be the second field). */ 387 1.1 mrg gcc_assert (TYPE_DELEGATE (TREE_TYPE (exp))); 388 1.1 mrg tree method_field = TREE_CHAIN (TYPE_FIELDS (TREE_TYPE (exp))); 389 1.1 mrg return component_ref (exp, method_field); 390 1.1 mrg } 391 1.1 mrg 392 1.1 mrg /* Returns the .object component from the delegate EXP. */ 393 1.1 mrg 394 1.1 mrg tree 395 1.1 mrg delegate_object (tree exp) 396 1.1 mrg { 397 1.1 mrg /* Get the back-end type for the delegate and pick out the object field 398 1.1 mrg (assumed to be the first field). */ 399 1.1 mrg gcc_assert (TYPE_DELEGATE (TREE_TYPE (exp))); 400 1.1 mrg tree obj_field = TYPE_FIELDS (TREE_TYPE (exp)); 401 1.1 mrg return component_ref (exp, obj_field); 402 1.1 mrg } 403 1.1 mrg 404 1.1 mrg /* Build a delegate literal of type TYPE whose pointer function is 405 1.1 mrg METHOD, and hidden object is OBJECT. */ 406 1.1 mrg 407 1.1 mrg tree 408 1.1 mrg build_delegate_cst (tree method, tree object, Type *type) 409 1.1 mrg { 410 1.1 mrg tree ctor = make_node (CONSTRUCTOR); 411 1.1 mrg tree ctype; 412 1.1 mrg 413 1.1 mrg Type *tb = type->toBasetype (); 414 1.1.1.3 mrg if (tb->ty == TY::Tdelegate) 415 1.1 mrg ctype = build_ctype (type); 416 1.1 mrg else 417 1.1 mrg { 418 1.1 mrg /* Convert a function method into an anonymous delegate. */ 419 1.1 mrg ctype = make_struct_type ("delegate()", 2, 420 1.1 mrg get_identifier ("object"), TREE_TYPE (object), 421 1.1 mrg get_identifier ("func"), TREE_TYPE (method)); 422 1.1 mrg TYPE_DELEGATE (ctype) = 1; 423 1.1 mrg } 424 1.1 mrg 425 1.1.1.3 mrg vec <constructor_elt, va_gc> *ce = NULL; 426 1.1 mrg CONSTRUCTOR_APPEND_ELT (ce, TYPE_FIELDS (ctype), object); 427 1.1 mrg CONSTRUCTOR_APPEND_ELT (ce, TREE_CHAIN (TYPE_FIELDS (ctype)), method); 428 1.1 mrg 429 1.1 mrg CONSTRUCTOR_ELTS (ctor) = ce; 430 1.1 mrg TREE_TYPE (ctor) = ctype; 431 1.1 mrg 432 1.1 mrg return ctor; 433 1.1 mrg } 434 1.1 mrg 435 1.1 mrg /* Builds a temporary tree to store the CALLEE and OBJECT 436 1.1 mrg of a method call expression of type TYPE. */ 437 1.1 mrg 438 1.1 mrg tree 439 1.1 mrg build_method_call (tree callee, tree object, Type *type) 440 1.1 mrg { 441 1.1 mrg tree t = build_delegate_cst (callee, object, type); 442 1.1 mrg METHOD_CALL_EXPR (t) = 1; 443 1.1 mrg return t; 444 1.1 mrg } 445 1.1 mrg 446 1.1 mrg /* Extract callee and object from T and return in to CALLEE and OBJECT. */ 447 1.1 mrg 448 1.1 mrg void 449 1.1.1.3 mrg extract_from_method_call (tree t, tree &callee, tree &object) 450 1.1 mrg { 451 1.1 mrg gcc_assert (METHOD_CALL_EXPR (t)); 452 1.1 mrg object = CONSTRUCTOR_ELT (t, 0)->value; 453 1.1 mrg callee = CONSTRUCTOR_ELT (t, 1)->value; 454 1.1 mrg } 455 1.1 mrg 456 1.1 mrg /* Build a typeof(null) constant of type TYPE. Handles certain special case 457 1.1 mrg conversions, where the underlying type is an aggregate with a nullable 458 1.1 mrg interior pointer. */ 459 1.1 mrg 460 1.1 mrg tree 461 1.1 mrg build_typeof_null_value (Type *type) 462 1.1 mrg { 463 1.1 mrg Type *tb = type->toBasetype (); 464 1.1 mrg tree value; 465 1.1 mrg 466 1.1 mrg /* For dynamic arrays, set length and pointer fields to zero. */ 467 1.1.1.3 mrg if (tb->ty == TY::Tarray) 468 1.1 mrg value = d_array_value (build_ctype (type), size_int (0), null_pointer_node); 469 1.1 mrg 470 1.1 mrg /* For associative arrays, set the pointer field to null. */ 471 1.1.1.3 mrg else if (tb->ty == TY::Taarray) 472 1.1 mrg { 473 1.1 mrg tree ctype = build_ctype (type); 474 1.1 mrg gcc_assert (TYPE_ASSOCIATIVE_ARRAY (ctype)); 475 1.1 mrg 476 1.1 mrg value = build_constructor_single (ctype, TYPE_FIELDS (ctype), 477 1.1 mrg null_pointer_node); 478 1.1 mrg } 479 1.1 mrg 480 1.1 mrg /* For delegates, set the frame and function pointer fields to null. */ 481 1.1.1.3 mrg else if (tb->ty == TY::Tdelegate) 482 1.1 mrg value = build_delegate_cst (null_pointer_node, null_pointer_node, type); 483 1.1 mrg 484 1.1 mrg /* Simple zero constant for all other types. */ 485 1.1 mrg else 486 1.1 mrg value = build_zero_cst (build_ctype (type)); 487 1.1 mrg 488 1.1 mrg TREE_CONSTANT (value) = 1; 489 1.1 mrg return value; 490 1.1 mrg } 491 1.1 mrg 492 1.1 mrg /* Build a dereference into the virtual table for OBJECT to retrieve 493 1.1 mrg a function pointer of type FNTYPE at position INDEX. */ 494 1.1 mrg 495 1.1 mrg tree 496 1.1 mrg build_vindex_ref (tree object, tree fntype, size_t index) 497 1.1 mrg { 498 1.1 mrg /* The vtable is the first field. Interface methods are also in the class's 499 1.1 mrg vtable, so we don't need to convert from a class to an interface. */ 500 1.1 mrg tree result = build_deref (object); 501 1.1 mrg result = component_ref (result, TYPE_FIELDS (TREE_TYPE (result))); 502 1.1 mrg 503 1.1 mrg gcc_assert (POINTER_TYPE_P (fntype)); 504 1.1 mrg 505 1.1.1.3 mrg return build_memref (fntype, result, size_int (target.ptrsize * index)); 506 1.1 mrg } 507 1.1 mrg 508 1.1 mrg /* Return TRUE if EXP is a valid lvalue. Lvalue references cannot be 509 1.1 mrg made into temporaries, otherwise any assignments will be lost. */ 510 1.1 mrg 511 1.1 mrg static bool 512 1.1 mrg lvalue_p (tree exp) 513 1.1 mrg { 514 1.1 mrg const enum tree_code code = TREE_CODE (exp); 515 1.1 mrg 516 1.1 mrg switch (code) 517 1.1 mrg { 518 1.1 mrg case SAVE_EXPR: 519 1.1 mrg return false; 520 1.1 mrg 521 1.1 mrg case ARRAY_REF: 522 1.1 mrg case INDIRECT_REF: 523 1.1 mrg case VAR_DECL: 524 1.1 mrg case PARM_DECL: 525 1.1 mrg case RESULT_DECL: 526 1.1 mrg return !FUNC_OR_METHOD_TYPE_P (TREE_TYPE (exp)); 527 1.1 mrg 528 1.1 mrg case IMAGPART_EXPR: 529 1.1 mrg case REALPART_EXPR: 530 1.1 mrg case COMPONENT_REF: 531 1.1 mrg CASE_CONVERT: 532 1.1 mrg return lvalue_p (TREE_OPERAND (exp, 0)); 533 1.1 mrg 534 1.1 mrg case COND_EXPR: 535 1.1 mrg return (lvalue_p (TREE_OPERAND (exp, 1) 536 1.1 mrg ? TREE_OPERAND (exp, 1) 537 1.1 mrg : TREE_OPERAND (exp, 0)) 538 1.1 mrg && lvalue_p (TREE_OPERAND (exp, 2))); 539 1.1 mrg 540 1.1 mrg case TARGET_EXPR: 541 1.1 mrg return true; 542 1.1 mrg 543 1.1 mrg case COMPOUND_EXPR: 544 1.1 mrg return lvalue_p (TREE_OPERAND (exp, 1)); 545 1.1 mrg 546 1.1 mrg default: 547 1.1 mrg return false; 548 1.1 mrg } 549 1.1 mrg } 550 1.1 mrg 551 1.1 mrg /* Create a SAVE_EXPR if EXP might have unwanted side effects if referenced 552 1.1 mrg more than once in an expression. */ 553 1.1 mrg 554 1.1 mrg tree 555 1.1 mrg d_save_expr (tree exp) 556 1.1 mrg { 557 1.1 mrg if (TREE_SIDE_EFFECTS (exp)) 558 1.1 mrg { 559 1.1 mrg if (lvalue_p (exp)) 560 1.1 mrg return stabilize_reference (exp); 561 1.1 mrg 562 1.1 mrg return save_expr (exp); 563 1.1 mrg } 564 1.1 mrg 565 1.1 mrg return exp; 566 1.1 mrg } 567 1.1 mrg 568 1.1 mrg /* VALUEP is an expression we want to pre-evaluate or perform a computation on. 569 1.1 mrg The expression returned by this function is the part whose value we don't 570 1.1 mrg care about, storing the value in VALUEP. Callers must ensure that the 571 1.1 mrg returned expression is evaluated before VALUEP. */ 572 1.1 mrg 573 1.1 mrg tree 574 1.1 mrg stabilize_expr (tree *valuep) 575 1.1 mrg { 576 1.1 mrg tree expr = *valuep; 577 1.1 mrg const enum tree_code code = TREE_CODE (expr); 578 1.1 mrg tree lhs; 579 1.1 mrg tree rhs; 580 1.1 mrg 581 1.1 mrg switch (code) 582 1.1 mrg { 583 1.1 mrg case COMPOUND_EXPR: 584 1.1 mrg /* Given ((e1, ...), eN): 585 1.1 mrg Store the last RHS 'eN' expression in VALUEP. */ 586 1.1 mrg lhs = TREE_OPERAND (expr, 0); 587 1.1 mrg rhs = TREE_OPERAND (expr, 1); 588 1.1 mrg lhs = compound_expr (lhs, stabilize_expr (&rhs)); 589 1.1 mrg *valuep = rhs; 590 1.1 mrg return lhs; 591 1.1 mrg 592 1.1 mrg default: 593 1.1 mrg return NULL_TREE; 594 1.1 mrg } 595 1.1 mrg } 596 1.1 mrg 597 1.1 mrg /* Return a TARGET_EXPR, initializing the DECL with EXP. */ 598 1.1 mrg 599 1.1 mrg tree 600 1.1 mrg build_target_expr (tree decl, tree exp) 601 1.1 mrg { 602 1.1 mrg tree type = TREE_TYPE (decl); 603 1.1 mrg tree result = build4 (TARGET_EXPR, type, decl, exp, NULL_TREE, NULL_TREE); 604 1.1 mrg 605 1.1 mrg if (EXPR_HAS_LOCATION (exp)) 606 1.1 mrg SET_EXPR_LOCATION (result, EXPR_LOCATION (exp)); 607 1.1 mrg 608 1.1 mrg /* If decl must always reside in memory. */ 609 1.1 mrg if (TREE_ADDRESSABLE (type)) 610 1.1 mrg d_mark_addressable (decl); 611 1.1 mrg 612 1.1 mrg /* Always set TREE_SIDE_EFFECTS so that expand_expr does not ignore the 613 1.1 mrg TARGET_EXPR. If there really turn out to be no side effects, then the 614 1.1 mrg optimizer should be able to remove it. */ 615 1.1 mrg TREE_SIDE_EFFECTS (result) = 1; 616 1.1 mrg 617 1.1 mrg return result; 618 1.1 mrg } 619 1.1 mrg 620 1.1 mrg /* Like the above function, but initializes a new temporary. */ 621 1.1 mrg 622 1.1 mrg tree 623 1.1 mrg force_target_expr (tree exp) 624 1.1 mrg { 625 1.1.1.2 mrg tree decl = build_decl (input_location, VAR_DECL, NULL_TREE, 626 1.1.1.2 mrg TREE_TYPE (exp)); 627 1.1.1.2 mrg DECL_CONTEXT (decl) = current_function_decl; 628 1.1.1.2 mrg DECL_ARTIFICIAL (decl) = 1; 629 1.1.1.2 mrg DECL_IGNORED_P (decl) = 1; 630 1.1.1.2 mrg layout_decl (decl, 0); 631 1.1 mrg 632 1.1 mrg return build_target_expr (decl, exp); 633 1.1 mrg } 634 1.1 mrg 635 1.1 mrg /* Returns the address of the expression EXP. */ 636 1.1 mrg 637 1.1 mrg tree 638 1.1 mrg build_address (tree exp) 639 1.1 mrg { 640 1.1 mrg if (error_operand_p (exp)) 641 1.1 mrg return exp; 642 1.1 mrg 643 1.1 mrg tree ptrtype; 644 1.1 mrg tree type = TREE_TYPE (exp); 645 1.1 mrg 646 1.1 mrg if (TREE_CODE (exp) == STRING_CST) 647 1.1 mrg { 648 1.1 mrg /* Just convert string literals (char[]) to C-style strings (char *), 649 1.1 mrg otherwise the latter method (char[]*) causes conversion problems 650 1.1 mrg during gimplification. */ 651 1.1 mrg ptrtype = build_pointer_type (TREE_TYPE (type)); 652 1.1 mrg } 653 1.1 mrg else if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (va_list_type_node) 654 1.1 mrg && TREE_CODE (TYPE_MAIN_VARIANT (type)) == ARRAY_TYPE) 655 1.1 mrg { 656 1.1 mrg /* Special case for va_list, allow arrays to decay to a pointer. */ 657 1.1 mrg ptrtype = build_pointer_type (TREE_TYPE (type)); 658 1.1 mrg } 659 1.1 mrg else 660 1.1 mrg ptrtype = build_pointer_type (type); 661 1.1 mrg 662 1.1 mrg /* Maybe rewrite: &(e1, e2) => (e1, &e2). */ 663 1.1 mrg tree init = stabilize_expr (&exp); 664 1.1 mrg 665 1.1 mrg /* Can't take the address of a manifest constant, instead use its value. */ 666 1.1 mrg if (TREE_CODE (exp) == CONST_DECL) 667 1.1 mrg exp = DECL_INITIAL (exp); 668 1.1 mrg 669 1.1.1.2 mrg /* Some expression lowering may request an address of a compile-time constant, 670 1.1.1.2 mrg or other non-lvalue expression. Make sure it is assigned to a location we 671 1.1.1.2 mrg can reference. */ 672 1.1.1.3 mrg if (CONSTANT_CLASS_P (exp) && TREE_CODE (exp) != STRING_CST) 673 1.1 mrg exp = force_target_expr (exp); 674 1.1.1.3 mrg else if (TREE_CODE (exp) == CALL_EXPR) 675 1.1.1.3 mrg { 676 1.1.1.3 mrg /* When a struct or array is returned in registers, we need to again fill 677 1.1.1.3 mrg in all alignment holes. */ 678 1.1.1.3 mrg if (AGGREGATE_TYPE_P (TREE_TYPE (exp)) 679 1.1.1.3 mrg && !aggregate_value_p (TREE_TYPE (exp), exp)) 680 1.1.1.3 mrg { 681 1.1.1.3 mrg tree tmp = build_local_temp (TREE_TYPE (exp)); 682 1.1.1.3 mrg init = compound_expr (init, build_memset_call (tmp)); 683 1.1.1.3 mrg init = compound_expr (init, modify_expr (tmp, exp)); 684 1.1.1.3 mrg exp = tmp; 685 1.1.1.3 mrg } 686 1.1.1.3 mrg else 687 1.1.1.3 mrg exp = force_target_expr (exp); 688 1.1.1.3 mrg } 689 1.1 mrg 690 1.1 mrg d_mark_addressable (exp); 691 1.1 mrg exp = build_fold_addr_expr_with_type_loc (input_location, exp, ptrtype); 692 1.1 mrg 693 1.1 mrg if (TREE_CODE (exp) == ADDR_EXPR) 694 1.1 mrg TREE_NO_TRAMPOLINE (exp) = 1; 695 1.1 mrg 696 1.1 mrg return compound_expr (init, exp); 697 1.1 mrg } 698 1.1 mrg 699 1.1 mrg /* Mark EXP saying that we need to be able to take the 700 1.1 mrg address of it; it should not be allocated in a register. */ 701 1.1 mrg 702 1.1 mrg tree 703 1.1 mrg d_mark_addressable (tree exp) 704 1.1 mrg { 705 1.1 mrg switch (TREE_CODE (exp)) 706 1.1 mrg { 707 1.1 mrg case ADDR_EXPR: 708 1.1 mrg case COMPONENT_REF: 709 1.1 mrg case ARRAY_REF: 710 1.1 mrg case REALPART_EXPR: 711 1.1 mrg case IMAGPART_EXPR: 712 1.1 mrg d_mark_addressable (TREE_OPERAND (exp, 0)); 713 1.1 mrg break; 714 1.1 mrg 715 1.1 mrg case PARM_DECL: 716 1.1 mrg case VAR_DECL: 717 1.1 mrg case RESULT_DECL: 718 1.1 mrg case CONST_DECL: 719 1.1 mrg case FUNCTION_DECL: 720 1.1 mrg TREE_ADDRESSABLE (exp) = 1; 721 1.1 mrg break; 722 1.1 mrg 723 1.1 mrg case CONSTRUCTOR: 724 1.1 mrg TREE_ADDRESSABLE (exp) = 1; 725 1.1 mrg break; 726 1.1 mrg 727 1.1 mrg case TARGET_EXPR: 728 1.1 mrg TREE_ADDRESSABLE (exp) = 1; 729 1.1 mrg d_mark_addressable (TREE_OPERAND (exp, 0)); 730 1.1 mrg break; 731 1.1 mrg 732 1.1 mrg default: 733 1.1 mrg break; 734 1.1 mrg } 735 1.1 mrg 736 1.1 mrg return exp; 737 1.1 mrg } 738 1.1 mrg 739 1.1 mrg /* Mark EXP as "used" in the program for the benefit of 740 1.1 mrg -Wunused warning purposes. */ 741 1.1 mrg 742 1.1 mrg tree 743 1.1 mrg d_mark_used (tree exp) 744 1.1 mrg { 745 1.1 mrg switch (TREE_CODE (exp)) 746 1.1 mrg { 747 1.1 mrg case VAR_DECL: 748 1.1 mrg case CONST_DECL: 749 1.1 mrg case PARM_DECL: 750 1.1 mrg case RESULT_DECL: 751 1.1 mrg case FUNCTION_DECL: 752 1.1 mrg TREE_USED (exp) = 1; 753 1.1 mrg break; 754 1.1 mrg 755 1.1 mrg case ARRAY_REF: 756 1.1 mrg case COMPONENT_REF: 757 1.1 mrg case MODIFY_EXPR: 758 1.1 mrg case REALPART_EXPR: 759 1.1 mrg case IMAGPART_EXPR: 760 1.1 mrg case NOP_EXPR: 761 1.1 mrg case CONVERT_EXPR: 762 1.1 mrg case ADDR_EXPR: 763 1.1 mrg d_mark_used (TREE_OPERAND (exp, 0)); 764 1.1 mrg break; 765 1.1 mrg 766 1.1 mrg case COMPOUND_EXPR: 767 1.1 mrg d_mark_used (TREE_OPERAND (exp, 0)); 768 1.1 mrg d_mark_used (TREE_OPERAND (exp, 1)); 769 1.1 mrg break; 770 1.1 mrg 771 1.1 mrg default: 772 1.1 mrg break; 773 1.1 mrg } 774 1.1 mrg return exp; 775 1.1 mrg } 776 1.1 mrg 777 1.1 mrg /* Mark EXP as read, not just set, for set but not used -Wunused 778 1.1 mrg warning purposes. */ 779 1.1 mrg 780 1.1 mrg tree 781 1.1 mrg d_mark_read (tree exp) 782 1.1 mrg { 783 1.1 mrg switch (TREE_CODE (exp)) 784 1.1 mrg { 785 1.1 mrg case VAR_DECL: 786 1.1 mrg case PARM_DECL: 787 1.1 mrg TREE_USED (exp) = 1; 788 1.1 mrg DECL_READ_P (exp) = 1; 789 1.1 mrg break; 790 1.1 mrg 791 1.1 mrg case ARRAY_REF: 792 1.1 mrg case COMPONENT_REF: 793 1.1 mrg case MODIFY_EXPR: 794 1.1 mrg case REALPART_EXPR: 795 1.1 mrg case IMAGPART_EXPR: 796 1.1 mrg case NOP_EXPR: 797 1.1 mrg case CONVERT_EXPR: 798 1.1 mrg case ADDR_EXPR: 799 1.1 mrg d_mark_read (TREE_OPERAND (exp, 0)); 800 1.1 mrg break; 801 1.1 mrg 802 1.1 mrg case COMPOUND_EXPR: 803 1.1 mrg d_mark_read (TREE_OPERAND (exp, 1)); 804 1.1 mrg break; 805 1.1 mrg 806 1.1 mrg default: 807 1.1 mrg break; 808 1.1 mrg } 809 1.1 mrg return exp; 810 1.1 mrg } 811 1.1 mrg 812 1.1.1.3 mrg /* Build a call to memcmp(), compares the first NUM bytes of PTR1 with PTR2. */ 813 1.1.1.3 mrg 814 1.1.1.3 mrg tree 815 1.1.1.3 mrg build_memcmp_call (tree ptr1, tree ptr2, tree num) 816 1.1.1.3 mrg { 817 1.1.1.3 mrg return build_call_expr (builtin_decl_explicit (BUILT_IN_MEMCMP), 3, 818 1.1.1.3 mrg ptr1, ptr2, num); 819 1.1.1.3 mrg } 820 1.1.1.3 mrg 821 1.1.1.3 mrg /* Build a call to memcpy(), copies the first NUM bytes of SRC into DST. */ 822 1.1.1.3 mrg 823 1.1.1.3 mrg tree 824 1.1.1.3 mrg build_memcpy_call (tree dst, tree src, tree num) 825 1.1.1.3 mrg { 826 1.1.1.3 mrg return build_call_expr (builtin_decl_explicit (BUILT_IN_MEMCPY), 3, 827 1.1.1.3 mrg dst, src, num); 828 1.1.1.3 mrg } 829 1.1.1.3 mrg 830 1.1.1.3 mrg /* Build a call to memset(), fills the first NUM bytes of PTR with zeros. 831 1.1.1.3 mrg If NUM is NULL, then we expect PTR to be object that requires filling. */ 832 1.1.1.3 mrg 833 1.1.1.3 mrg tree 834 1.1.1.3 mrg build_memset_call (tree ptr, tree num) 835 1.1.1.3 mrg { 836 1.1.1.3 mrg if (num == NULL_TREE) 837 1.1.1.3 mrg { 838 1.1.1.3 mrg gcc_assert (TREE_CODE (ptr) != ADDR_EXPR); 839 1.1.1.3 mrg num = TYPE_SIZE_UNIT (TREE_TYPE (ptr)); 840 1.1.1.3 mrg ptr = build_address (ptr); 841 1.1.1.3 mrg } 842 1.1.1.3 mrg 843 1.1.1.3 mrg /* Use a zero constant to fill the destination if setting the entire object. 844 1.1.1.3 mrg For CONSTRUCTORs, the memcpy() is lowered to a ref-all pointer assignment, 845 1.1.1.3 mrg which can then be merged with other stores to the object. */ 846 1.1.1.3 mrg tree valtype = TREE_TYPE (TREE_TYPE (ptr)); 847 1.1.1.3 mrg if (tree_int_cst_equal (TYPE_SIZE_UNIT (valtype), num)) 848 1.1.1.3 mrg { 849 1.1.1.3 mrg tree cst = build_zero_cst (valtype); 850 1.1.1.3 mrg if (TREE_CODE (cst) == CONSTRUCTOR) 851 1.1.1.3 mrg return build_memcpy_call (ptr, build_address (cst), num); 852 1.1.1.3 mrg 853 1.1.1.3 mrg return modify_expr (build_deref (ptr), cst); 854 1.1.1.3 mrg } 855 1.1.1.3 mrg 856 1.1.1.3 mrg return build_call_expr (builtin_decl_explicit (BUILT_IN_MEMSET), 3, 857 1.1.1.3 mrg ptr, integer_zero_node, num); 858 1.1.1.3 mrg } 859 1.1.1.3 mrg 860 1.1 mrg /* Return TRUE if the struct SD is suitable for comparison using memcmp. 861 1.1 mrg This is because we don't guarantee that padding is zero-initialized for 862 1.1 mrg a stack variable, so we can't use memcmp to compare struct values. */ 863 1.1 mrg 864 1.1 mrg bool 865 1.1 mrg identity_compare_p (StructDeclaration *sd) 866 1.1 mrg { 867 1.1 mrg if (sd->isUnionDeclaration ()) 868 1.1 mrg return true; 869 1.1 mrg 870 1.1 mrg unsigned offset = 0; 871 1.1 mrg 872 1.1.1.3 mrg for (size_t i = 0; i < sd->fields.length; i++) 873 1.1 mrg { 874 1.1 mrg VarDeclaration *vd = sd->fields[i]; 875 1.1 mrg Type *tb = vd->type->toBasetype (); 876 1.1 mrg 877 1.1 mrg /* Check inner data structures. */ 878 1.1.1.3 mrg if (TypeStruct *ts = tb->isTypeStruct ()) 879 1.1 mrg { 880 1.1 mrg if (!identity_compare_p (ts->sym)) 881 1.1 mrg return false; 882 1.1 mrg } 883 1.1 mrg 884 1.1 mrg /* Check for types that may have padding. */ 885 1.1.1.3 mrg if ((tb->ty == TY::Tcomplex80 886 1.1.1.3 mrg || tb->ty == TY::Tfloat80 887 1.1.1.3 mrg || tb->ty == TY::Timaginary80) 888 1.1.1.3 mrg && target.realpad != 0) 889 1.1 mrg return false; 890 1.1 mrg 891 1.1 mrg if (offset <= vd->offset) 892 1.1 mrg { 893 1.1 mrg /* There's a hole in the struct. */ 894 1.1 mrg if (offset != vd->offset) 895 1.1 mrg return false; 896 1.1 mrg 897 1.1 mrg offset += vd->type->size (); 898 1.1 mrg } 899 1.1 mrg } 900 1.1 mrg 901 1.1 mrg /* Any trailing padding may not be zero. */ 902 1.1 mrg if (offset < sd->structsize) 903 1.1 mrg return false; 904 1.1 mrg 905 1.1 mrg return true; 906 1.1 mrg } 907 1.1 mrg 908 1.1 mrg /* Build a floating-point identity comparison between T1 and T2, ignoring any 909 1.1 mrg excessive padding in the type. CODE is EQ_EXPR or NE_EXPR comparison. */ 910 1.1 mrg 911 1.1 mrg tree 912 1.1 mrg build_float_identity (tree_code code, tree t1, tree t2) 913 1.1 mrg { 914 1.1 mrg tree size = size_int (TYPE_PRECISION (TREE_TYPE (t1)) / BITS_PER_UNIT); 915 1.1.1.3 mrg tree result = build_memcmp_call (build_address (t1), 916 1.1.1.3 mrg build_address (t2), size); 917 1.1 mrg return build_boolop (code, result, integer_zero_node); 918 1.1 mrg } 919 1.1 mrg 920 1.1 mrg /* Lower a field-by-field equality expression between T1 and T2 of type SD. 921 1.1 mrg CODE is the EQ_EXPR or NE_EXPR comparison. */ 922 1.1 mrg 923 1.1 mrg static tree 924 1.1 mrg lower_struct_comparison (tree_code code, StructDeclaration *sd, 925 1.1 mrg tree t1, tree t2) 926 1.1 mrg { 927 1.1 mrg tree_code tcode = (code == EQ_EXPR) ? TRUTH_ANDIF_EXPR : TRUTH_ORIF_EXPR; 928 1.1 mrg tree tmemcmp = NULL_TREE; 929 1.1 mrg 930 1.1 mrg /* We can skip the compare if the structs are empty. */ 931 1.1.1.3 mrg if (sd->fields.length == 0) 932 1.1 mrg { 933 1.1 mrg tmemcmp = build_boolop (code, integer_zero_node, integer_zero_node); 934 1.1 mrg if (TREE_SIDE_EFFECTS (t2)) 935 1.1 mrg tmemcmp = compound_expr (t2, tmemcmp); 936 1.1 mrg if (TREE_SIDE_EFFECTS (t1)) 937 1.1 mrg tmemcmp = compound_expr (t1, tmemcmp); 938 1.1 mrg 939 1.1 mrg return tmemcmp; 940 1.1 mrg } 941 1.1 mrg 942 1.1 mrg /* Let back-end take care of union comparisons. */ 943 1.1 mrg if (sd->isUnionDeclaration ()) 944 1.1 mrg { 945 1.1.1.3 mrg tmemcmp = build_memcmp_call (build_address (t1), build_address (t2), 946 1.1.1.3 mrg size_int (sd->structsize)); 947 1.1 mrg return build_boolop (code, tmemcmp, integer_zero_node); 948 1.1 mrg } 949 1.1 mrg 950 1.1.1.3 mrg for (size_t i = 0; i < sd->fields.length; i++) 951 1.1 mrg { 952 1.1 mrg VarDeclaration *vd = sd->fields[i]; 953 1.1 mrg Type *type = vd->type->toBasetype (); 954 1.1 mrg tree sfield = get_symbol_decl (vd); 955 1.1 mrg 956 1.1 mrg tree t1ref = component_ref (t1, sfield); 957 1.1 mrg tree t2ref = component_ref (t2, sfield); 958 1.1 mrg tree tcmp; 959 1.1 mrg 960 1.1.1.3 mrg if (TypeStruct *ts = type->isTypeStruct ()) 961 1.1 mrg { 962 1.1 mrg /* Compare inner data structures. */ 963 1.1.1.3 mrg tcmp = lower_struct_comparison (code, ts->sym, t1ref, t2ref); 964 1.1 mrg } 965 1.1.1.3 mrg else if (type->ty != TY::Tvector && type->isintegral ()) 966 1.1 mrg { 967 1.1 mrg /* Integer comparison, no special handling required. */ 968 1.1 mrg tcmp = build_boolop (code, t1ref, t2ref); 969 1.1 mrg } 970 1.1.1.3 mrg else if (type->ty != TY::Tvector && type->isfloating ()) 971 1.1 mrg { 972 1.1 mrg /* Floating-point comparison, don't compare padding in type. */ 973 1.1 mrg if (!type->iscomplex ()) 974 1.1 mrg tcmp = build_float_identity (code, t1ref, t2ref); 975 1.1 mrg else 976 1.1 mrg { 977 1.1 mrg tree req = build_float_identity (code, real_part (t1ref), 978 1.1 mrg real_part (t2ref)); 979 1.1 mrg tree ieq = build_float_identity (code, imaginary_part (t1ref), 980 1.1 mrg imaginary_part (t2ref)); 981 1.1 mrg 982 1.1 mrg tcmp = build_boolop (tcode, req, ieq); 983 1.1 mrg } 984 1.1 mrg } 985 1.1 mrg else 986 1.1 mrg { 987 1.1 mrg tree stype = build_ctype (type); 988 1.1 mrg opt_scalar_int_mode mode = int_mode_for_mode (TYPE_MODE (stype)); 989 1.1 mrg 990 1.1 mrg if (mode.exists ()) 991 1.1 mrg { 992 1.1 mrg /* Compare field bits as their corresponding integer type. 993 1.1 mrg *((T*) &t1) == *((T*) &t2) */ 994 1.1 mrg tree tmode = lang_hooks.types.type_for_mode (mode.require (), 1); 995 1.1 mrg 996 1.1 mrg if (tmode == NULL_TREE) 997 1.1 mrg tmode = make_unsigned_type (GET_MODE_BITSIZE (mode.require ())); 998 1.1 mrg 999 1.1.1.3 mrg tmode = build_aligned_type (tmode, TYPE_ALIGN (stype)); 1000 1.1 mrg t1ref = build_vconvert (tmode, t1ref); 1001 1.1 mrg t2ref = build_vconvert (tmode, t2ref); 1002 1.1 mrg 1003 1.1 mrg tcmp = build_boolop (code, t1ref, t2ref); 1004 1.1 mrg } 1005 1.1 mrg else 1006 1.1 mrg { 1007 1.1 mrg /* Simple memcmp between types. */ 1008 1.1.1.3 mrg tcmp = build_memcmp_call (build_address (t1ref), 1009 1.1.1.3 mrg build_address (t2ref), 1010 1.1.1.3 mrg TYPE_SIZE_UNIT (stype)); 1011 1.1 mrg tcmp = build_boolop (code, tcmp, integer_zero_node); 1012 1.1 mrg } 1013 1.1 mrg } 1014 1.1 mrg 1015 1.1 mrg tmemcmp = (tmemcmp) ? build_boolop (tcode, tmemcmp, tcmp) : tcmp; 1016 1.1 mrg } 1017 1.1 mrg 1018 1.1 mrg return tmemcmp; 1019 1.1 mrg } 1020 1.1 mrg 1021 1.1 mrg 1022 1.1 mrg /* Build an equality expression between two RECORD_TYPES T1 and T2 of type SD. 1023 1.1 mrg If possible, use memcmp, otherwise field-by-field comparison is done. 1024 1.1 mrg CODE is the EQ_EXPR or NE_EXPR comparison. */ 1025 1.1 mrg 1026 1.1 mrg tree 1027 1.1 mrg build_struct_comparison (tree_code code, StructDeclaration *sd, 1028 1.1 mrg tree t1, tree t2) 1029 1.1 mrg { 1030 1.1 mrg /* We can skip the compare if the structs are empty. */ 1031 1.1.1.3 mrg if (sd->fields.length == 0) 1032 1.1 mrg { 1033 1.1 mrg tree exp = build_boolop (code, integer_zero_node, integer_zero_node); 1034 1.1 mrg if (TREE_SIDE_EFFECTS (t2)) 1035 1.1 mrg exp = compound_expr (t2, exp); 1036 1.1 mrg if (TREE_SIDE_EFFECTS (t1)) 1037 1.1 mrg exp = compound_expr (t1, exp); 1038 1.1 mrg 1039 1.1 mrg return exp; 1040 1.1 mrg } 1041 1.1 mrg 1042 1.1 mrg /* Make temporaries to prevent multiple evaluations. */ 1043 1.1 mrg tree t1init = stabilize_expr (&t1); 1044 1.1 mrg tree t2init = stabilize_expr (&t2); 1045 1.1 mrg tree result; 1046 1.1 mrg 1047 1.1 mrg t1 = d_save_expr (t1); 1048 1.1 mrg t2 = d_save_expr (t2); 1049 1.1 mrg 1050 1.1 mrg /* Bitwise comparison of structs not returned in memory may not work 1051 1.1 mrg due to data holes loosing its zero padding upon return. 1052 1.1 mrg As a heuristic, small structs are not compared using memcmp either. */ 1053 1.1 mrg if (TYPE_MODE (TREE_TYPE (t1)) != BLKmode || !identity_compare_p (sd)) 1054 1.1 mrg result = lower_struct_comparison (code, sd, t1, t2); 1055 1.1 mrg else 1056 1.1 mrg { 1057 1.1 mrg /* Do bit compare of structs. */ 1058 1.1.1.3 mrg tree tmemcmp = build_memcmp_call (build_address (t1), build_address (t2), 1059 1.1.1.3 mrg size_int (sd->structsize)); 1060 1.1 mrg result = build_boolop (code, tmemcmp, integer_zero_node); 1061 1.1 mrg } 1062 1.1 mrg 1063 1.1 mrg return compound_expr (compound_expr (t1init, t2init), result); 1064 1.1 mrg } 1065 1.1 mrg 1066 1.1 mrg /* Build an equality expression between two ARRAY_TYPES of size LENGTH. 1067 1.1 mrg The pointer references are T1 and T2, and the element type is SD. 1068 1.1 mrg CODE is the EQ_EXPR or NE_EXPR comparison. */ 1069 1.1 mrg 1070 1.1 mrg tree 1071 1.1 mrg build_array_struct_comparison (tree_code code, StructDeclaration *sd, 1072 1.1 mrg tree length, tree t1, tree t2) 1073 1.1 mrg { 1074 1.1 mrg tree_code tcode = (code == EQ_EXPR) ? TRUTH_ANDIF_EXPR : TRUTH_ORIF_EXPR; 1075 1.1 mrg 1076 1.1 mrg /* Build temporary for the result of the comparison. 1077 1.1 mrg Initialize as either 0 or 1 depending on operation. */ 1078 1.1 mrg tree result = build_local_temp (d_bool_type); 1079 1.1 mrg tree init = build_boolop (code, integer_zero_node, integer_zero_node); 1080 1.1 mrg add_stmt (build_assign (INIT_EXPR, result, init)); 1081 1.1 mrg 1082 1.1 mrg /* Cast pointer-to-array to pointer-to-struct. */ 1083 1.1 mrg tree ptrtype = build_ctype (sd->type->pointerTo ()); 1084 1.1 mrg tree lentype = TREE_TYPE (length); 1085 1.1 mrg 1086 1.1 mrg push_binding_level (level_block); 1087 1.1 mrg push_stmt_list (); 1088 1.1 mrg 1089 1.1 mrg /* Build temporary locals for length and pointers. */ 1090 1.1 mrg tree t = build_local_temp (size_type_node); 1091 1.1 mrg add_stmt (build_assign (INIT_EXPR, t, length)); 1092 1.1 mrg length = t; 1093 1.1 mrg 1094 1.1 mrg t = build_local_temp (ptrtype); 1095 1.1 mrg add_stmt (build_assign (INIT_EXPR, t, d_convert (ptrtype, t1))); 1096 1.1 mrg t1 = t; 1097 1.1 mrg 1098 1.1 mrg t = build_local_temp (ptrtype); 1099 1.1 mrg add_stmt (build_assign (INIT_EXPR, t, d_convert (ptrtype, t2))); 1100 1.1 mrg t2 = t; 1101 1.1 mrg 1102 1.1 mrg /* Build loop for comparing each element. */ 1103 1.1 mrg push_stmt_list (); 1104 1.1 mrg 1105 1.1 mrg /* Exit logic for the loop. 1106 1.1 mrg if (length == 0 || result OP 0) break; */ 1107 1.1 mrg t = build_boolop (EQ_EXPR, length, d_convert (lentype, integer_zero_node)); 1108 1.1 mrg t = build_boolop (TRUTH_ORIF_EXPR, t, build_boolop (code, result, 1109 1.1.1.3 mrg d_bool_false_node)); 1110 1.1 mrg t = build1 (EXIT_EXPR, void_type_node, t); 1111 1.1 mrg add_stmt (t); 1112 1.1 mrg 1113 1.1 mrg /* Do comparison, caching the value. 1114 1.1 mrg result = result OP (*t1 == *t2); */ 1115 1.1 mrg t = build_struct_comparison (code, sd, build_deref (t1), build_deref (t2)); 1116 1.1 mrg t = build_boolop (tcode, result, t); 1117 1.1 mrg t = modify_expr (result, t); 1118 1.1 mrg add_stmt (t); 1119 1.1 mrg 1120 1.1 mrg /* Move both pointers to next element position. 1121 1.1 mrg t1++, t2++; */ 1122 1.1 mrg tree size = d_convert (ptrtype, TYPE_SIZE_UNIT (TREE_TYPE (ptrtype))); 1123 1.1 mrg t = build2 (POSTINCREMENT_EXPR, ptrtype, t1, size); 1124 1.1 mrg add_stmt (t); 1125 1.1 mrg t = build2 (POSTINCREMENT_EXPR, ptrtype, t2, size); 1126 1.1 mrg add_stmt (t); 1127 1.1 mrg 1128 1.1 mrg /* Decrease loop counter. 1129 1.1 mrg length -= 1; */ 1130 1.1 mrg t = build2 (POSTDECREMENT_EXPR, lentype, length, 1131 1.1 mrg d_convert (lentype, integer_one_node)); 1132 1.1 mrg add_stmt (t); 1133 1.1 mrg 1134 1.1 mrg /* Pop statements and finish loop. */ 1135 1.1 mrg tree body = pop_stmt_list (); 1136 1.1 mrg add_stmt (build1 (LOOP_EXPR, void_type_node, body)); 1137 1.1 mrg 1138 1.1 mrg /* Wrap it up into a bind expression. */ 1139 1.1 mrg tree stmt_list = pop_stmt_list (); 1140 1.1 mrg tree block = pop_binding_level (); 1141 1.1 mrg 1142 1.1 mrg body = build3 (BIND_EXPR, void_type_node, 1143 1.1 mrg BLOCK_VARS (block), stmt_list, block); 1144 1.1 mrg 1145 1.1 mrg return compound_expr (body, result); 1146 1.1 mrg } 1147 1.1 mrg 1148 1.1 mrg /* Build a constructor for a variable of aggregate type TYPE using the 1149 1.1 mrg initializer INIT, an ordered flat list of fields and values provided 1150 1.1 mrg by the frontend. The returned constructor should be a value that 1151 1.1 mrg matches the layout of TYPE. */ 1152 1.1 mrg 1153 1.1 mrg tree 1154 1.1.1.3 mrg build_struct_literal (tree type, vec <constructor_elt, va_gc> *init) 1155 1.1 mrg { 1156 1.1 mrg /* If the initializer was empty, use default zero initialization. */ 1157 1.1 mrg if (vec_safe_is_empty (init)) 1158 1.1 mrg return build_constructor (type, NULL); 1159 1.1 mrg 1160 1.1.1.3 mrg /* Struct literals can be seen for special enums representing `_Complex', 1161 1.1.1.3 mrg make sure to reinterpret the literal as the correct type. */ 1162 1.1.1.3 mrg if (COMPLEX_FLOAT_TYPE_P (type)) 1163 1.1.1.3 mrg { 1164 1.1.1.3 mrg gcc_assert (vec_safe_length (init) == 2); 1165 1.1.1.3 mrg return complex_expr (type, (*init)[0].value, (*init)[1].value); 1166 1.1.1.3 mrg } 1167 1.1.1.3 mrg 1168 1.1.1.3 mrg vec <constructor_elt, va_gc> *ve = NULL; 1169 1.1.1.3 mrg HOST_WIDE_INT bitoffset = 0; 1170 1.1 mrg bool constant_p = true; 1171 1.1 mrg bool finished = false; 1172 1.1 mrg 1173 1.1 mrg /* Walk through each field, matching our initializer list. */ 1174 1.1 mrg for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field)) 1175 1.1 mrg { 1176 1.1 mrg bool is_initialized = false; 1177 1.1 mrg tree value; 1178 1.1 mrg 1179 1.1 mrg if (DECL_NAME (field) == NULL_TREE 1180 1.1 mrg && RECORD_OR_UNION_TYPE_P (TREE_TYPE (field)) 1181 1.1 mrg && ANON_AGGR_TYPE_P (TREE_TYPE (field))) 1182 1.1 mrg { 1183 1.1 mrg /* Search all nesting aggregates, if nothing is found, then 1184 1.1 mrg this will return an empty initializer to fill the hole. */ 1185 1.1 mrg value = build_struct_literal (TREE_TYPE (field), init); 1186 1.1 mrg 1187 1.1 mrg if (!initializer_zerop (value)) 1188 1.1 mrg is_initialized = true; 1189 1.1 mrg } 1190 1.1 mrg else 1191 1.1 mrg { 1192 1.1 mrg /* Search for the value to initialize the next field. Once found, 1193 1.1 mrg pop it from the init list so we don't look at it again. */ 1194 1.1 mrg unsigned HOST_WIDE_INT idx; 1195 1.1 mrg tree index; 1196 1.1 mrg 1197 1.1 mrg FOR_EACH_CONSTRUCTOR_ELT (init, idx, index, value) 1198 1.1 mrg { 1199 1.1 mrg /* If the index is NULL, then just assign it to the next field. 1200 1.1 mrg This comes from layout_typeinfo(), which generates a flat 1201 1.1 mrg list of values that we must shape into the record type. */ 1202 1.1 mrg if (index == field || index == NULL_TREE) 1203 1.1 mrg { 1204 1.1 mrg init->ordered_remove (idx); 1205 1.1 mrg if (!finished) 1206 1.1 mrg is_initialized = true; 1207 1.1 mrg break; 1208 1.1 mrg } 1209 1.1 mrg } 1210 1.1 mrg } 1211 1.1 mrg 1212 1.1 mrg if (is_initialized) 1213 1.1 mrg { 1214 1.1.1.3 mrg HOST_WIDE_INT fieldpos = int_bit_position (field); 1215 1.1 mrg gcc_assert (value != NULL_TREE); 1216 1.1 mrg 1217 1.1 mrg /* Must not initialize fields that overlap. */ 1218 1.1.1.3 mrg if (fieldpos < bitoffset) 1219 1.1 mrg { 1220 1.1 mrg /* Find the nearest user defined type and field. */ 1221 1.1 mrg tree vtype = type; 1222 1.1 mrg while (ANON_AGGR_TYPE_P (vtype)) 1223 1.1 mrg vtype = TYPE_CONTEXT (vtype); 1224 1.1 mrg 1225 1.1 mrg tree vfield = field; 1226 1.1 mrg if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (vfield)) 1227 1.1 mrg && ANON_AGGR_TYPE_P (TREE_TYPE (vfield))) 1228 1.1 mrg vfield = TYPE_FIELDS (TREE_TYPE (vfield)); 1229 1.1 mrg 1230 1.1 mrg /* Must not generate errors for compiler generated fields. */ 1231 1.1 mrg gcc_assert (TYPE_NAME (vtype) && DECL_NAME (vfield)); 1232 1.1 mrg error ("overlapping initializer for field %qT.%qD", 1233 1.1 mrg TYPE_NAME (vtype), DECL_NAME (vfield)); 1234 1.1 mrg } 1235 1.1 mrg 1236 1.1 mrg if (!TREE_CONSTANT (value)) 1237 1.1 mrg constant_p = false; 1238 1.1 mrg 1239 1.1 mrg CONSTRUCTOR_APPEND_ELT (ve, field, value); 1240 1.1 mrg 1241 1.1 mrg /* For unions, only the first field is initialized, any other field 1242 1.1 mrg initializers found for this union are drained and ignored. */ 1243 1.1 mrg if (TREE_CODE (type) == UNION_TYPE) 1244 1.1 mrg finished = true; 1245 1.1 mrg } 1246 1.1 mrg 1247 1.1.1.3 mrg /* Move bit offset to the next position in the struct. */ 1248 1.1.1.3 mrg if (TREE_CODE (type) == RECORD_TYPE && DECL_SIZE (field)) 1249 1.1.1.3 mrg bitoffset = int_bit_position (field) + tree_to_shwi (DECL_SIZE (field)); 1250 1.1 mrg 1251 1.1 mrg /* If all initializers have been assigned, there's nothing else to do. */ 1252 1.1 mrg if (vec_safe_is_empty (init)) 1253 1.1 mrg break; 1254 1.1 mrg } 1255 1.1 mrg 1256 1.1 mrg /* Ensure that we have consumed all values. */ 1257 1.1 mrg gcc_assert (vec_safe_is_empty (init) || ANON_AGGR_TYPE_P (type)); 1258 1.1 mrg 1259 1.1 mrg tree ctor = build_constructor (type, ve); 1260 1.1 mrg 1261 1.1 mrg if (constant_p) 1262 1.1 mrg TREE_CONSTANT (ctor) = 1; 1263 1.1 mrg 1264 1.1 mrg return ctor; 1265 1.1 mrg } 1266 1.1 mrg 1267 1.1 mrg /* Given the TYPE of an anonymous field inside T, return the 1268 1.1 mrg FIELD_DECL for the field. If not found return NULL_TREE. 1269 1.1 mrg Because anonymous types can nest, we must also search all 1270 1.1 mrg anonymous fields that are directly reachable. */ 1271 1.1 mrg 1272 1.1 mrg static tree 1273 1.1 mrg lookup_anon_field (tree t, tree type) 1274 1.1 mrg { 1275 1.1 mrg t = TYPE_MAIN_VARIANT (t); 1276 1.1 mrg 1277 1.1 mrg for (tree field = TYPE_FIELDS (t); field; field = DECL_CHAIN (field)) 1278 1.1 mrg { 1279 1.1 mrg if (DECL_NAME (field) == NULL_TREE) 1280 1.1 mrg { 1281 1.1 mrg /* If we find it directly, return the field. */ 1282 1.1 mrg if (type == TYPE_MAIN_VARIANT (TREE_TYPE (field))) 1283 1.1 mrg return field; 1284 1.1 mrg 1285 1.1 mrg /* Otherwise, it could be nested, search harder. */ 1286 1.1 mrg if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (field)) 1287 1.1 mrg && ANON_AGGR_TYPE_P (TREE_TYPE (field))) 1288 1.1 mrg { 1289 1.1 mrg tree subfield = lookup_anon_field (TREE_TYPE (field), type); 1290 1.1 mrg if (subfield) 1291 1.1 mrg return subfield; 1292 1.1 mrg } 1293 1.1 mrg } 1294 1.1 mrg } 1295 1.1 mrg 1296 1.1 mrg return NULL_TREE; 1297 1.1 mrg } 1298 1.1 mrg 1299 1.1 mrg /* Builds OBJECT.FIELD component reference. */ 1300 1.1 mrg 1301 1.1 mrg tree 1302 1.1 mrg component_ref (tree object, tree field) 1303 1.1 mrg { 1304 1.1 mrg if (error_operand_p (object) || error_operand_p (field)) 1305 1.1 mrg return error_mark_node; 1306 1.1 mrg 1307 1.1 mrg gcc_assert (TREE_CODE (field) == FIELD_DECL); 1308 1.1 mrg 1309 1.1 mrg /* Maybe rewrite: (e1, e2).field => (e1, e2.field) */ 1310 1.1 mrg tree init = stabilize_expr (&object); 1311 1.1 mrg 1312 1.1 mrg /* If the FIELD is from an anonymous aggregate, generate a reference 1313 1.1 mrg to the anonymous data member, and recur to find FIELD. */ 1314 1.1 mrg if (ANON_AGGR_TYPE_P (DECL_CONTEXT (field))) 1315 1.1 mrg { 1316 1.1 mrg tree anonymous_field = lookup_anon_field (TREE_TYPE (object), 1317 1.1 mrg DECL_CONTEXT (field)); 1318 1.1 mrg object = component_ref (object, anonymous_field); 1319 1.1 mrg } 1320 1.1 mrg 1321 1.1 mrg tree result = fold_build3_loc (input_location, COMPONENT_REF, 1322 1.1 mrg TREE_TYPE (field), object, field, NULL_TREE); 1323 1.1 mrg 1324 1.1 mrg return compound_expr (init, result); 1325 1.1 mrg } 1326 1.1 mrg 1327 1.1 mrg /* Build an assignment expression of lvalue LHS from value RHS. 1328 1.1 mrg CODE is the code for a binary operator that we use to combine 1329 1.1 mrg the old value of LHS with RHS to get the new value. */ 1330 1.1 mrg 1331 1.1 mrg tree 1332 1.1 mrg build_assign (tree_code code, tree lhs, tree rhs) 1333 1.1 mrg { 1334 1.1.1.2 mrg tree result; 1335 1.1 mrg tree init = stabilize_expr (&lhs); 1336 1.1 mrg init = compound_expr (init, stabilize_expr (&rhs)); 1337 1.1 mrg 1338 1.1 mrg /* If initializing the LHS using a function that returns via NRVO. */ 1339 1.1 mrg if (code == INIT_EXPR && TREE_CODE (rhs) == CALL_EXPR 1340 1.1 mrg && AGGREGATE_TYPE_P (TREE_TYPE (rhs)) 1341 1.1 mrg && aggregate_value_p (TREE_TYPE (rhs), rhs)) 1342 1.1 mrg { 1343 1.1 mrg /* Mark as addressable here, which should ensure the return slot is the 1344 1.1 mrg address of the LHS expression, taken care of by back-end. */ 1345 1.1 mrg d_mark_addressable (lhs); 1346 1.1 mrg CALL_EXPR_RETURN_SLOT_OPT (rhs) = true; 1347 1.1 mrg } 1348 1.1.1.3 mrg /* If modifying an LHS whose type is marked TREE_ADDRESSABLE. */ 1349 1.1.1.3 mrg else if (code == MODIFY_EXPR && TREE_ADDRESSABLE (TREE_TYPE (lhs)) 1350 1.1.1.3 mrg && TREE_SIDE_EFFECTS (rhs) && TREE_CODE (rhs) != TARGET_EXPR) 1351 1.1.1.3 mrg { 1352 1.1.1.3 mrg /* LHS may be referenced by the RHS expression, so force a temporary. */ 1353 1.1.1.3 mrg rhs = force_target_expr (rhs); 1354 1.1.1.3 mrg } 1355 1.1 mrg 1356 1.1 mrg /* The LHS assignment replaces the temporary in TARGET_EXPR_SLOT. */ 1357 1.1 mrg if (TREE_CODE (rhs) == TARGET_EXPR) 1358 1.1 mrg { 1359 1.1 mrg /* If CODE is not INIT_EXPR, can't initialize LHS directly, 1360 1.1.1.2 mrg since that would cause the LHS to be constructed twice. */ 1361 1.1 mrg if (code != INIT_EXPR) 1362 1.1.1.2 mrg { 1363 1.1.1.2 mrg init = compound_expr (init, rhs); 1364 1.1.1.2 mrg result = build_assign (code, lhs, TARGET_EXPR_SLOT (rhs)); 1365 1.1.1.2 mrg } 1366 1.1 mrg else 1367 1.1 mrg { 1368 1.1 mrg d_mark_addressable (lhs); 1369 1.1.1.2 mrg TARGET_EXPR_INITIAL (rhs) = build_assign (code, lhs, 1370 1.1.1.2 mrg TARGET_EXPR_INITIAL (rhs)); 1371 1.1.1.2 mrg result = rhs; 1372 1.1 mrg } 1373 1.1 mrg } 1374 1.1.1.2 mrg else 1375 1.1.1.2 mrg { 1376 1.1.1.2 mrg /* Simple assignment. */ 1377 1.1.1.2 mrg result = fold_build2_loc (input_location, code, 1378 1.1.1.2 mrg TREE_TYPE (lhs), lhs, rhs); 1379 1.1.1.2 mrg } 1380 1.1 mrg 1381 1.1 mrg return compound_expr (init, result); 1382 1.1 mrg } 1383 1.1 mrg 1384 1.1 mrg /* Build an assignment expression of lvalue LHS from value RHS. */ 1385 1.1 mrg 1386 1.1 mrg tree 1387 1.1 mrg modify_expr (tree lhs, tree rhs) 1388 1.1 mrg { 1389 1.1 mrg return build_assign (MODIFY_EXPR, lhs, rhs); 1390 1.1 mrg } 1391 1.1 mrg 1392 1.1 mrg /* Return EXP represented as TYPE. */ 1393 1.1 mrg 1394 1.1 mrg tree 1395 1.1 mrg build_nop (tree type, tree exp) 1396 1.1 mrg { 1397 1.1 mrg if (error_operand_p (exp)) 1398 1.1 mrg return exp; 1399 1.1 mrg 1400 1.1 mrg /* Maybe rewrite: cast(TYPE)(e1, e2) => (e1, cast(TYPE) e2) */ 1401 1.1 mrg tree init = stabilize_expr (&exp); 1402 1.1 mrg exp = fold_build1_loc (input_location, NOP_EXPR, type, exp); 1403 1.1 mrg 1404 1.1 mrg return compound_expr (init, exp); 1405 1.1 mrg } 1406 1.1 mrg 1407 1.1 mrg /* Return EXP to be viewed as being another type TYPE. Same as build_nop, 1408 1.1 mrg except that EXP is type-punned, rather than a straight-forward cast. */ 1409 1.1 mrg 1410 1.1 mrg tree 1411 1.1 mrg build_vconvert (tree type, tree exp) 1412 1.1 mrg { 1413 1.1 mrg /* Building *(cast(TYPE *)&e1) directly rather then using VIEW_CONVERT_EXPR 1414 1.1 mrg makes sure this works for vector-to-array viewing, or if EXP ends up being 1415 1.1 mrg used as the LHS of a MODIFY_EXPR. */ 1416 1.1 mrg return indirect_ref (type, build_address (exp)); 1417 1.1 mrg } 1418 1.1 mrg 1419 1.1 mrg /* Maybe warn about ARG being an address that can never be null. */ 1420 1.1 mrg 1421 1.1 mrg static void 1422 1.1 mrg warn_for_null_address (tree arg) 1423 1.1 mrg { 1424 1.1 mrg if (TREE_CODE (arg) == ADDR_EXPR 1425 1.1 mrg && decl_with_nonnull_addr_p (TREE_OPERAND (arg, 0))) 1426 1.1 mrg warning (OPT_Waddress, 1427 1.1 mrg "the address of %qD will never be %<null%>", 1428 1.1 mrg TREE_OPERAND (arg, 0)); 1429 1.1 mrg } 1430 1.1 mrg 1431 1.1 mrg /* Build a boolean ARG0 op ARG1 expression. */ 1432 1.1 mrg 1433 1.1 mrg tree 1434 1.1 mrg build_boolop (tree_code code, tree arg0, tree arg1) 1435 1.1 mrg { 1436 1.1 mrg /* Aggregate comparisons may get lowered to a call to builtin memcmp, 1437 1.1 mrg so need to remove all side effects incase its address is taken. */ 1438 1.1 mrg if (AGGREGATE_TYPE_P (TREE_TYPE (arg0))) 1439 1.1 mrg arg0 = d_save_expr (arg0); 1440 1.1 mrg if (AGGREGATE_TYPE_P (TREE_TYPE (arg1))) 1441 1.1 mrg arg1 = d_save_expr (arg1); 1442 1.1 mrg 1443 1.1 mrg if (VECTOR_TYPE_P (TREE_TYPE (arg0)) && VECTOR_TYPE_P (TREE_TYPE (arg1))) 1444 1.1 mrg { 1445 1.1 mrg /* Build a vector comparison. 1446 1.1 mrg VEC_COND_EXPR <e1 op e2, { -1, -1, -1, -1 }, { 0, 0, 0, 0 }>; */ 1447 1.1 mrg tree type = TREE_TYPE (arg0); 1448 1.1.1.2 mrg tree cmptype = truth_type_for (type); 1449 1.1 mrg tree cmp = fold_build2_loc (input_location, code, cmptype, arg0, arg1); 1450 1.1 mrg 1451 1.1 mrg return fold_build3_loc (input_location, VEC_COND_EXPR, type, cmp, 1452 1.1 mrg build_minus_one_cst (type), 1453 1.1 mrg build_zero_cst (type)); 1454 1.1 mrg } 1455 1.1 mrg 1456 1.1 mrg if (code == EQ_EXPR || code == NE_EXPR) 1457 1.1 mrg { 1458 1.1 mrg /* Check if comparing the address of a variable to null. */ 1459 1.1 mrg if (POINTER_TYPE_P (TREE_TYPE (arg0)) && integer_zerop (arg1)) 1460 1.1 mrg warn_for_null_address (arg0); 1461 1.1 mrg if (POINTER_TYPE_P (TREE_TYPE (arg1)) && integer_zerop (arg0)) 1462 1.1 mrg warn_for_null_address (arg1); 1463 1.1 mrg } 1464 1.1 mrg 1465 1.1 mrg return fold_build2_loc (input_location, code, d_bool_type, 1466 1.1 mrg arg0, d_convert (TREE_TYPE (arg0), arg1)); 1467 1.1 mrg } 1468 1.1 mrg 1469 1.1 mrg /* Return a COND_EXPR. ARG0, ARG1, and ARG2 are the three 1470 1.1 mrg arguments to the conditional expression. */ 1471 1.1 mrg 1472 1.1 mrg tree 1473 1.1 mrg build_condition (tree type, tree arg0, tree arg1, tree arg2) 1474 1.1 mrg { 1475 1.1 mrg if (arg1 == void_node) 1476 1.1 mrg arg1 = build_empty_stmt (input_location); 1477 1.1 mrg 1478 1.1 mrg if (arg2 == void_node) 1479 1.1 mrg arg2 = build_empty_stmt (input_location); 1480 1.1 mrg 1481 1.1 mrg return fold_build3_loc (input_location, COND_EXPR, 1482 1.1 mrg type, arg0, arg1, arg2); 1483 1.1 mrg } 1484 1.1 mrg 1485 1.1 mrg tree 1486 1.1 mrg build_vcondition (tree arg0, tree arg1, tree arg2) 1487 1.1 mrg { 1488 1.1 mrg return build_condition (void_type_node, arg0, arg1, arg2); 1489 1.1 mrg } 1490 1.1 mrg 1491 1.1 mrg /* Build a compound expr to join ARG0 and ARG1 together. */ 1492 1.1 mrg 1493 1.1 mrg tree 1494 1.1 mrg compound_expr (tree arg0, tree arg1) 1495 1.1 mrg { 1496 1.1 mrg if (arg1 == NULL_TREE) 1497 1.1 mrg return arg0; 1498 1.1 mrg 1499 1.1 mrg if (arg0 == NULL_TREE || !TREE_SIDE_EFFECTS (arg0)) 1500 1.1 mrg return arg1; 1501 1.1 mrg 1502 1.1.1.2 mrg /* Remove intermediate expressions that have no side-effects. */ 1503 1.1.1.2 mrg while (TREE_CODE (arg0) == COMPOUND_EXPR 1504 1.1.1.2 mrg && !TREE_SIDE_EFFECTS (TREE_OPERAND (arg0, 1))) 1505 1.1.1.2 mrg arg0 = TREE_OPERAND (arg0, 0); 1506 1.1.1.2 mrg 1507 1.1 mrg if (TREE_CODE (arg1) == TARGET_EXPR) 1508 1.1 mrg { 1509 1.1 mrg /* If the rhs is a TARGET_EXPR, then build the compound expression 1510 1.1 mrg inside the target_expr's initializer. This helps the compiler 1511 1.1 mrg to eliminate unnecessary temporaries. */ 1512 1.1 mrg tree init = compound_expr (arg0, TARGET_EXPR_INITIAL (arg1)); 1513 1.1 mrg TARGET_EXPR_INITIAL (arg1) = init; 1514 1.1 mrg 1515 1.1 mrg return arg1; 1516 1.1 mrg } 1517 1.1 mrg 1518 1.1 mrg return fold_build2_loc (input_location, COMPOUND_EXPR, 1519 1.1 mrg TREE_TYPE (arg1), arg0, arg1); 1520 1.1 mrg } 1521 1.1 mrg 1522 1.1 mrg /* Build a return expression. */ 1523 1.1 mrg 1524 1.1 mrg tree 1525 1.1 mrg return_expr (tree ret) 1526 1.1 mrg { 1527 1.1.1.2 mrg /* Same as build_assign, the DECL_RESULT assignment replaces the temporary 1528 1.1.1.2 mrg in TARGET_EXPR_SLOT. */ 1529 1.1.1.2 mrg if (ret != NULL_TREE && TREE_CODE (ret) == TARGET_EXPR) 1530 1.1.1.2 mrg { 1531 1.1.1.2 mrg tree exp = TARGET_EXPR_INITIAL (ret); 1532 1.1.1.2 mrg tree init = stabilize_expr (&exp); 1533 1.1.1.2 mrg 1534 1.1.1.2 mrg exp = fold_build1_loc (input_location, RETURN_EXPR, void_type_node, exp); 1535 1.1.1.2 mrg TARGET_EXPR_INITIAL (ret) = compound_expr (init, exp); 1536 1.1.1.2 mrg 1537 1.1.1.2 mrg return ret; 1538 1.1.1.2 mrg } 1539 1.1.1.2 mrg 1540 1.1 mrg return fold_build1_loc (input_location, RETURN_EXPR, 1541 1.1 mrg void_type_node, ret); 1542 1.1 mrg } 1543 1.1 mrg 1544 1.1 mrg /* Return the product of ARG0 and ARG1 as a size_type_node. */ 1545 1.1 mrg 1546 1.1 mrg tree 1547 1.1 mrg size_mult_expr (tree arg0, tree arg1) 1548 1.1 mrg { 1549 1.1 mrg return fold_build2_loc (input_location, MULT_EXPR, size_type_node, 1550 1.1 mrg d_convert (size_type_node, arg0), 1551 1.1 mrg d_convert (size_type_node, arg1)); 1552 1.1 mrg 1553 1.1 mrg } 1554 1.1 mrg 1555 1.1 mrg /* Return the real part of CE, which should be a complex expression. */ 1556 1.1 mrg 1557 1.1 mrg tree 1558 1.1 mrg real_part (tree ce) 1559 1.1 mrg { 1560 1.1 mrg return fold_build1_loc (input_location, REALPART_EXPR, 1561 1.1 mrg TREE_TYPE (TREE_TYPE (ce)), ce); 1562 1.1 mrg } 1563 1.1 mrg 1564 1.1 mrg /* Return the imaginary part of CE, which should be a complex expression. */ 1565 1.1 mrg 1566 1.1 mrg tree 1567 1.1 mrg imaginary_part (tree ce) 1568 1.1 mrg { 1569 1.1 mrg return fold_build1_loc (input_location, IMAGPART_EXPR, 1570 1.1 mrg TREE_TYPE (TREE_TYPE (ce)), ce); 1571 1.1 mrg } 1572 1.1 mrg 1573 1.1 mrg /* Build a complex expression of type TYPE using RE and IM. */ 1574 1.1 mrg 1575 1.1 mrg tree 1576 1.1 mrg complex_expr (tree type, tree re, tree im) 1577 1.1 mrg { 1578 1.1 mrg return fold_build2_loc (input_location, COMPLEX_EXPR, 1579 1.1 mrg type, re, im); 1580 1.1 mrg } 1581 1.1 mrg 1582 1.1.1.3 mrg /* Build a two-field record TYPE representing the complex expression EXPR. */ 1583 1.1.1.3 mrg 1584 1.1.1.3 mrg tree 1585 1.1.1.3 mrg underlying_complex_expr (tree type, tree expr) 1586 1.1.1.3 mrg { 1587 1.1.1.3 mrg gcc_assert (list_length (TYPE_FIELDS (type)) == 2); 1588 1.1.1.3 mrg 1589 1.1.1.3 mrg expr = d_save_expr (expr); 1590 1.1.1.3 mrg 1591 1.1.1.3 mrg /* Build a constructor from the real and imaginary parts. */ 1592 1.1.1.3 mrg if (COMPLEX_FLOAT_TYPE_P (TREE_TYPE (expr)) && 1593 1.1.1.3 mrg (!INDIRECT_REF_P (expr) 1594 1.1.1.3 mrg || !CONVERT_EXPR_CODE_P (TREE_CODE (TREE_OPERAND (expr, 0))))) 1595 1.1.1.3 mrg { 1596 1.1.1.3 mrg vec <constructor_elt, va_gc> *ve = NULL; 1597 1.1.1.3 mrg CONSTRUCTOR_APPEND_ELT (ve, TYPE_FIELDS (type), 1598 1.1.1.3 mrg real_part (expr)); 1599 1.1.1.3 mrg CONSTRUCTOR_APPEND_ELT (ve, TREE_CHAIN (TYPE_FIELDS (type)), 1600 1.1.1.3 mrg imaginary_part (expr)); 1601 1.1.1.3 mrg return build_constructor (type, ve); 1602 1.1.1.3 mrg } 1603 1.1.1.3 mrg 1604 1.1.1.3 mrg /* Replace type in the reinterpret cast with a cast to the record type. */ 1605 1.1.1.3 mrg return build_vconvert (type, expr); 1606 1.1.1.3 mrg } 1607 1.1.1.3 mrg 1608 1.1 mrg /* Cast EXP (which should be a pointer) to TYPE* and then indirect. 1609 1.1 mrg The back-end requires this cast in many cases. */ 1610 1.1 mrg 1611 1.1 mrg tree 1612 1.1 mrg indirect_ref (tree type, tree exp) 1613 1.1 mrg { 1614 1.1 mrg if (error_operand_p (exp)) 1615 1.1 mrg return exp; 1616 1.1 mrg 1617 1.1 mrg /* Maybe rewrite: *(e1, e2) => (e1, *e2) */ 1618 1.1 mrg tree init = stabilize_expr (&exp); 1619 1.1 mrg 1620 1.1 mrg if (TREE_CODE (TREE_TYPE (exp)) == REFERENCE_TYPE) 1621 1.1 mrg exp = fold_build1 (INDIRECT_REF, type, exp); 1622 1.1 mrg else 1623 1.1 mrg { 1624 1.1 mrg exp = build_nop (build_pointer_type (type), exp); 1625 1.1 mrg exp = build_deref (exp); 1626 1.1 mrg } 1627 1.1 mrg 1628 1.1 mrg return compound_expr (init, exp); 1629 1.1 mrg } 1630 1.1 mrg 1631 1.1 mrg /* Returns indirect reference of EXP, which must be a pointer type. */ 1632 1.1 mrg 1633 1.1 mrg tree 1634 1.1 mrg build_deref (tree exp) 1635 1.1 mrg { 1636 1.1 mrg if (error_operand_p (exp)) 1637 1.1 mrg return exp; 1638 1.1 mrg 1639 1.1 mrg /* Maybe rewrite: *(e1, e2) => (e1, *e2) */ 1640 1.1 mrg tree init = stabilize_expr (&exp); 1641 1.1 mrg 1642 1.1 mrg gcc_assert (POINTER_TYPE_P (TREE_TYPE (exp))); 1643 1.1 mrg 1644 1.1 mrg if (TREE_CODE (exp) == ADDR_EXPR) 1645 1.1 mrg exp = TREE_OPERAND (exp, 0); 1646 1.1 mrg else 1647 1.1 mrg exp = build_fold_indirect_ref (exp); 1648 1.1 mrg 1649 1.1 mrg return compound_expr (init, exp); 1650 1.1 mrg } 1651 1.1 mrg 1652 1.1 mrg /* Builds pointer offset expression PTR[INDEX]. */ 1653 1.1 mrg 1654 1.1 mrg tree 1655 1.1 mrg build_array_index (tree ptr, tree index) 1656 1.1 mrg { 1657 1.1 mrg if (error_operand_p (ptr) || error_operand_p (index)) 1658 1.1 mrg return error_mark_node; 1659 1.1 mrg 1660 1.1 mrg tree ptr_type = TREE_TYPE (ptr); 1661 1.1 mrg tree target_type = TREE_TYPE (ptr_type); 1662 1.1 mrg 1663 1.1 mrg tree type = lang_hooks.types.type_for_size (TYPE_PRECISION (sizetype), 1664 1.1 mrg TYPE_UNSIGNED (sizetype)); 1665 1.1 mrg 1666 1.1 mrg /* Array element size. */ 1667 1.1 mrg tree size_exp = size_in_bytes (target_type); 1668 1.1 mrg 1669 1.1.1.2 mrg if (integer_zerop (size_exp) || integer_onep (size_exp)) 1670 1.1 mrg { 1671 1.1.1.2 mrg /* Array of void or bytes -- No need to multiply. */ 1672 1.1 mrg index = fold_convert (type, index); 1673 1.1 mrg } 1674 1.1 mrg else 1675 1.1 mrg { 1676 1.1 mrg index = d_convert (type, index); 1677 1.1 mrg index = fold_build2 (MULT_EXPR, TREE_TYPE (index), 1678 1.1 mrg index, d_convert (TREE_TYPE (index), size_exp)); 1679 1.1 mrg index = fold_convert (type, index); 1680 1.1 mrg } 1681 1.1 mrg 1682 1.1 mrg if (integer_zerop (index)) 1683 1.1 mrg return ptr; 1684 1.1 mrg 1685 1.1 mrg return fold_build2 (POINTER_PLUS_EXPR, ptr_type, ptr, index); 1686 1.1 mrg } 1687 1.1 mrg 1688 1.1 mrg /* Builds pointer offset expression *(PTR OP OFFSET) 1689 1.1 mrg OP could be a plus or minus expression. */ 1690 1.1 mrg 1691 1.1 mrg tree 1692 1.1 mrg build_offset_op (tree_code op, tree ptr, tree offset) 1693 1.1 mrg { 1694 1.1 mrg gcc_assert (op == MINUS_EXPR || op == PLUS_EXPR); 1695 1.1 mrg 1696 1.1 mrg tree type = lang_hooks.types.type_for_size (TYPE_PRECISION (sizetype), 1697 1.1 mrg TYPE_UNSIGNED (sizetype)); 1698 1.1 mrg offset = fold_convert (type, offset); 1699 1.1 mrg 1700 1.1 mrg if (op == MINUS_EXPR) 1701 1.1 mrg offset = fold_build1 (NEGATE_EXPR, type, offset); 1702 1.1 mrg 1703 1.1 mrg return fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (ptr), ptr, offset); 1704 1.1 mrg } 1705 1.1 mrg 1706 1.1 mrg /* Builds pointer offset expression *(PTR + OFFSET). */ 1707 1.1 mrg 1708 1.1 mrg tree 1709 1.1 mrg build_offset (tree ptr, tree offset) 1710 1.1 mrg { 1711 1.1 mrg return build_offset_op (PLUS_EXPR, ptr, offset); 1712 1.1 mrg } 1713 1.1 mrg 1714 1.1 mrg tree 1715 1.1 mrg build_memref (tree type, tree ptr, tree offset) 1716 1.1 mrg { 1717 1.1 mrg return fold_build2 (MEM_REF, type, ptr, fold_convert (type, offset)); 1718 1.1 mrg } 1719 1.1 mrg 1720 1.1 mrg /* Create a tree node to set multiple elements to a single value. */ 1721 1.1 mrg 1722 1.1 mrg tree 1723 1.1 mrg build_array_set (tree ptr, tree length, tree value) 1724 1.1 mrg { 1725 1.1 mrg tree ptrtype = TREE_TYPE (ptr); 1726 1.1 mrg tree lentype = TREE_TYPE (length); 1727 1.1 mrg 1728 1.1 mrg push_binding_level (level_block); 1729 1.1 mrg push_stmt_list (); 1730 1.1 mrg 1731 1.1 mrg /* Build temporary locals for length and ptr, and maybe value. */ 1732 1.1 mrg tree t = build_local_temp (size_type_node); 1733 1.1 mrg add_stmt (build_assign (INIT_EXPR, t, length)); 1734 1.1 mrg length = t; 1735 1.1 mrg 1736 1.1 mrg t = build_local_temp (ptrtype); 1737 1.1 mrg add_stmt (build_assign (INIT_EXPR, t, ptr)); 1738 1.1 mrg ptr = t; 1739 1.1 mrg 1740 1.1 mrg if (TREE_SIDE_EFFECTS (value)) 1741 1.1 mrg { 1742 1.1 mrg t = build_local_temp (TREE_TYPE (value)); 1743 1.1 mrg add_stmt (build_assign (INIT_EXPR, t, value)); 1744 1.1 mrg value = t; 1745 1.1 mrg } 1746 1.1 mrg 1747 1.1 mrg /* Build loop to initialize { .length=length, .ptr=ptr } with value. */ 1748 1.1 mrg push_stmt_list (); 1749 1.1 mrg 1750 1.1 mrg /* Exit logic for the loop. 1751 1.1 mrg if (length == 0) break; */ 1752 1.1 mrg t = build_boolop (EQ_EXPR, length, d_convert (lentype, integer_zero_node)); 1753 1.1 mrg t = build1 (EXIT_EXPR, void_type_node, t); 1754 1.1 mrg add_stmt (t); 1755 1.1 mrg 1756 1.1 mrg /* Assign value to the current pointer position. 1757 1.1 mrg *ptr = value; */ 1758 1.1 mrg t = modify_expr (build_deref (ptr), value); 1759 1.1 mrg add_stmt (t); 1760 1.1 mrg 1761 1.1 mrg /* Move pointer to next element position. 1762 1.1 mrg ptr++; */ 1763 1.1 mrg tree size = TYPE_SIZE_UNIT (TREE_TYPE (ptrtype)); 1764 1.1 mrg t = build2 (POSTINCREMENT_EXPR, ptrtype, ptr, d_convert (ptrtype, size)); 1765 1.1 mrg add_stmt (t); 1766 1.1 mrg 1767 1.1 mrg /* Decrease loop counter. 1768 1.1 mrg length -= 1; */ 1769 1.1 mrg t = build2 (POSTDECREMENT_EXPR, lentype, length, 1770 1.1 mrg d_convert (lentype, integer_one_node)); 1771 1.1 mrg add_stmt (t); 1772 1.1 mrg 1773 1.1 mrg /* Pop statements and finish loop. */ 1774 1.1 mrg tree loop_body = pop_stmt_list (); 1775 1.1 mrg add_stmt (build1 (LOOP_EXPR, void_type_node, loop_body)); 1776 1.1 mrg 1777 1.1 mrg /* Wrap it up into a bind expression. */ 1778 1.1 mrg tree stmt_list = pop_stmt_list (); 1779 1.1 mrg tree block = pop_binding_level (); 1780 1.1 mrg 1781 1.1 mrg return build3 (BIND_EXPR, void_type_node, 1782 1.1 mrg BLOCK_VARS (block), stmt_list, block); 1783 1.1 mrg } 1784 1.1 mrg 1785 1.1 mrg 1786 1.1 mrg /* Build an array of type TYPE where all the elements are VAL. */ 1787 1.1 mrg 1788 1.1 mrg tree 1789 1.1 mrg build_array_from_val (Type *type, tree val) 1790 1.1 mrg { 1791 1.1 mrg tree etype = build_ctype (type->nextOf ()); 1792 1.1 mrg 1793 1.1 mrg /* Initializing a multidimensional array. */ 1794 1.1 mrg if (TREE_CODE (etype) == ARRAY_TYPE && TREE_TYPE (val) != etype) 1795 1.1 mrg val = build_array_from_val (type->nextOf (), val); 1796 1.1 mrg 1797 1.1.1.3 mrg size_t dims = type->isTypeSArray ()->dim->toInteger (); 1798 1.1.1.3 mrg vec <constructor_elt, va_gc> *elms = NULL; 1799 1.1 mrg vec_safe_reserve (elms, dims); 1800 1.1 mrg 1801 1.1 mrg val = d_convert (etype, val); 1802 1.1 mrg 1803 1.1 mrg for (size_t i = 0; i < dims; i++) 1804 1.1 mrg CONSTRUCTOR_APPEND_ELT (elms, size_int (i), val); 1805 1.1 mrg 1806 1.1 mrg return build_constructor (build_ctype (type), elms); 1807 1.1 mrg } 1808 1.1 mrg 1809 1.1.1.3 mrg /* Build a static array of type TYPE from an array of EXPS. 1810 1.1.1.3 mrg If CONST_P is true, then all elements in EXPS are constants. */ 1811 1.1.1.3 mrg 1812 1.1.1.3 mrg tree 1813 1.1.1.3 mrg build_array_from_exprs (Type *type, Expressions *exps, bool const_p) 1814 1.1.1.3 mrg { 1815 1.1.1.3 mrg /* Build a CONSTRUCTOR from all expressions. */ 1816 1.1.1.3 mrg vec <constructor_elt, va_gc> *elms = NULL; 1817 1.1.1.3 mrg vec_safe_reserve (elms, exps->length); 1818 1.1.1.3 mrg 1819 1.1.1.3 mrg Type *etype = type->nextOf (); 1820 1.1.1.3 mrg tree satype = make_array_type (etype, exps->length); 1821 1.1.1.3 mrg 1822 1.1.1.3 mrg for (size_t i = 0; i < exps->length; i++) 1823 1.1.1.3 mrg { 1824 1.1.1.3 mrg Expression *expr = (*exps)[i]; 1825 1.1.1.3 mrg tree t = build_expr (expr, const_p); 1826 1.1.1.3 mrg CONSTRUCTOR_APPEND_ELT (elms, size_int (i), 1827 1.1.1.3 mrg convert_expr (t, expr->type, etype)); 1828 1.1.1.3 mrg } 1829 1.1.1.3 mrg 1830 1.1.1.3 mrg /* Create a new temporary to store the array. */ 1831 1.1.1.3 mrg tree var = build_local_temp (satype); 1832 1.1.1.3 mrg 1833 1.1.1.3 mrg /* Fill any alignment holes with zeroes. */ 1834 1.1.1.3 mrg TypeStruct *ts = etype->baseElemOf ()->isTypeStruct (); 1835 1.1.1.3 mrg tree init = NULL; 1836 1.1.1.3 mrg if (ts && (!identity_compare_p (ts->sym) || ts->sym->isUnionDeclaration ())) 1837 1.1.1.3 mrg init = build_memset_call (var); 1838 1.1.1.3 mrg 1839 1.1.1.3 mrg /* Initialize the temporary. */ 1840 1.1.1.3 mrg tree assign = modify_expr (var, build_constructor (satype, elms)); 1841 1.1.1.3 mrg return compound_expr (compound_expr (init, assign), var); 1842 1.1.1.3 mrg } 1843 1.1.1.3 mrg 1844 1.1.1.3 mrg 1845 1.1 mrg /* Implicitly converts void* T to byte* as D allows { void[] a; &a[3]; } */ 1846 1.1 mrg 1847 1.1 mrg tree 1848 1.1 mrg void_okay_p (tree t) 1849 1.1 mrg { 1850 1.1 mrg tree type = TREE_TYPE (t); 1851 1.1 mrg 1852 1.1 mrg if (VOID_TYPE_P (TREE_TYPE (type))) 1853 1.1 mrg { 1854 1.1 mrg tree totype = build_ctype (Type::tuns8->pointerTo ()); 1855 1.1 mrg return fold_convert (totype, t); 1856 1.1 mrg } 1857 1.1 mrg 1858 1.1 mrg return t; 1859 1.1 mrg } 1860 1.1 mrg 1861 1.1.1.3 mrg /* Builds a STRING_CST representing the filename of location LOC. When the 1862 1.1.1.3 mrg location is not valid, the name of the source module is used instead. */ 1863 1.1.1.3 mrg 1864 1.1.1.3 mrg static tree 1865 1.1.1.3 mrg build_filename_from_loc (const Loc &loc) 1866 1.1.1.3 mrg { 1867 1.1.1.3 mrg const char *filename = loc.filename 1868 1.1.1.3 mrg ? loc.filename : d_function_chain->module->srcfile.toChars (); 1869 1.1.1.3 mrg 1870 1.1.1.3 mrg unsigned length = strlen (filename); 1871 1.1.1.3 mrg tree str = build_string (length, filename); 1872 1.1.1.3 mrg TREE_TYPE (str) = make_array_type (Type::tchar, length + 1); 1873 1.1.1.3 mrg 1874 1.1.1.3 mrg return build_address (str); 1875 1.1.1.3 mrg } 1876 1.1.1.3 mrg 1877 1.1.1.3 mrg /* Builds a CALL_EXPR at location LOC in the source file to call LIBCALL when 1878 1.1.1.3 mrg an assert check fails. When calling the msg variant functions, MSG is the 1879 1.1.1.3 mrg error message supplied by the user. */ 1880 1.1 mrg 1881 1.1 mrg tree 1882 1.1.1.3 mrg build_assert_call (const Loc &loc, libcall_fn libcall, tree msg) 1883 1.1 mrg { 1884 1.1.1.3 mrg tree file; 1885 1.1.1.3 mrg tree line = size_int (loc.linnum); 1886 1.1.1.3 mrg 1887 1.1.1.3 mrg switch (libcall) 1888 1.1.1.3 mrg { 1889 1.1.1.3 mrg case LIBCALL_ASSERT_MSG: 1890 1.1.1.3 mrg case LIBCALL_UNITTEST_MSG: 1891 1.1.1.3 mrg /* File location is passed as a D string. */ 1892 1.1.1.3 mrg if (loc.filename) 1893 1.1.1.3 mrg { 1894 1.1.1.3 mrg unsigned len = strlen (loc.filename); 1895 1.1.1.3 mrg tree str = build_string (len, loc.filename); 1896 1.1.1.3 mrg TREE_TYPE (str) = make_array_type (Type::tchar, len); 1897 1.1.1.3 mrg 1898 1.1.1.3 mrg file = d_array_value (build_ctype (Type::tchar->arrayOf ()), 1899 1.1.1.3 mrg size_int (len), build_address (str)); 1900 1.1.1.3 mrg } 1901 1.1.1.3 mrg else 1902 1.1.1.3 mrg file = null_array_node; 1903 1.1.1.3 mrg break; 1904 1.1.1.3 mrg 1905 1.1.1.3 mrg case LIBCALL_ASSERTP: 1906 1.1.1.3 mrg case LIBCALL_UNITTESTP: 1907 1.1.1.3 mrg file = build_filename_from_loc (loc); 1908 1.1.1.3 mrg break; 1909 1.1.1.3 mrg 1910 1.1.1.3 mrg default: 1911 1.1.1.3 mrg gcc_unreachable (); 1912 1.1.1.3 mrg } 1913 1.1.1.3 mrg 1914 1.1.1.3 mrg 1915 1.1.1.3 mrg if (msg != NULL_TREE) 1916 1.1.1.3 mrg return build_libcall (libcall, Type::tvoid, 3, msg, file, line); 1917 1.1.1.3 mrg else 1918 1.1.1.3 mrg return build_libcall (libcall, Type::tvoid, 2, file, line); 1919 1.1.1.3 mrg } 1920 1.1.1.3 mrg 1921 1.1.1.3 mrg /* Builds a CALL_EXPR at location LOC in the source file to execute when an 1922 1.1.1.3 mrg array bounds check fails. */ 1923 1.1.1.3 mrg 1924 1.1.1.3 mrg tree 1925 1.1.1.3 mrg build_array_bounds_call (const Loc &loc) 1926 1.1.1.3 mrg { 1927 1.1.1.3 mrg /* Terminate the program with a trap if no D runtime present. */ 1928 1.1.1.3 mrg if (checkaction_trap_p ()) 1929 1.1.1.3 mrg return build_call_expr (builtin_decl_explicit (BUILT_IN_TRAP), 0); 1930 1.1.1.3 mrg else 1931 1.1.1.3 mrg { 1932 1.1.1.3 mrg return build_libcall (LIBCALL_ARRAYBOUNDSP, Type::tvoid, 2, 1933 1.1.1.3 mrg build_filename_from_loc (loc), 1934 1.1.1.3 mrg size_int (loc.linnum)); 1935 1.1.1.3 mrg } 1936 1.1.1.3 mrg } 1937 1.1.1.3 mrg 1938 1.1.1.3 mrg /* Builds a bounds condition checking that INDEX is between 0 and LENGTH 1939 1.1.1.3 mrg in the index expression IE. The condition returns the INDEX if true, or 1940 1.1.1.3 mrg throws a `ArrayIndexError`. */ 1941 1.1.1.3 mrg 1942 1.1.1.3 mrg tree 1943 1.1.1.3 mrg build_bounds_index_condition (IndexExp *ie, tree index, tree length) 1944 1.1.1.3 mrg { 1945 1.1.1.3 mrg if (ie->indexIsInBounds || !array_bounds_check ()) 1946 1.1 mrg return index; 1947 1.1 mrg 1948 1.1 mrg /* Prevent multiple evaluations of the index. */ 1949 1.1 mrg index = d_save_expr (index); 1950 1.1 mrg 1951 1.1.1.3 mrg /* Generate INDEX >= LENGTH && throw RangeError. 1952 1.1 mrg No need to check whether INDEX >= 0 as the front-end should 1953 1.1 mrg have already taken care of implicit casts to unsigned. */ 1954 1.1.1.3 mrg tree condition = fold_build2 (GE_EXPR, d_bool_type, index, length); 1955 1.1.1.3 mrg tree boundserr; 1956 1.1.1.3 mrg 1957 1.1.1.3 mrg if (checkaction_trap_p ()) 1958 1.1.1.3 mrg boundserr = build_call_expr (builtin_decl_explicit (BUILT_IN_TRAP), 0); 1959 1.1.1.3 mrg else 1960 1.1.1.3 mrg { 1961 1.1.1.3 mrg boundserr = build_libcall (LIBCALL_ARRAYBOUNDS_INDEXP, Type::tvoid, 4, 1962 1.1.1.3 mrg build_filename_from_loc (ie->e2->loc), 1963 1.1.1.3 mrg size_int (ie->e2->loc.linnum), index, length); 1964 1.1.1.3 mrg } 1965 1.1 mrg 1966 1.1 mrg return build_condition (TREE_TYPE (index), condition, boundserr, index); 1967 1.1 mrg } 1968 1.1 mrg 1969 1.1.1.3 mrg /* Builds a bounds condition checking that the range LOWER..UPPER do not overlap 1970 1.1.1.3 mrg the slice expression SE of the source array length LENGTH. The condition 1971 1.1.1.3 mrg returns the new array length if true, or throws an `ArraySliceError`. */ 1972 1.1.1.3 mrg 1973 1.1.1.3 mrg tree 1974 1.1.1.3 mrg build_bounds_slice_condition (SliceExp *se, tree lower, tree upper, tree length) 1975 1.1.1.3 mrg { 1976 1.1.1.3 mrg if (array_bounds_check ()) 1977 1.1.1.3 mrg { 1978 1.1.1.3 mrg tree condition = NULL_TREE; 1979 1.1.1.3 mrg 1980 1.1.1.3 mrg /* Enforces that `upper <= length`. */ 1981 1.1.1.3 mrg if (!se->upperIsInBounds && length != NULL_TREE) 1982 1.1.1.3 mrg condition = fold_build2 (GT_EXPR, d_bool_type, upper, length); 1983 1.1.1.3 mrg else 1984 1.1.1.3 mrg length = integer_zero_node; 1985 1.1.1.3 mrg 1986 1.1.1.3 mrg /* Enforces that `lower <= upper`. No need to check `lower <= length` as 1987 1.1.1.3 mrg we've already ensured that `upper <= length`. */ 1988 1.1.1.3 mrg if (!se->lowerIsLessThanUpper) 1989 1.1.1.3 mrg { 1990 1.1.1.3 mrg tree lwr_cond = fold_build2 (GT_EXPR, d_bool_type, lower, upper); 1991 1.1.1.3 mrg 1992 1.1.1.3 mrg if (condition != NULL_TREE) 1993 1.1.1.3 mrg condition = build_boolop (TRUTH_ORIF_EXPR, condition, lwr_cond); 1994 1.1.1.3 mrg else 1995 1.1.1.3 mrg condition = lwr_cond; 1996 1.1.1.3 mrg } 1997 1.1.1.3 mrg 1998 1.1.1.3 mrg if (condition != NULL_TREE) 1999 1.1.1.3 mrg { 2000 1.1.1.3 mrg tree boundserr; 2001 1.1.1.3 mrg 2002 1.1.1.3 mrg if (checkaction_trap_p ()) 2003 1.1.1.3 mrg { 2004 1.1.1.3 mrg boundserr = 2005 1.1.1.3 mrg build_call_expr (builtin_decl_explicit (BUILT_IN_TRAP), 0); 2006 1.1.1.3 mrg } 2007 1.1.1.3 mrg else 2008 1.1.1.3 mrg { 2009 1.1.1.3 mrg boundserr = build_libcall (LIBCALL_ARRAYBOUNDS_SLICEP, 2010 1.1.1.3 mrg Type::tvoid, 5, 2011 1.1.1.3 mrg build_filename_from_loc (se->loc), 2012 1.1.1.3 mrg size_int (se->loc.linnum), 2013 1.1.1.3 mrg lower, upper, length); 2014 1.1.1.3 mrg } 2015 1.1.1.3 mrg 2016 1.1.1.3 mrg upper = build_condition (TREE_TYPE (upper), condition, 2017 1.1.1.3 mrg boundserr, upper); 2018 1.1.1.3 mrg } 2019 1.1.1.3 mrg } 2020 1.1.1.3 mrg 2021 1.1.1.3 mrg /* Need to ensure lower always gets evaluated first, as it may be a function 2022 1.1.1.3 mrg call. Generates (lower, upper) - lower. */ 2023 1.1.1.3 mrg return fold_build2 (MINUS_EXPR, TREE_TYPE (upper), 2024 1.1.1.3 mrg compound_expr (lower, upper), lower); 2025 1.1.1.3 mrg } 2026 1.1.1.3 mrg 2027 1.1 mrg /* Returns TRUE if array bounds checking code generation is turned on. */ 2028 1.1 mrg 2029 1.1 mrg bool 2030 1.1 mrg array_bounds_check (void) 2031 1.1 mrg { 2032 1.1 mrg FuncDeclaration *fd; 2033 1.1 mrg 2034 1.1 mrg switch (global.params.useArrayBounds) 2035 1.1 mrg { 2036 1.1.1.3 mrg case CHECKENABLEoff: 2037 1.1 mrg return false; 2038 1.1 mrg 2039 1.1.1.3 mrg case CHECKENABLEon: 2040 1.1 mrg return true; 2041 1.1 mrg 2042 1.1.1.3 mrg case CHECKENABLEsafeonly: 2043 1.1 mrg /* For D2 safe functions only. */ 2044 1.1 mrg fd = d_function_chain->function; 2045 1.1.1.3 mrg if (fd && fd->type->ty == TY::Tfunction) 2046 1.1 mrg { 2047 1.1.1.3 mrg if (fd->type->isTypeFunction ()->trust == TRUST::safe) 2048 1.1 mrg return true; 2049 1.1 mrg } 2050 1.1 mrg return false; 2051 1.1 mrg 2052 1.1 mrg default: 2053 1.1 mrg gcc_unreachable (); 2054 1.1 mrg } 2055 1.1 mrg } 2056 1.1 mrg 2057 1.1.1.3 mrg /* Returns TRUE if we terminate the program with a trap if an array bounds or 2058 1.1.1.3 mrg contract check fails. */ 2059 1.1.1.3 mrg 2060 1.1.1.3 mrg bool 2061 1.1.1.3 mrg checkaction_trap_p (void) 2062 1.1.1.3 mrg { 2063 1.1.1.3 mrg switch (global.params.checkAction) 2064 1.1.1.3 mrg { 2065 1.1.1.3 mrg case CHECKACTION_D: 2066 1.1.1.3 mrg case CHECKACTION_context: 2067 1.1.1.3 mrg return false; 2068 1.1.1.3 mrg 2069 1.1.1.3 mrg case CHECKACTION_C: 2070 1.1.1.3 mrg case CHECKACTION_halt: 2071 1.1.1.3 mrg return true; 2072 1.1.1.3 mrg 2073 1.1.1.3 mrg default: 2074 1.1.1.3 mrg gcc_unreachable (); 2075 1.1.1.3 mrg } 2076 1.1.1.3 mrg } 2077 1.1.1.3 mrg 2078 1.1 mrg /* Returns the TypeFunction class for Type T. 2079 1.1 mrg Assumes T is already ->toBasetype(). */ 2080 1.1 mrg 2081 1.1 mrg TypeFunction * 2082 1.1 mrg get_function_type (Type *t) 2083 1.1 mrg { 2084 1.1 mrg TypeFunction *tf = NULL; 2085 1.1.1.3 mrg if (t->ty == TY::Tpointer) 2086 1.1 mrg t = t->nextOf ()->toBasetype (); 2087 1.1.1.3 mrg if (t->ty == TY::Tfunction) 2088 1.1.1.3 mrg tf = t->isTypeFunction (); 2089 1.1.1.3 mrg else if (t->ty == TY::Tdelegate) 2090 1.1.1.3 mrg tf = t->isTypeDelegate ()->next->isTypeFunction (); 2091 1.1 mrg return tf; 2092 1.1 mrg } 2093 1.1 mrg 2094 1.1 mrg /* Returns TRUE if CALLEE is a plain nested function outside the scope of 2095 1.1 mrg CALLER. In which case, CALLEE is being called through an alias that was 2096 1.1 mrg passed to CALLER. */ 2097 1.1 mrg 2098 1.1 mrg bool 2099 1.1 mrg call_by_alias_p (FuncDeclaration *caller, FuncDeclaration *callee) 2100 1.1 mrg { 2101 1.1 mrg if (!callee->isNested ()) 2102 1.1 mrg return false; 2103 1.1 mrg 2104 1.1 mrg if (caller->toParent () == callee->toParent ()) 2105 1.1 mrg return false; 2106 1.1 mrg 2107 1.1 mrg Dsymbol *dsym = callee; 2108 1.1 mrg 2109 1.1 mrg while (dsym) 2110 1.1 mrg { 2111 1.1 mrg if (dsym->isTemplateInstance ()) 2112 1.1 mrg return false; 2113 1.1 mrg else if (dsym->isFuncDeclaration () == caller) 2114 1.1 mrg return false; 2115 1.1 mrg dsym = dsym->toParent (); 2116 1.1 mrg } 2117 1.1 mrg 2118 1.1 mrg return true; 2119 1.1 mrg } 2120 1.1 mrg 2121 1.1 mrg /* Entry point for call routines. Builds a function call to FD. 2122 1.1.1.3 mrg OBJECT is the `this' reference passed and ARGS are the arguments to FD. */ 2123 1.1 mrg 2124 1.1 mrg tree 2125 1.1 mrg d_build_call_expr (FuncDeclaration *fd, tree object, Expressions *arguments) 2126 1.1 mrg { 2127 1.1 mrg return d_build_call (get_function_type (fd->type), 2128 1.1 mrg build_address (get_symbol_decl (fd)), object, arguments); 2129 1.1 mrg } 2130 1.1 mrg 2131 1.1.1.3 mrg /* Builds a CALL_EXPR of type TF to CALLABLE. OBJECT holds the `this' pointer, 2132 1.1 mrg ARGUMENTS are evaluated in left to right order, saved and promoted 2133 1.1 mrg before passing. */ 2134 1.1 mrg 2135 1.1 mrg tree 2136 1.1 mrg d_build_call (TypeFunction *tf, tree callable, tree object, 2137 1.1 mrg Expressions *arguments) 2138 1.1 mrg { 2139 1.1 mrg tree ctype = TREE_TYPE (callable); 2140 1.1 mrg tree callee = callable; 2141 1.1 mrg 2142 1.1 mrg if (POINTER_TYPE_P (ctype)) 2143 1.1 mrg ctype = TREE_TYPE (ctype); 2144 1.1 mrg else 2145 1.1 mrg callee = build_address (callable); 2146 1.1 mrg 2147 1.1 mrg gcc_assert (FUNC_OR_METHOD_TYPE_P (ctype)); 2148 1.1 mrg gcc_assert (tf != NULL); 2149 1.1.1.3 mrg gcc_assert (tf->ty == TY::Tfunction); 2150 1.1 mrg 2151 1.1 mrg if (TREE_CODE (ctype) != FUNCTION_TYPE && object == NULL_TREE) 2152 1.1 mrg { 2153 1.1 mrg /* Front-end apparently doesn't check this. */ 2154 1.1 mrg if (TREE_CODE (callable) == FUNCTION_DECL) 2155 1.1 mrg { 2156 1.1 mrg error ("need %<this%> to access member %qE", DECL_NAME (callable)); 2157 1.1 mrg return error_mark_node; 2158 1.1 mrg } 2159 1.1 mrg 2160 1.1 mrg /* Probably an internal error. */ 2161 1.1 mrg gcc_unreachable (); 2162 1.1 mrg } 2163 1.1 mrg 2164 1.1 mrg /* Build the argument list for the call. */ 2165 1.1.1.3 mrg vec <tree, va_gc> *args = NULL; 2166 1.1 mrg tree saved_args = NULL_TREE; 2167 1.1.1.3 mrg bool noreturn_call = false; 2168 1.1 mrg 2169 1.1 mrg /* If this is a delegate call or a nested function being called as 2170 1.1 mrg a delegate, the object should not be NULL. */ 2171 1.1 mrg if (object != NULL_TREE) 2172 1.1 mrg vec_safe_push (args, object); 2173 1.1 mrg 2174 1.1 mrg if (arguments) 2175 1.1 mrg { 2176 1.1 mrg /* First pass, evaluated expanded tuples in function arguments. */ 2177 1.1.1.3 mrg for (size_t i = 0; i < arguments->length; ++i) 2178 1.1 mrg { 2179 1.1 mrg Lagain: 2180 1.1 mrg Expression *arg = (*arguments)[i]; 2181 1.1.1.3 mrg gcc_assert (arg->op != EXP::tuple); 2182 1.1 mrg 2183 1.1.1.3 mrg if (arg->op == EXP::comma) 2184 1.1 mrg { 2185 1.1.1.3 mrg CommaExp *ce = arg->isCommaExp (); 2186 1.1 mrg tree tce = build_expr (ce->e1); 2187 1.1 mrg saved_args = compound_expr (saved_args, tce); 2188 1.1 mrg (*arguments)[i] = ce->e2; 2189 1.1 mrg goto Lagain; 2190 1.1 mrg } 2191 1.1 mrg } 2192 1.1 mrg 2193 1.1.1.3 mrg const size_t nparams = tf->parameterList.length (); 2194 1.1 mrg /* if _arguments[] is the first argument. */ 2195 1.1.1.3 mrg const size_t varargs = tf->isDstyleVariadic (); 2196 1.1 mrg 2197 1.1.1.3 mrg /* Assumes arguments->length <= formal_args->length if (!tf->varargs). */ 2198 1.1.1.3 mrg for (size_t i = 0; i < arguments->length; ++i) 2199 1.1 mrg { 2200 1.1 mrg Expression *arg = (*arguments)[i]; 2201 1.1.1.3 mrg tree targ; 2202 1.1 mrg 2203 1.1 mrg if (i - varargs < nparams && i >= varargs) 2204 1.1 mrg { 2205 1.1 mrg /* Actual arguments for declared formal arguments. */ 2206 1.1.1.3 mrg Parameter *parg = tf->parameterList[i - varargs]; 2207 1.1.1.3 mrg targ = convert_for_argument (arg, parg); 2208 1.1 mrg } 2209 1.1.1.3 mrg else 2210 1.1.1.3 mrg targ = build_expr (arg); 2211 1.1 mrg 2212 1.1 mrg /* Don't pass empty aggregates by value. */ 2213 1.1 mrg if (empty_aggregate_p (TREE_TYPE (targ)) && !TREE_ADDRESSABLE (targ) 2214 1.1 mrg && TREE_CODE (targ) != CONSTRUCTOR) 2215 1.1 mrg { 2216 1.1 mrg tree t = build_constructor (TREE_TYPE (targ), NULL); 2217 1.1 mrg targ = build2 (COMPOUND_EXPR, TREE_TYPE (t), targ, t); 2218 1.1 mrg } 2219 1.1 mrg 2220 1.1.1.2 mrg /* Parameter is a struct or array passed by invisible reference. */ 2221 1.1.1.2 mrg if (TREE_ADDRESSABLE (TREE_TYPE (targ))) 2222 1.1.1.2 mrg { 2223 1.1.1.3 mrg Type *t = arg->type->toBasetype (); 2224 1.1.1.3 mrg StructDeclaration *sd = t->baseElemOf ()->isTypeStruct ()->sym; 2225 1.1.1.3 mrg 2226 1.1.1.3 mrg /* Need to take care of copying its value before passing the 2227 1.1.1.3 mrg argument in the following scenarios: 2228 1.1.1.3 mrg - The argument is a literal expression; a CONSTRUCTOR can't 2229 1.1.1.3 mrg have its address taken. 2230 1.1.1.3 mrg - The type has neither a copy constructor nor a destructor 2231 1.1.1.3 mrg available; nested structs also have ADDRESSABLE set. 2232 1.1.1.3 mrg - The ABI of the function expects the callee to destroy its 2233 1.1.1.3 mrg arguments; when the caller is handles destruction, then `targ' 2234 1.1.1.3 mrg has already been made into a temporary. */ 2235 1.1.1.3 mrg if (arg->op == EXP::structLiteral || (!sd->postblit && !sd->dtor) 2236 1.1.1.3 mrg || target.isCalleeDestroyingArgs (tf)) 2237 1.1.1.2 mrg targ = force_target_expr (targ); 2238 1.1.1.2 mrg 2239 1.1.1.2 mrg targ = convert (build_reference_type (TREE_TYPE (targ)), 2240 1.1.1.2 mrg build_address (targ)); 2241 1.1.1.2 mrg } 2242 1.1.1.2 mrg 2243 1.1.1.3 mrg /* Complex types are exposed as special types with an underlying 2244 1.1.1.3 mrg struct representation, if we are passing the native type to a 2245 1.1.1.3 mrg function that accepts the library-defined version, then ensure 2246 1.1.1.3 mrg it is properly reinterpreted as the underlying struct type. */ 2247 1.1.1.3 mrg if (COMPLEX_FLOAT_TYPE_P (TREE_TYPE (targ)) 2248 1.1.1.3 mrg && arg->type->isTypeStruct ()) 2249 1.1.1.3 mrg targ = underlying_complex_expr (build_ctype (arg->type), targ); 2250 1.1.1.3 mrg 2251 1.1.1.3 mrg /* Type `noreturn` is a terminator, as no other arguments can possibly 2252 1.1.1.3 mrg be evaluated after it. */ 2253 1.1.1.3 mrg if (TREE_TYPE (targ) == noreturn_type_node) 2254 1.1.1.3 mrg noreturn_call = true; 2255 1.1.1.3 mrg 2256 1.1 mrg vec_safe_push (args, targ); 2257 1.1 mrg } 2258 1.1 mrg } 2259 1.1 mrg 2260 1.1 mrg /* Evaluate the callee before calling it. */ 2261 1.1 mrg if (TREE_SIDE_EFFECTS (callee)) 2262 1.1 mrg { 2263 1.1 mrg callee = d_save_expr (callee); 2264 1.1 mrg saved_args = compound_expr (callee, saved_args); 2265 1.1 mrg } 2266 1.1 mrg 2267 1.1.1.3 mrg /* If we saw a `noreturn` parameter, any unreachable argument evaluations 2268 1.1.1.3 mrg after it are discarded, as well as the function call itself. */ 2269 1.1.1.3 mrg if (noreturn_call) 2270 1.1.1.3 mrg { 2271 1.1.1.3 mrg if (TREE_SIDE_EFFECTS (callee)) 2272 1.1.1.3 mrg saved_args = compound_expr (callee, saved_args); 2273 1.1.1.3 mrg 2274 1.1.1.3 mrg tree arg; 2275 1.1.1.3 mrg unsigned int ix; 2276 1.1.1.3 mrg 2277 1.1.1.3 mrg FOR_EACH_VEC_SAFE_ELT (args, ix, arg) 2278 1.1.1.3 mrg saved_args = compound_expr (saved_args, arg); 2279 1.1.1.3 mrg 2280 1.1.1.3 mrg /* Add a stub result type for the expression. */ 2281 1.1.1.3 mrg tree result = build_zero_cst (TREE_TYPE (ctype)); 2282 1.1.1.3 mrg return compound_expr (saved_args, result); 2283 1.1.1.3 mrg } 2284 1.1 mrg 2285 1.1.1.3 mrg tree result = build_call_vec (TREE_TYPE (ctype), callee, args); 2286 1.1.1.3 mrg SET_EXPR_LOCATION (result, input_location); 2287 1.1 mrg 2288 1.1 mrg result = maybe_expand_intrinsic (result); 2289 1.1 mrg 2290 1.1 mrg /* Return the value in a temporary slot so that it can be evaluated 2291 1.1 mrg multiple times by the caller. */ 2292 1.1 mrg if (TREE_CODE (result) == CALL_EXPR 2293 1.1 mrg && AGGREGATE_TYPE_P (TREE_TYPE (result)) 2294 1.1 mrg && TREE_ADDRESSABLE (TREE_TYPE (result))) 2295 1.1 mrg { 2296 1.1 mrg CALL_EXPR_RETURN_SLOT_OPT (result) = true; 2297 1.1 mrg result = force_target_expr (result); 2298 1.1 mrg } 2299 1.1 mrg 2300 1.1 mrg return compound_expr (saved_args, result); 2301 1.1 mrg } 2302 1.1 mrg 2303 1.1 mrg /* Build and return the correct call to fmod depending on TYPE. 2304 1.1 mrg ARG0 and ARG1 are the arguments pass to the function. */ 2305 1.1 mrg 2306 1.1 mrg tree 2307 1.1 mrg build_float_modulus (tree type, tree arg0, tree arg1) 2308 1.1 mrg { 2309 1.1 mrg tree fmodfn = NULL_TREE; 2310 1.1 mrg tree basetype = type; 2311 1.1 mrg 2312 1.1 mrg if (COMPLEX_FLOAT_TYPE_P (basetype)) 2313 1.1 mrg basetype = TREE_TYPE (basetype); 2314 1.1 mrg 2315 1.1 mrg if (TYPE_MAIN_VARIANT (basetype) == double_type_node 2316 1.1 mrg || TYPE_MAIN_VARIANT (basetype) == idouble_type_node) 2317 1.1 mrg fmodfn = builtin_decl_explicit (BUILT_IN_FMOD); 2318 1.1 mrg else if (TYPE_MAIN_VARIANT (basetype) == float_type_node 2319 1.1 mrg || TYPE_MAIN_VARIANT (basetype) == ifloat_type_node) 2320 1.1 mrg fmodfn = builtin_decl_explicit (BUILT_IN_FMODF); 2321 1.1 mrg else if (TYPE_MAIN_VARIANT (basetype) == long_double_type_node 2322 1.1 mrg || TYPE_MAIN_VARIANT (basetype) == ireal_type_node) 2323 1.1 mrg fmodfn = builtin_decl_explicit (BUILT_IN_FMODL); 2324 1.1 mrg 2325 1.1 mrg if (!fmodfn) 2326 1.1 mrg { 2327 1.1 mrg error ("tried to perform floating-point modulo division on %qT", type); 2328 1.1 mrg return error_mark_node; 2329 1.1 mrg } 2330 1.1 mrg 2331 1.1 mrg if (COMPLEX_FLOAT_TYPE_P (type)) 2332 1.1 mrg { 2333 1.1 mrg tree re = build_call_expr (fmodfn, 2, real_part (arg0), arg1); 2334 1.1 mrg tree im = build_call_expr (fmodfn, 2, imaginary_part (arg0), arg1); 2335 1.1 mrg 2336 1.1 mrg return complex_expr (type, re, im); 2337 1.1 mrg } 2338 1.1 mrg 2339 1.1 mrg if (SCALAR_FLOAT_TYPE_P (type)) 2340 1.1 mrg return build_call_expr (fmodfn, 2, arg0, arg1); 2341 1.1 mrg 2342 1.1 mrg /* Should have caught this above. */ 2343 1.1 mrg gcc_unreachable (); 2344 1.1 mrg } 2345 1.1 mrg 2346 1.1 mrg /* Build a function type whose first argument is a pointer to BASETYPE, 2347 1.1.1.3 mrg which is to be used for the `vthis' context parameter for TYPE. 2348 1.1 mrg The base type may be a record for member functions, or a void for 2349 1.1 mrg nested functions and delegates. */ 2350 1.1 mrg 2351 1.1 mrg tree 2352 1.1 mrg build_vthis_function (tree basetype, tree type) 2353 1.1 mrg { 2354 1.1 mrg gcc_assert (TREE_CODE (type) == FUNCTION_TYPE); 2355 1.1 mrg 2356 1.1 mrg tree argtypes = tree_cons (NULL_TREE, build_pointer_type (basetype), 2357 1.1 mrg TYPE_ARG_TYPES (type)); 2358 1.1 mrg tree fntype = build_function_type (TREE_TYPE (type), argtypes); 2359 1.1 mrg 2360 1.1.1.3 mrg /* Copy volatile qualifiers from the original function type. */ 2361 1.1.1.3 mrg if (TYPE_QUALS (type) & TYPE_QUAL_VOLATILE) 2362 1.1.1.3 mrg fntype = build_qualified_type (fntype, TYPE_QUAL_VOLATILE); 2363 1.1.1.3 mrg 2364 1.1 mrg if (RECORD_OR_UNION_TYPE_P (basetype)) 2365 1.1 mrg TYPE_METHOD_BASETYPE (fntype) = TYPE_MAIN_VARIANT (basetype); 2366 1.1 mrg else 2367 1.1 mrg gcc_assert (VOID_TYPE_P (basetype)); 2368 1.1 mrg 2369 1.1 mrg return fntype; 2370 1.1 mrg } 2371 1.1 mrg 2372 1.1.1.2 mrg /* Raise an error at that the context pointer of the function or object SYM is 2373 1.1.1.2 mrg not accessible from the current scope. */ 2374 1.1.1.2 mrg 2375 1.1.1.2 mrg tree 2376 1.1.1.2 mrg error_no_frame_access (Dsymbol *sym) 2377 1.1.1.2 mrg { 2378 1.1.1.2 mrg error_at (input_location, "cannot get frame pointer to %qs", 2379 1.1.1.2 mrg sym->toPrettyChars ()); 2380 1.1.1.2 mrg return null_pointer_node; 2381 1.1.1.2 mrg } 2382 1.1.1.2 mrg 2383 1.1 mrg /* If SYM is a nested function, return the static chain to be 2384 1.1 mrg used when calling that function from the current function. 2385 1.1 mrg 2386 1.1 mrg If SYM is a nested class or struct, return the static chain 2387 1.1 mrg to be used when creating an instance of the class from CFUN. */ 2388 1.1 mrg 2389 1.1 mrg tree 2390 1.1 mrg get_frame_for_symbol (Dsymbol *sym) 2391 1.1 mrg { 2392 1.1 mrg FuncDeclaration *thisfd 2393 1.1 mrg = d_function_chain ? d_function_chain->function : NULL; 2394 1.1 mrg FuncDeclaration *fd = sym->isFuncDeclaration (); 2395 1.1 mrg FuncDeclaration *fdparent = NULL; 2396 1.1 mrg FuncDeclaration *fdoverride = NULL; 2397 1.1 mrg 2398 1.1 mrg if (fd != NULL) 2399 1.1 mrg { 2400 1.1 mrg /* Check that the nested function is properly defined. */ 2401 1.1 mrg if (!fd->fbody) 2402 1.1 mrg { 2403 1.1.1.3 mrg /* Should instead error on line that references `fd'. */ 2404 1.1 mrg error_at (make_location_t (fd->loc), "nested function missing body"); 2405 1.1 mrg return null_pointer_node; 2406 1.1 mrg } 2407 1.1 mrg 2408 1.1 mrg fdparent = fd->toParent2 ()->isFuncDeclaration (); 2409 1.1 mrg 2410 1.1 mrg /* Special case for __ensure and __require. */ 2411 1.1 mrg if ((fd->ident == Identifier::idPool ("__ensure") 2412 1.1 mrg || fd->ident == Identifier::idPool ("__require")) 2413 1.1 mrg && fdparent != thisfd) 2414 1.1 mrg { 2415 1.1 mrg fdoverride = fdparent; 2416 1.1 mrg fdparent = thisfd; 2417 1.1 mrg } 2418 1.1 mrg } 2419 1.1 mrg else 2420 1.1 mrg { 2421 1.1 mrg /* It's a class (or struct). NewExp codegen has already determined its 2422 1.1 mrg outer scope is not another class, so it must be a function. */ 2423 1.1 mrg while (sym && !sym->isFuncDeclaration ()) 2424 1.1 mrg sym = sym->toParent2 (); 2425 1.1 mrg 2426 1.1 mrg fdparent = (FuncDeclaration *) sym; 2427 1.1 mrg } 2428 1.1 mrg 2429 1.1 mrg /* Not a nested function, there is no frame pointer to pass. */ 2430 1.1 mrg if (fdparent == NULL) 2431 1.1 mrg { 2432 1.1 mrg /* Only delegate literals report as being nested, even if they are in 2433 1.1 mrg global scope. */ 2434 1.1 mrg gcc_assert (fd && fd->isFuncLiteralDeclaration ()); 2435 1.1 mrg return null_pointer_node; 2436 1.1 mrg } 2437 1.1 mrg 2438 1.1 mrg gcc_assert (thisfd != NULL); 2439 1.1 mrg 2440 1.1 mrg if (thisfd != fdparent) 2441 1.1 mrg { 2442 1.1 mrg /* If no frame pointer for this function. */ 2443 1.1 mrg if (!thisfd->vthis) 2444 1.1 mrg { 2445 1.1 mrg error_at (make_location_t (sym->loc), 2446 1.1 mrg "%qs is a nested function and cannot be accessed from %qs", 2447 1.1.1.2 mrg fdparent->toPrettyChars (), thisfd->toPrettyChars ()); 2448 1.1 mrg return null_pointer_node; 2449 1.1 mrg } 2450 1.1 mrg 2451 1.1 mrg /* Make sure we can get the frame pointer to the outer function. 2452 1.1 mrg Go up each nesting level until we find the enclosing function. */ 2453 1.1 mrg Dsymbol *dsym = thisfd; 2454 1.1 mrg 2455 1.1 mrg while (fd != dsym) 2456 1.1 mrg { 2457 1.1 mrg /* Check if enclosing function is a function. */ 2458 1.1.1.2 mrg FuncDeclaration *fdp = dsym->isFuncDeclaration (); 2459 1.1.1.2 mrg Dsymbol *parent = dsym->toParent2 (); 2460 1.1 mrg 2461 1.1.1.2 mrg if (fdp != NULL) 2462 1.1 mrg { 2463 1.1.1.2 mrg if (fdparent == parent) 2464 1.1 mrg break; 2465 1.1 mrg 2466 1.1.1.2 mrg gcc_assert (fdp->isNested () || fdp->vthis); 2467 1.1.1.2 mrg dsym = parent; 2468 1.1 mrg continue; 2469 1.1 mrg } 2470 1.1 mrg 2471 1.1 mrg /* Check if enclosed by an aggregate. That means the current 2472 1.1 mrg function must be a member function of that aggregate. */ 2473 1.1.1.2 mrg AggregateDeclaration *adp = dsym->isAggregateDeclaration (); 2474 1.1 mrg 2475 1.1.1.2 mrg if (adp != NULL) 2476 1.1 mrg { 2477 1.1.1.2 mrg if ((adp->isClassDeclaration () || adp->isStructDeclaration ()) 2478 1.1.1.2 mrg && fdparent == parent) 2479 1.1.1.2 mrg break; 2480 1.1 mrg } 2481 1.1 mrg 2482 1.1.1.2 mrg /* No frame to outer function found. */ 2483 1.1.1.2 mrg if (!adp || !adp->isNested () || !adp->vthis) 2484 1.1.1.2 mrg return error_no_frame_access (sym); 2485 1.1.1.2 mrg 2486 1.1.1.2 mrg dsym = parent; 2487 1.1 mrg } 2488 1.1 mrg } 2489 1.1 mrg 2490 1.1 mrg tree ffo = get_frameinfo (fdparent); 2491 1.1 mrg if (FRAMEINFO_CREATES_FRAME (ffo) || FRAMEINFO_STATIC_CHAIN (ffo)) 2492 1.1 mrg { 2493 1.1 mrg tree frame_ref = get_framedecl (thisfd, fdparent); 2494 1.1 mrg 2495 1.1.1.3 mrg /* If `thisfd' is a derived member function, then `fdparent' is the 2496 1.1 mrg overridden member function in the base class. Even if there's a 2497 1.1 mrg closure environment, we should give the original stack data as the 2498 1.1 mrg nested function frame. */ 2499 1.1 mrg if (fdoverride) 2500 1.1 mrg { 2501 1.1 mrg ClassDeclaration *cdo = fdoverride->isThis ()->isClassDeclaration (); 2502 1.1 mrg ClassDeclaration *cd = thisfd->isThis ()->isClassDeclaration (); 2503 1.1 mrg gcc_assert (cdo && cd); 2504 1.1 mrg 2505 1.1 mrg int offset; 2506 1.1 mrg if (cdo->isBaseOf (cd, &offset) && offset != 0) 2507 1.1 mrg { 2508 1.1 mrg /* Generate a new frame to pass to the overriden function that 2509 1.1.1.3 mrg has the `this' pointer adjusted. */ 2510 1.1 mrg gcc_assert (offset != OFFSET_RUNTIME); 2511 1.1 mrg 2512 1.1 mrg tree type = FRAMEINFO_TYPE (get_frameinfo (fdoverride)); 2513 1.1 mrg tree fields = TYPE_FIELDS (type); 2514 1.1.1.3 mrg /* The `this' field comes immediately after the `__chain'. */ 2515 1.1 mrg tree thisfield = chain_index (1, fields); 2516 1.1.1.3 mrg vec <constructor_elt, va_gc> *ve = NULL; 2517 1.1 mrg 2518 1.1 mrg tree framefields = TYPE_FIELDS (FRAMEINFO_TYPE (ffo)); 2519 1.1 mrg frame_ref = build_deref (frame_ref); 2520 1.1 mrg 2521 1.1 mrg for (tree field = fields; field; field = DECL_CHAIN (field)) 2522 1.1 mrg { 2523 1.1 mrg tree value = component_ref (frame_ref, framefields); 2524 1.1 mrg if (field == thisfield) 2525 1.1 mrg value = build_offset (value, size_int (offset)); 2526 1.1 mrg 2527 1.1 mrg CONSTRUCTOR_APPEND_ELT (ve, field, value); 2528 1.1 mrg framefields = DECL_CHAIN (framefields); 2529 1.1 mrg } 2530 1.1 mrg 2531 1.1 mrg frame_ref = build_address (build_constructor (type, ve)); 2532 1.1 mrg } 2533 1.1 mrg } 2534 1.1 mrg 2535 1.1 mrg return frame_ref; 2536 1.1 mrg } 2537 1.1 mrg 2538 1.1 mrg return null_pointer_node; 2539 1.1 mrg } 2540 1.1 mrg 2541 1.1.1.3 mrg /* Return the parent function of a nested class or struct AD. */ 2542 1.1 mrg 2543 1.1 mrg static FuncDeclaration * 2544 1.1.1.3 mrg get_outer_function (AggregateDeclaration *ad) 2545 1.1 mrg { 2546 1.1 mrg FuncDeclaration *fd = NULL; 2547 1.1.1.3 mrg while (ad && ad->isNested ()) 2548 1.1 mrg { 2549 1.1.1.3 mrg Dsymbol *dsym = ad->toParent2 (); 2550 1.1 mrg if ((fd = dsym->isFuncDeclaration ())) 2551 1.1 mrg return fd; 2552 1.1 mrg else 2553 1.1.1.3 mrg ad = dsym->isAggregateDeclaration (); 2554 1.1 mrg } 2555 1.1 mrg 2556 1.1 mrg return NULL; 2557 1.1 mrg } 2558 1.1 mrg 2559 1.1 mrg /* Starting from the current function FD, try to find a suitable value of 2560 1.1.1.3 mrg `this' in nested function instances. A suitable `this' value is an 2561 1.1 mrg instance of OCD or a class that has OCD as a base. */ 2562 1.1 mrg 2563 1.1 mrg static tree 2564 1.1 mrg find_this_tree (ClassDeclaration *ocd) 2565 1.1 mrg { 2566 1.1 mrg FuncDeclaration *fd = d_function_chain ? d_function_chain->function : NULL; 2567 1.1 mrg 2568 1.1 mrg while (fd) 2569 1.1 mrg { 2570 1.1 mrg AggregateDeclaration *ad = fd->isThis (); 2571 1.1 mrg ClassDeclaration *cd = ad ? ad->isClassDeclaration () : NULL; 2572 1.1 mrg 2573 1.1 mrg if (cd != NULL) 2574 1.1 mrg { 2575 1.1 mrg if (ocd == cd) 2576 1.1 mrg return get_decl_tree (fd->vthis); 2577 1.1 mrg else if (ocd->isBaseOf (cd, NULL)) 2578 1.1 mrg return convert_expr (get_decl_tree (fd->vthis), 2579 1.1 mrg cd->type, ocd->type); 2580 1.1 mrg 2581 1.1.1.3 mrg fd = get_outer_function (cd); 2582 1.1.1.3 mrg continue; 2583 1.1 mrg } 2584 1.1 mrg 2585 1.1.1.3 mrg if (fd->isNested ()) 2586 1.1.1.3 mrg { 2587 1.1.1.3 mrg fd = fd->toParent2 ()->isFuncDeclaration (); 2588 1.1.1.3 mrg continue; 2589 1.1 mrg } 2590 1.1.1.3 mrg 2591 1.1.1.3 mrg fd = NULL; 2592 1.1 mrg } 2593 1.1 mrg 2594 1.1 mrg return NULL_TREE; 2595 1.1 mrg } 2596 1.1 mrg 2597 1.1.1.3 mrg /* Retrieve the outer class/struct `this' value of DECL from 2598 1.1 mrg the current function. */ 2599 1.1 mrg 2600 1.1 mrg tree 2601 1.1 mrg build_vthis (AggregateDeclaration *decl) 2602 1.1 mrg { 2603 1.1 mrg ClassDeclaration *cd = decl->isClassDeclaration (); 2604 1.1 mrg StructDeclaration *sd = decl->isStructDeclaration (); 2605 1.1 mrg 2606 1.1 mrg /* If an aggregate nested in a function has no methods and there are no 2607 1.1 mrg other nested functions, any static chain created here will never be 2608 1.1 mrg translated. Use a null pointer for the link in this case. */ 2609 1.1 mrg tree vthis_value = null_pointer_node; 2610 1.1 mrg 2611 1.1 mrg if (cd != NULL || sd != NULL) 2612 1.1 mrg { 2613 1.1 mrg Dsymbol *outer = decl->toParent2 (); 2614 1.1 mrg 2615 1.1 mrg /* If the parent is a templated struct, the outer context is instead 2616 1.1 mrg the enclosing symbol of where the instantiation happened. */ 2617 1.1 mrg if (outer->isStructDeclaration ()) 2618 1.1 mrg { 2619 1.1 mrg gcc_assert (outer->parent && outer->parent->isTemplateInstance ()); 2620 1.1 mrg outer = ((TemplateInstance *) outer->parent)->enclosing; 2621 1.1 mrg } 2622 1.1 mrg 2623 1.1.1.3 mrg /* For outer classes, get a suitable `this' value. 2624 1.1 mrg For outer functions, get a suitable frame/closure pointer. */ 2625 1.1 mrg ClassDeclaration *cdo = outer->isClassDeclaration (); 2626 1.1 mrg FuncDeclaration *fdo = outer->isFuncDeclaration (); 2627 1.1 mrg 2628 1.1 mrg if (cdo) 2629 1.1 mrg { 2630 1.1 mrg vthis_value = find_this_tree (cdo); 2631 1.1 mrg gcc_assert (vthis_value != NULL_TREE); 2632 1.1 mrg } 2633 1.1 mrg else if (fdo) 2634 1.1 mrg { 2635 1.1 mrg tree ffo = get_frameinfo (fdo); 2636 1.1 mrg if (FRAMEINFO_CREATES_FRAME (ffo) || FRAMEINFO_STATIC_CHAIN (ffo) 2637 1.1 mrg || fdo->hasNestedFrameRefs ()) 2638 1.1 mrg vthis_value = get_frame_for_symbol (decl); 2639 1.1 mrg else if (cd != NULL) 2640 1.1 mrg { 2641 1.1 mrg /* Classes nested in methods are allowed to access any outer 2642 1.1 mrg class fields, use the function chain in this case. */ 2643 1.1 mrg if (fdo->vthis && fdo->vthis->type != Type::tvoidptr) 2644 1.1 mrg vthis_value = get_decl_tree (fdo->vthis); 2645 1.1 mrg } 2646 1.1 mrg } 2647 1.1 mrg else 2648 1.1 mrg gcc_unreachable (); 2649 1.1 mrg } 2650 1.1 mrg 2651 1.1 mrg return vthis_value; 2652 1.1 mrg } 2653 1.1 mrg 2654 1.1 mrg /* Build the RECORD_TYPE that describes the function frame or closure type for 2655 1.1 mrg the function FD. FFI is the tree holding all frame information. */ 2656 1.1 mrg 2657 1.1 mrg static tree 2658 1.1 mrg build_frame_type (tree ffi, FuncDeclaration *fd) 2659 1.1 mrg { 2660 1.1 mrg if (FRAMEINFO_TYPE (ffi)) 2661 1.1 mrg return FRAMEINFO_TYPE (ffi); 2662 1.1 mrg 2663 1.1 mrg tree frame_rec_type = make_node (RECORD_TYPE); 2664 1.1 mrg char *name = concat (FRAMEINFO_IS_CLOSURE (ffi) ? "CLOSURE." : "FRAME.", 2665 1.1 mrg fd->toPrettyChars (), NULL); 2666 1.1 mrg TYPE_NAME (frame_rec_type) = get_identifier (name); 2667 1.1 mrg free (name); 2668 1.1 mrg 2669 1.1 mrg tree fields = NULL_TREE; 2670 1.1 mrg 2671 1.1 mrg /* Function is a member or nested, so must have field for outer context. */ 2672 1.1 mrg if (fd->vthis) 2673 1.1 mrg { 2674 1.1 mrg tree ptr_field = build_decl (BUILTINS_LOCATION, FIELD_DECL, 2675 1.1 mrg get_identifier ("__chain"), ptr_type_node); 2676 1.1 mrg DECL_FIELD_CONTEXT (ptr_field) = frame_rec_type; 2677 1.1 mrg fields = chainon (NULL_TREE, ptr_field); 2678 1.1 mrg DECL_NONADDRESSABLE_P (ptr_field) = 1; 2679 1.1 mrg } 2680 1.1 mrg 2681 1.1 mrg /* The __ensure and __require are called directly, so never make the outer 2682 1.1 mrg functions closure, but nevertheless could still be referencing parameters 2683 1.1 mrg of the calling function non-locally. So we add all parameters with nested 2684 1.1 mrg refs to the function frame, this should also mean overriding methods will 2685 1.1 mrg have the same frame layout when inheriting a contract. */ 2686 1.1.1.3 mrg if ((global.params.useIn == CHECKENABLEon && fd->frequire) 2687 1.1.1.3 mrg || (global.params.useOut == CHECKENABLEon && fd->fensure)) 2688 1.1 mrg { 2689 1.1 mrg if (fd->parameters) 2690 1.1 mrg { 2691 1.1.1.3 mrg for (size_t i = 0; fd->parameters && i < fd->parameters->length; i++) 2692 1.1 mrg { 2693 1.1 mrg VarDeclaration *v = (*fd->parameters)[i]; 2694 1.1 mrg /* Remove if already in closureVars so can push to front. */ 2695 1.1.1.3 mrg size_t j = fd->closureVars.find (v); 2696 1.1.1.3 mrg 2697 1.1.1.3 mrg if (j < fd->closureVars.length) 2698 1.1.1.3 mrg fd->closureVars.remove (j); 2699 1.1.1.3 mrg 2700 1.1 mrg fd->closureVars.insert (i, v); 2701 1.1 mrg } 2702 1.1 mrg } 2703 1.1 mrg 2704 1.1.1.3 mrg /* Also add hidden `this' to outer context. */ 2705 1.1 mrg if (fd->vthis) 2706 1.1 mrg { 2707 1.1.1.3 mrg size_t i = fd->closureVars.find (fd->vthis); 2708 1.1.1.3 mrg 2709 1.1.1.3 mrg if (i < fd->closureVars.length) 2710 1.1.1.3 mrg fd->closureVars.remove (i); 2711 1.1.1.3 mrg 2712 1.1 mrg fd->closureVars.insert (0, fd->vthis); 2713 1.1 mrg } 2714 1.1 mrg } 2715 1.1 mrg 2716 1.1.1.3 mrg for (size_t i = 0; i < fd->closureVars.length; i++) 2717 1.1 mrg { 2718 1.1 mrg VarDeclaration *v = fd->closureVars[i]; 2719 1.1 mrg tree vsym = get_symbol_decl (v); 2720 1.1 mrg tree ident = v->ident 2721 1.1 mrg ? get_identifier (v->ident->toChars ()) : NULL_TREE; 2722 1.1 mrg 2723 1.1 mrg tree field = build_decl (make_location_t (v->loc), FIELD_DECL, ident, 2724 1.1 mrg TREE_TYPE (vsym)); 2725 1.1 mrg SET_DECL_LANG_FRAME_FIELD (vsym, field); 2726 1.1 mrg DECL_FIELD_CONTEXT (field) = frame_rec_type; 2727 1.1 mrg fields = chainon (fields, field); 2728 1.1 mrg TREE_USED (vsym) = 1; 2729 1.1 mrg 2730 1.1 mrg TREE_ADDRESSABLE (field) = TREE_ADDRESSABLE (vsym); 2731 1.1 mrg DECL_NONADDRESSABLE_P (field) = !TREE_ADDRESSABLE (vsym); 2732 1.1 mrg TREE_THIS_VOLATILE (field) = TREE_THIS_VOLATILE (vsym); 2733 1.1.1.3 mrg SET_DECL_ALIGN (field, DECL_ALIGN (vsym)); 2734 1.1 mrg 2735 1.1.1.3 mrg /* Update alignment for frame record type. */ 2736 1.1.1.3 mrg if (TYPE_ALIGN (frame_rec_type) < DECL_ALIGN (field)) 2737 1.1.1.3 mrg SET_TYPE_ALIGN (frame_rec_type, DECL_ALIGN (field)); 2738 1.1.1.3 mrg 2739 1.1.1.3 mrg if (DECL_LANG_NRVO (vsym)) 2740 1.1.1.3 mrg { 2741 1.1.1.3 mrg /* Store the nrvo variable in the frame by reference. */ 2742 1.1.1.3 mrg TREE_TYPE (field) = build_reference_type (TREE_TYPE (field)); 2743 1.1.1.3 mrg 2744 1.1.1.3 mrg /* Can't do nrvo if the variable is put in a closure, since what the 2745 1.1.1.3 mrg return slot points to may no longer exist. */ 2746 1.1.1.3 mrg gcc_assert (!FRAMEINFO_IS_CLOSURE (ffi)); 2747 1.1.1.3 mrg } 2748 1.1 mrg 2749 1.1 mrg if (FRAMEINFO_IS_CLOSURE (ffi)) 2750 1.1 mrg { 2751 1.1 mrg /* Because the value needs to survive the end of the scope. */ 2752 1.1 mrg if ((v->edtor && (v->storage_class & STCparameter)) 2753 1.1 mrg || v->needsScopeDtor ()) 2754 1.1 mrg error_at (make_location_t (v->loc), 2755 1.1 mrg "has scoped destruction, cannot build closure"); 2756 1.1 mrg } 2757 1.1 mrg } 2758 1.1 mrg 2759 1.1 mrg TYPE_FIELDS (frame_rec_type) = fields; 2760 1.1 mrg TYPE_READONLY (frame_rec_type) = 1; 2761 1.1.1.3 mrg TYPE_CXX_ODR_P (frame_rec_type) = 1; 2762 1.1 mrg layout_type (frame_rec_type); 2763 1.1 mrg d_keep (frame_rec_type); 2764 1.1 mrg 2765 1.1 mrg return frame_rec_type; 2766 1.1 mrg } 2767 1.1 mrg 2768 1.1 mrg /* Closures are implemented by taking the local variables that 2769 1.1 mrg need to survive the scope of the function, and copying them 2770 1.1 mrg into a GC allocated chuck of memory. That chunk, called the 2771 1.1 mrg closure here, is inserted into the linked list of stack 2772 1.1 mrg frames instead of the usual stack frame. 2773 1.1 mrg 2774 1.1 mrg If a closure is not required, but FD still needs a frame to lower 2775 1.1 mrg nested refs, then instead build custom static chain decl on stack. */ 2776 1.1 mrg 2777 1.1 mrg void 2778 1.1 mrg build_closure (FuncDeclaration *fd) 2779 1.1 mrg { 2780 1.1 mrg tree ffi = get_frameinfo (fd); 2781 1.1 mrg 2782 1.1 mrg if (!FRAMEINFO_CREATES_FRAME (ffi)) 2783 1.1 mrg return; 2784 1.1 mrg 2785 1.1 mrg tree type = FRAMEINFO_TYPE (ffi); 2786 1.1 mrg gcc_assert (COMPLETE_TYPE_P (type)); 2787 1.1 mrg 2788 1.1 mrg tree decl, decl_ref; 2789 1.1 mrg 2790 1.1 mrg if (FRAMEINFO_IS_CLOSURE (ffi)) 2791 1.1 mrg { 2792 1.1 mrg decl = build_local_temp (build_pointer_type (type)); 2793 1.1 mrg DECL_NAME (decl) = get_identifier ("__closptr"); 2794 1.1 mrg decl_ref = build_deref (decl); 2795 1.1 mrg 2796 1.1 mrg /* Allocate memory for closure. */ 2797 1.1 mrg tree arg = convert (build_ctype (Type::tsize_t), TYPE_SIZE_UNIT (type)); 2798 1.1 mrg tree init = build_libcall (LIBCALL_ALLOCMEMORY, Type::tvoidptr, 1, arg); 2799 1.1 mrg 2800 1.1 mrg tree init_exp = build_assign (INIT_EXPR, decl, 2801 1.1 mrg build_nop (TREE_TYPE (decl), init)); 2802 1.1 mrg add_stmt (init_exp); 2803 1.1 mrg } 2804 1.1 mrg else 2805 1.1 mrg { 2806 1.1 mrg decl = build_local_temp (type); 2807 1.1 mrg DECL_NAME (decl) = get_identifier ("__frame"); 2808 1.1 mrg decl_ref = decl; 2809 1.1 mrg } 2810 1.1 mrg 2811 1.1 mrg /* Set the first entry to the parent closure/frame, if any. */ 2812 1.1 mrg if (fd->vthis) 2813 1.1 mrg { 2814 1.1 mrg tree chain_field = component_ref (decl_ref, TYPE_FIELDS (type)); 2815 1.1 mrg tree chain_expr = modify_expr (chain_field, 2816 1.1 mrg d_function_chain->static_chain); 2817 1.1 mrg add_stmt (chain_expr); 2818 1.1 mrg } 2819 1.1 mrg 2820 1.1 mrg /* Copy parameters that are referenced nonlocally. */ 2821 1.1.1.3 mrg for (size_t i = 0; i < fd->closureVars.length; i++) 2822 1.1 mrg { 2823 1.1 mrg VarDeclaration *v = fd->closureVars[i]; 2824 1.1.1.3 mrg tree vsym = get_symbol_decl (v); 2825 1.1 mrg 2826 1.1.1.3 mrg if (TREE_CODE (vsym) != PARM_DECL && !DECL_LANG_NRVO (vsym)) 2827 1.1 mrg continue; 2828 1.1 mrg 2829 1.1 mrg tree field = component_ref (decl_ref, DECL_LANG_FRAME_FIELD (vsym)); 2830 1.1.1.3 mrg 2831 1.1.1.3 mrg /* Variable is an alias for the NRVO slot, store the reference. */ 2832 1.1.1.3 mrg if (DECL_LANG_NRVO (vsym)) 2833 1.1.1.3 mrg vsym = build_address (DECL_LANG_NRVO (vsym)); 2834 1.1.1.3 mrg 2835 1.1 mrg tree expr = modify_expr (field, vsym); 2836 1.1 mrg add_stmt (expr); 2837 1.1 mrg } 2838 1.1 mrg 2839 1.1 mrg if (!FRAMEINFO_IS_CLOSURE (ffi)) 2840 1.1 mrg decl = build_address (decl); 2841 1.1 mrg 2842 1.1 mrg d_function_chain->static_chain = decl; 2843 1.1 mrg } 2844 1.1 mrg 2845 1.1 mrg /* Return the frame of FD. This could be a static chain or a closure 2846 1.1.1.3 mrg passed via the hidden `this' pointer. */ 2847 1.1 mrg 2848 1.1 mrg tree 2849 1.1 mrg get_frameinfo (FuncDeclaration *fd) 2850 1.1 mrg { 2851 1.1 mrg tree fds = get_symbol_decl (fd); 2852 1.1 mrg if (DECL_LANG_FRAMEINFO (fds)) 2853 1.1 mrg return DECL_LANG_FRAMEINFO (fds); 2854 1.1 mrg 2855 1.1 mrg tree ffi = make_node (FUNCFRAME_INFO); 2856 1.1 mrg 2857 1.1 mrg DECL_LANG_FRAMEINFO (fds) = ffi; 2858 1.1 mrg 2859 1.1 mrg if (fd->needsClosure ()) 2860 1.1 mrg { 2861 1.1 mrg /* Set-up a closure frame, this will be allocated on the heap. */ 2862 1.1 mrg FRAMEINFO_CREATES_FRAME (ffi) = 1; 2863 1.1 mrg FRAMEINFO_IS_CLOSURE (ffi) = 1; 2864 1.1 mrg } 2865 1.1 mrg else if (fd->hasNestedFrameRefs ()) 2866 1.1 mrg { 2867 1.1 mrg /* Functions with nested refs must create a static frame for local 2868 1.1 mrg variables to be referenced from. */ 2869 1.1 mrg FRAMEINFO_CREATES_FRAME (ffi) = 1; 2870 1.1 mrg } 2871 1.1 mrg else 2872 1.1 mrg { 2873 1.1 mrg /* For nested functions, default to creating a frame. Even if there are 2874 1.1 mrg no fields to populate the frame, create it anyway, as this will be 2875 1.1 mrg used as the record type instead of `void*` for the this parameter. */ 2876 1.1 mrg if (fd->vthis && fd->vthis->type == Type::tvoidptr) 2877 1.1 mrg FRAMEINFO_CREATES_FRAME (ffi) = 1; 2878 1.1 mrg 2879 1.1 mrg /* In checkNestedReference, references from contracts are not added to the 2880 1.1 mrg closureVars array, so assume all parameters referenced. */ 2881 1.1.1.3 mrg if ((global.params.useIn == CHECKENABLEon && fd->frequire) 2882 1.1.1.3 mrg || (global.params.useOut == CHECKENABLEon && fd->fensure)) 2883 1.1 mrg FRAMEINFO_CREATES_FRAME (ffi) = 1; 2884 1.1 mrg 2885 1.1 mrg /* If however `fd` is nested (deeply) in a function that creates a 2886 1.1 mrg closure, then `fd` instead inherits that closure via hidden vthis 2887 1.1 mrg pointer, and doesn't create a stack frame at all. */ 2888 1.1 mrg FuncDeclaration *ff = fd; 2889 1.1 mrg 2890 1.1 mrg while (ff) 2891 1.1 mrg { 2892 1.1 mrg tree ffo = get_frameinfo (ff); 2893 1.1 mrg 2894 1.1 mrg if (ff != fd && FRAMEINFO_CREATES_FRAME (ffo)) 2895 1.1 mrg { 2896 1.1 mrg gcc_assert (FRAMEINFO_TYPE (ffo)); 2897 1.1 mrg FRAMEINFO_CREATES_FRAME (ffi) = 0; 2898 1.1 mrg FRAMEINFO_STATIC_CHAIN (ffi) = 1; 2899 1.1 mrg FRAMEINFO_IS_CLOSURE (ffi) = FRAMEINFO_IS_CLOSURE (ffo); 2900 1.1 mrg gcc_assert (COMPLETE_TYPE_P (FRAMEINFO_TYPE (ffo))); 2901 1.1 mrg FRAMEINFO_TYPE (ffi) = FRAMEINFO_TYPE (ffo); 2902 1.1 mrg break; 2903 1.1 mrg } 2904 1.1 mrg 2905 1.1 mrg /* Stop looking if no frame pointer for this function. */ 2906 1.1 mrg if (ff->vthis == NULL) 2907 1.1 mrg break; 2908 1.1 mrg 2909 1.1 mrg AggregateDeclaration *ad = ff->isThis (); 2910 1.1 mrg if (ad && ad->isNested ()) 2911 1.1 mrg { 2912 1.1 mrg while (ad->isNested ()) 2913 1.1 mrg { 2914 1.1 mrg Dsymbol *d = ad->toParent2 (); 2915 1.1 mrg ad = d->isAggregateDeclaration (); 2916 1.1 mrg ff = d->isFuncDeclaration (); 2917 1.1 mrg 2918 1.1 mrg if (ad == NULL) 2919 1.1 mrg break; 2920 1.1 mrg } 2921 1.1 mrg } 2922 1.1 mrg else 2923 1.1 mrg ff = ff->toParent2 ()->isFuncDeclaration (); 2924 1.1 mrg } 2925 1.1 mrg } 2926 1.1 mrg 2927 1.1 mrg /* Build type now as may be referenced from another module. */ 2928 1.1 mrg if (FRAMEINFO_CREATES_FRAME (ffi)) 2929 1.1 mrg FRAMEINFO_TYPE (ffi) = build_frame_type (ffi, fd); 2930 1.1 mrg 2931 1.1 mrg return ffi; 2932 1.1 mrg } 2933 1.1 mrg 2934 1.1 mrg /* Return a pointer to the frame/closure block of OUTER 2935 1.1 mrg so can be accessed from the function INNER. */ 2936 1.1 mrg 2937 1.1 mrg tree 2938 1.1 mrg get_framedecl (FuncDeclaration *inner, FuncDeclaration *outer) 2939 1.1 mrg { 2940 1.1 mrg tree result = d_function_chain->static_chain; 2941 1.1 mrg FuncDeclaration *fd = inner; 2942 1.1 mrg 2943 1.1 mrg while (fd && fd != outer) 2944 1.1 mrg { 2945 1.1 mrg /* Parent frame link is the first field. */ 2946 1.1 mrg if (FRAMEINFO_CREATES_FRAME (get_frameinfo (fd))) 2947 1.1 mrg result = indirect_ref (ptr_type_node, result); 2948 1.1 mrg 2949 1.1 mrg if (fd->isNested ()) 2950 1.1 mrg fd = fd->toParent2 ()->isFuncDeclaration (); 2951 1.1 mrg /* The frame/closure record always points to the outer function's 2952 1.1 mrg frame, even if there are intervening nested classes or structs. 2953 1.1 mrg So, we can just skip over these. */ 2954 1.1 mrg else 2955 1.1.1.3 mrg fd = get_outer_function (fd->isThis ()); 2956 1.1 mrg } 2957 1.1 mrg 2958 1.1.1.2 mrg if (fd != outer) 2959 1.1.1.2 mrg return error_no_frame_access (outer); 2960 1.1.1.2 mrg 2961 1.1 mrg /* Go get our frame record. */ 2962 1.1 mrg tree frame_type = FRAMEINFO_TYPE (get_frameinfo (outer)); 2963 1.1 mrg 2964 1.1 mrg if (frame_type != NULL_TREE) 2965 1.1 mrg { 2966 1.1 mrg result = build_nop (build_pointer_type (frame_type), result); 2967 1.1 mrg return result; 2968 1.1 mrg } 2969 1.1 mrg else 2970 1.1 mrg { 2971 1.1 mrg error_at (make_location_t (inner->loc), 2972 1.1 mrg "forward reference to frame of %qs", outer->toChars ()); 2973 1.1 mrg return null_pointer_node; 2974 1.1 mrg } 2975 1.1 mrg } 2976