FreeBSD/contrib/gcc/cp/decl.c
/* DECL is a VAR_DECL with static storage duration.  INIT, if present,
   is its initializer.  Generate code to handle the construction
   and destruction of DECL.  */
DECL is a VAR_DECL with static storage duration.  INIT, if present,
is its initializer.  Generate code to handle the construction
and destruction of DECL.
DECL is a VAR_DECL with static storage duration . INIT if present is its initializer . Generate code to handle the construction and destruction of DECL .
static void
expand_static_init (tree decl, tree init)
{
  gcc_assert (TREE_CODE (decl) == VAR_DECL);
  gcc_assert (TREE_STATIC (decl));
  if (!init
      && !TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl))
      && TYPE_HAS_TRIVIAL_DESTRUCTOR (TREE_TYPE (decl)))
    return;
  if (c_dialect_objc () && flag_objc_gc && init && TREE_CODE (init) == INIT_EXPR)
  {
    tree result = objc_generate_write_barrier (TREE_OPERAND (init, 0),
					        INIT_EXPR, TREE_OPERAND (init, 1));
    if (result)
      init = result;
  }
  if (DECL_FUNCTION_SCOPE_P (decl))
    {
      tree if_stmt = NULL_TREE, inner_if_stmt = NULL_TREE;
      tree then_clause = NULL_TREE, inner_then_clause = NULL_TREE;
      tree guard, guard_addr, guard_addr_list;
      tree acquire_fn, release_fn, abort_fn;
      tree flag, begin;
      guard = get_guard (decl);
      if (!targetm.relaxed_ordering || !flag_threadsafe_statics)
	{
	  if_stmt = begin_if_stmt ();
	  finish_if_stmt_cond (get_guard_cond (guard), if_stmt);
	  then_clause = begin_compound_stmt (BCS_NO_SCOPE);
	}
      if (flag_threadsafe_statics)
	{
	  guard_addr = build_address (guard);
	  guard_addr_list = build_tree_list (NULL_TREE, guard_addr);
	  acquire_fn = get_identifier ("__cxa_guard_acquire");
	  release_fn = get_identifier ("__cxa_guard_release");
	  abort_fn = get_identifier ("__cxa_guard_abort");
	  if (!get_global_value_if_present (acquire_fn, &acquire_fn))
	    {
	      tree argtypes = tree_cons (NULL_TREE, TREE_TYPE (guard_addr),
					 void_list_node);
	      tree vfntype = build_function_type (void_type_node, argtypes);
	      acquire_fn = push_library_fn
		(acquire_fn, build_function_type (integer_type_node, argtypes));
	      release_fn = push_library_fn (release_fn, vfntype);
	      abort_fn = push_library_fn (abort_fn, vfntype);
	    }
	  else
	    {
	      release_fn = identifier_global_value (release_fn);
	      abort_fn = identifier_global_value (abort_fn);
	    }
	  inner_if_stmt = begin_if_stmt ();
	  finish_if_stmt_cond (build_call (acquire_fn, guard_addr_list),
			       inner_if_stmt);
	  inner_then_clause = begin_compound_stmt (BCS_NO_SCOPE);
	  begin = get_target_expr (boolean_false_node);
	  flag = TARGET_EXPR_SLOT (begin);
	  TARGET_EXPR_CLEANUP (begin)
	    = build3 (COND_EXPR, void_type_node, flag,
		      void_zero_node,
		      build_call (abort_fn, guard_addr_list));
	  CLEANUP_EH_ONLY (begin) = 1;
	  init = add_stmt_to_compound (begin, init);
	  init = add_stmt_to_compound
	    (init, build2 (MODIFY_EXPR, void_type_node, flag, boolean_true_node));
	  init = add_stmt_to_compound
	    (init, build_call (release_fn, guard_addr_list));
	}
      else
	init = add_stmt_to_compound (init, set_guard (guard));
      init = add_stmt_to_compound (init, register_dtor_fn (decl));
      finish_expr_stmt (init);
      if (flag_threadsafe_statics)
	{
	  finish_compound_stmt (inner_then_clause);
	  finish_then_clause (inner_if_stmt);
	  finish_if_stmt (inner_if_stmt);
	}
      if (!targetm.relaxed_ordering || !flag_threadsafe_statics)
	{
	  finish_compound_stmt (then_clause);
	  finish_then_clause (if_stmt);
	  finish_if_stmt (if_stmt);
	}
    }
  else
    static_aggregates = tree_cons (init, decl, static_aggregates);
}
static void expand_static_init ( tree decl , tree init ) { gcc_assert ( TREE_CODE ( decl ) == VAR_DECL ) ; gcc_assert ( TREE_STATIC ( decl ) ) ; if ( ! init && ! TYPE_NEEDS_CONSTRUCTING ( TREE_TYPE ( decl ) ) && TYPE_HAS_TRIVIAL_DESTRUCTOR ( TREE_TYPE ( decl ) ) ) return ; if ( c_dialect_objc ( ) && flag_objc_gc && init && TREE_CODE ( init ) == INIT_EXPR ) { tree result = objc_generate_write_barrier ( TREE_OPERAND ( init , 0 ) , INIT_EXPR , TREE_OPERAND ( init , 1 ) ) ; if ( result ) init = result ; } if ( DECL_FUNCTION_SCOPE_P ( decl ) ) { tree if_stmt = NULL_TREE , inner_if_stmt = NULL_TREE ; tree then_clause = NULL_TREE , inner_then_clause = NULL_TREE ; tree guard , guard_addr , guard_addr_list ; tree acquire_fn , release_fn , abort_fn ; tree flag , begin ; guard = get_guard ( decl ) ; if ( ! targetm . relaxed_ordering || ! flag_threadsafe_statics ) { if_stmt = begin_if_stmt ( ) ; finish_if_stmt_cond ( get_guard_cond ( guard ) , if_stmt ) ; then_clause = begin_compound_stmt ( BCS_NO_SCOPE ) ; } if ( flag_threadsafe_statics ) { guard_addr = build_address ( guard ) ; guard_addr_list = build_tree_list ( NULL_TREE , guard_addr ) ; acquire_fn = get_identifier ( " " ) ; release_fn = get_identifier ( " " ) ; abort_fn = get_identifier ( " " ) ; if ( ! get_global_value_if_present ( acquire_fn , & acquire_fn ) ) { tree argtypes = tree_cons ( NULL_TREE , TREE_TYPE ( guard_addr ) , void_list_node ) ; tree vfntype = build_function_type ( void_type_node , argtypes ) ; acquire_fn = push_library_fn ( acquire_fn , build_function_type ( integer_type_node , argtypes ) ) ; release_fn = push_library_fn ( release_fn , vfntype ) ; abort_fn = push_library_fn ( abort_fn , vfntype ) ; } else { release_fn = identifier_global_value ( release_fn ) ; abort_fn = identifier_global_value ( abort_fn ) ; } inner_if_stmt = begin_if_stmt ( ) ; finish_if_stmt_cond ( build_call ( acquire_fn , guard_addr_list ) , inner_if_stmt ) ; inner_then_clause = begin_compound_stmt ( BCS_NO_SCOPE ) ; begin = get_target_expr ( boolean_false_node ) ; flag = TARGET_EXPR_SLOT ( begin ) ; TARGET_EXPR_CLEANUP ( begin ) = build3 ( COND_EXPR , void_type_node , flag , void_zero_node , build_call ( abort_fn , guard_addr_list ) ) ; CLEANUP_EH_ONLY ( begin ) = 1 ; init = add_stmt_to_compound ( begin , init ) ; init = add_stmt_to_compound ( init , build2 ( MODIFY_EXPR , void_type_node , flag , boolean_true_node ) ) ; init = add_stmt_to_compound ( init , build_call ( release_fn , guard_addr_list ) ) ; } else init = add_stmt_to_compound ( init , set_guard ( guard ) ) ; init = add_stmt_to_compound ( init , register_dtor_fn ( decl ) ) ; finish_expr_stmt ( init ) ; if ( flag_threadsafe_statics ) { finish_compound_stmt ( inner_then_clause ) ; finish_then_clause ( inner_if_stmt ) ; finish_if_stmt ( inner_if_stmt ) ; } if ( ! targetm . relaxed_ordering || ! flag_threadsafe_statics ) { finish_compound_stmt ( then_clause ) ; finish_then_clause ( if_stmt ) ; finish_if_stmt ( if_stmt ) ; } } else static_aggregates = tree_cons ( init , decl , static_aggregates ) ; }
DECL is a VAR_DECL with static storage duration.
DECL is a VAR_DECL with static storage duration .
/* Some variables require no initialization.  */ /* APPLE LOCAL begin radar 5733674 */ /* APPLE LOCAL end radar 5733674 */ /* Emit code to perform this initialization but once.  */ /* Emit code to perform this initialization but once.  This code
	 looks like:

	   static <type> guard;
	   if (!guard.first_byte) {
	     if (__cxa_guard_acquire (&guard)) {
	       bool flag = false;
	       try {
		 // Do initialization.
		 flag = true; __cxa_guard_release (&guard);
		 // Register variable for destruction at end of program.
	       } catch {
		 if (!flag) __cxa_guard_abort (&guard);
	       }
	   }

	 Note that the `flag' variable is only set to 1 *after* the
	 initialization is complete.  This ensures that an exception,
	 thrown during the construction, will cause the variable to
	 reinitialized when we pass through this code again, as per:

	   [stmt.dcl]

	   If the initialization exits by throwing an exception, the
	   initialization is not complete, so it will be tried again
	   the next time control enters the declaration.

	 This process should be thread-safe, too; multiple threads
	 should not be able to initialize the variable more than
	 once.  */ /* Create the guard variable.  */ /* This optimization isn't safe on targets with relaxed memory
	 consistency.  On such targets we force synchronization in
	 __cxa_guard_acquire.  */ /* Begin the conditional initialization.  */ /* Do the initialization itself.  */ /* Use atexit to register a function for destroying this static
	 variable.  */