build1 is same as build, but only builds for unary operators. Saves lion share of calls to build; cuts down use of varargs, which is expensive for RISC machines.
2411 tree
2412 build1 (enum tree_code code, tree type, tree node) in tree.c
2413 {
2414 int length = sizeof (struct tree_exp);
2415 #ifdef GATHER_STATISTICS
2416 tree_node_kind kind;
2417 #endif
2418 tree t;
2419
2420 #ifdef GATHER_STATISTICS
2421 switch (TREE_CODE_CLASS (code))
2422 {
2423 case 's': /* an expression with side effects */
2424 kind = s_kind;
2425 break;
2426 case 'r': /* a reference */
2427 kind = r_kind;
2428 break;
2429 default:
2430 kind = e_kind;
2431 break;
2432 }
2433
2434 tree_node_counts[(int) kind]++;
2435 tree_node_sizes[(int) kind] += length;
2436 #endif
2437
2438 #ifdef ENABLE_CHECKING
2439 if (TREE_CODE_CLASS (code) == '2'
2440 || TREE_CODE_CLASS (code) == '<'
2441 || TREE_CODE_LENGTH (code) != 1)
2442 abort ();
2443 #endif /* ENABLE_CHECKING */
2444
2445 t = ggc_alloc_tree (length);
2446
2447 memset (t, 0, sizeof (struct tree_common));
2448
2449 TREE_SET_CODE (t, code);
2450
2451 TREE_TYPE (t) = type;
2452 TREE_COMPLEXITY (t) = 0;
2453 TREE_OPERAND (t, 0) = node;
2454 if (node && first_rtl_op (code) != 0)
2455 {
2456 TREE_SIDE_EFFECTS (t) = TREE_SIDE_EFFECTS (node);
2457 TREE_READONLY (t) = TREE_READONLY (node);
2458 }
2459
2460 if (TREE_CODE_CLASS (code) == 's')
2461 TREE_SIDE_EFFECTS (t) = 1;
2462 else switch (code)
2463 {
2464 case INIT_EXPR:
2465 case MODIFY_EXPR:
2466 case VA_ARG_EXPR:
2467 case RTL_EXPR:
2468 case PREDECREMENT_EXPR:
2469 case PREINCREMENT_EXPR:
2470 case POSTDECREMENT_EXPR:
2471 case POSTINCREMENT_EXPR:
2472 /* All of these have side-effects, no matter what their
2473 operands are. */
2474 TREE_SIDE_EFFECTS (t) = 1;
2475 TREE_READONLY (t) = 0;
2476 break;
2477
2478 case INDIRECT_REF:
2479 /* Whether a dereference is readonly has nothing to do with whether
2480 its operand is readonly. */
2481 TREE_READONLY (t) = 0;
2482 break;
2483
2484 case ADDR_EXPR:
2485 if (node)
2486 {
2487 /* The address of a volatile decl or reference does not have
2488 side-effects. But be careful not to ignore side-effects from
2489 other sources deeper in the expression--if node is a _REF and
2490 one of its operands has side-effects, so do we. */
2491 if (TREE_THIS_VOLATILE (node))
2492 {
2493 TREE_SIDE_EFFECTS (t) = 0;
2494 if (!DECL_P (node))
2495 {
2496 int i = first_rtl_op (TREE_CODE (node)) - 1;
2497 for (; i >= 0; --i)
2498 {
2499 if (TREE_SIDE_EFFECTS (TREE_OPERAND (node, i)))
2500 TREE_SIDE_EFFECTS (t) = 1;
2501 }
2502 }
2503 }
2504 }
2505 break;
2506
2507 default:
2508 if (TREE_CODE_CLASS (code) == '1' && node && TREE_CONSTANT (node))
2509 TREE_CONSTANT (t) = 1;
2510 break;
2511 }
2512
2513 return t;
2514 }
Above at line 2460, code class of ‘s’ means statement with side-effects, but usually no interesting value.
Routine build_decl is the function to create object of tree_decl - the node for declarations. Pay attention to line 2565 below, in object file, function definition will be placed within text section. And its invocation will be compiled into a jump instruction and related stack or registers operation. It acts like a pointer, so function mode (FUNCTION_MODE) corresponding to the function declaration, on target machines, usually is the same mode as pointer.
2547 tree
2548 build_decl (enum tree_code code, tree name, tree type) in tree.c
2549 {
2550 tree t;
2551
2552 t = make_node (code);
2553
2554 /* if (type == error_mark_node)
2555 type = integer_type_node; */
2556 /* That is not done, deliberately, so that having error_mark_node
2557 as the type can suppress useless errors in the use of this variable. */
2558
2559 DECL_NAME (t) = name;
2560 TREE_TYPE (t) = type;
2561
2562 if (code == VAR_DECL || code == PARM_DECL || code == RESULT_DECL)
2563 layout_decl (t, 0);
2564 else if (code == FUNCTION_DECL)
2565 DECL_MODE (t) = FUNCTION_MODE;
2566
2567 return t;
2568 }
In above, for VAR_DECL, PARM_DECL and RESULT_DECL special treatment is required. So first we see what are PARM_DECL and RESULT_DECL.
PARM_DECL[2]
² Used to represent a parameter to a function. Treat these nodes similarly to VAR_DECL nodes. These nodes only appear in the DECL_ARGUMENTS for a FUNCTION_DECL. The DECL_ARG_TYPE for a PARM_DECL is the type that will actually be used when a value is passed to this function. It may be a wider type than the TREE_TYPE of the parameter; for example, the ordinary type might be short while the DECL_ARG_TYPE is int.
RESULT_DECL[2]
² These nodes represent the value returned by a function. When a value is assigned to a RESULT_DECL, that indicates that the value should be returned, via bitwise copy, by the function. You can use DECL_SIZE and DECL_ALIGN on a RESULT_DECL, just as with a VAR_DECL.
For VAR_DECL, PARM_DECL and RESULT_DECL, they need set inforamtion of size, mode and alignment in the nodes.
352 void
353 layout_decl (tree decl, unsigned int known_align) in stor-layout.c
354 {
355 tree type = TREE_TYPE (decl);
356 enum tree_code code = TREE_CODE (decl);
357 rtx rtl = NULL_RTX;
358
359 if (code == CONST_DECL)
360 return;
361 else if (code != VAR_DECL && code != PARM_DECL && code != RESULT_DECL
362 && code != TYPE_DECL && code != FIELD_DECL)
363 abort ();
364
365 rtl = DECL_RTL_IF_SET (decl);
366
367 if (type == error_mark_node)
368 type = void_type_node;
369
370 /* Usually the size and mode come from the data type without change,
371 however, the front-end may set the explicit width of the field, so its
372 size may not be the same as the size of its type. This happens with
373 bitfields, of course (an `int' bitfield may be only 2 bits, say), but it
374 also happens with other fields. For example, the C++ front-end creates
375 zero-sized fields corresponding to empty base classes, and depends on
376 layout_type setting DECL_FIELD_BITPOS correctly for the field. Set the
377 size in bytes from the size in bits. If we have already set the mode,
378 don't set it again since we can be called twice for FIELD_DECLs. */
379
380 TREE_UNSIGNED (decl) = TREE_UNSIGNED (type);
381 if (DECL_MODE (decl) == VOIDmode)
382 DECL_MODE (decl) = TYPE_MODE (type);
383
384 if (DECL_SIZE (decl) == 0)
385 {
386 DECL_SIZE (decl) = TYPE_SIZE (type);
387 DECL_SIZE_UNIT (decl) = TYPE_SIZE_UNIT (type);
388 }
389 else if (DECL_SIZE_UNIT (decl) == 0)
390 DECL_SIZE_UNIT (decl)
391 = convert (sizetype, size_binop (CEIL_DIV_EXPR, DECL_SIZE (decl),
392 bitsize_unit_node));
393
394 if (code != FIELD_DECL)
395 /* For non-fields, update the alignment from the type. */
396 do_type_align (type, decl);
397 else
398 /* For fields, it's a bit more complicated... */
399 {
…
493 }
When entering from build_decl, the node of tree_decl is filled with 0 (see make_node), only the name and type fields are updated. Notice that at line 382, VOIDmode is 0. And at line 394, we should not be FIELD_DECL as we are not from layout_type. So at line 396, do_type_align forces the alignment to that of the type.
328 static inline void
329 do_type_align (tree type, tree decl) in stor-layout.c
330 {
331 if (TYPE_ALIGN (type) > DECL_ALIGN (decl))
332 {
333 DECL_ALIGN (decl) = TYPE_ALIGN (type);
334 if (TREE_CODE (decl) == FIELD_DECL)
335 DECL_USER_ALIGN (decl) = TYPE_USER_ALIGN (type);
336 }
337 }
GNU C++ has an interesting extension. It allows the deminsion of a local array being a non-constant value. For example:
void func () {
int j = 5;
int arrJ[j++];
}
It is a good code! Obviously, the size of arrJ is an expression instead of an INTEGER_CST. This size represented expression may have side-effect (here, j++ is the kind), which means can only evaluate the expression once, and later reference should be towards the cached value. In the front-end, node of SAVE_EXPR is provided for the purpose. And below routine variable_size would replace those size nodes of expression with SAVE_EXPR.
layout_decl (continue)
495 /* Evaluate nonconstant size only once, either now or as soon as safe. */
496 if (DECL_SIZE (decl) != 0 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
497 DECL_SIZE (decl) = variable_size (DECL_SIZE (decl));
498 if (DECL_SIZE_UNIT (decl) != 0
499 && TREE_CODE (DECL_SIZE_UNIT (decl)) != INTEGER_CST)
500 DECL_SIZE_UNIT (decl) = variable_size (DECL_SIZE_UNIT (decl));
501
502 /* If requested, warn about definitions of large data objects. */
503 if (warn_larger_than
504 && (code == VAR_DECL || code == PARM_DECL)
505 && ! DECL_EXTERNAL (decl))
506 {
507 tree size = DECL_SIZE_UNIT (decl);
508
509 if (size != 0 && TREE_CODE (size) == INTEGER_CST
510 && compare_tree_int (size, larger_than_size) > 0)
511 {
512 int size_as_int = TREE_INT_CST_LOW (size);
513
514 if (compare_tree_int (size, size_as_int) == 0)
515 warning ("%Jsize of '%D' is %d bytes", decl, decl, size_as_int);
516 else
517 warning ("%Jsize of '%D' is larger than %d bytes",
518 decl, decl, larger_than_size);
519 }
520 }
521
522 /* If the RTL was already set, update its mode and mem attributes. */
523 if (rtl)
524 {
525 PUT_MODE (rtl, DECL_MODE (decl));
526 SET_DECL_RTL (decl, 0);
527 set_mem_attributes (rtl, decl, 1);
528 SET_DECL_RTL (decl, rtl);
529 }
530 }
Above at line 523, rtl is the RTL node associating with the declaration node. It is only available after parsing the whole translation-unit. The node of RTL will guide the output of assemble. So if the layout of the declaration has been changed, it may affect the allocation of memory for the declaration, it must update the fields in the RTL node accordingly.