FreeBSD/contrib/gcc/c-decl.c
/**
  build_block_ref_decl - This routine inserts a copied-in variable (a variable
  referenced in the block but whose scope is outside the block) in helper
  function's outer-most scope. It also sets its type to 'const' as such
  variables are read-only.
*/
This routine inserts a copied-in variable (a variable
referenced in the block but whose scope is outside the block) in helper
function's outer-most scope. It also sets its type to 'const' as such
variables are read-only.
This routine inserts a copied - in variable ( a variable referenced in the block but whose scope is outside the block ) in helper function ' s outer - most scope . It also sets its type to ' const ' as such variables are read - only .
tree
build_block_ref_decl (tree name, tree decl)
{
  struct c_scope *scope = current_scope;
  tree ref_decl;
  tree type, exp;
  if (TREE_CODE (decl) == VAR_DECL && COPYABLE_BYREF_LOCAL_VAR (decl))
    decl = build_byref_local_var_access (decl, DECL_NAME (decl));
  else {
    if (cur_block->prev_block_info) {
      struct block_sema_info *cb = cur_block->prev_block_info;
      while (cb) {
	 struct c_binding *b = I_SYMBOL_BINDING (name);
	 while (b && b->decl
	        && (TREE_CODE (b->decl) == VAR_DECL
	            || TREE_CODE (b->decl) == PARM_DECL)
	        && b->depth >= cur_block->the_scope->depth)
	   b = b->shadowed;
	 if (b && b->decl
	     && (TREE_CODE (b->decl) == VAR_DECL
	         || TREE_CODE (b->decl) == PARM_DECL)
	     && b->depth < cb->the_scope->depth) {
	   struct c_scope *save_scope = current_scope;
	   struct block_sema_info *save_current_block = cur_block;
	   current_scope = cb->the_scope;
	   cur_block = cb;
	   decl = build_block_ref_decl (name, decl);
	   cur_block = save_current_block;
	   current_scope = save_scope;
	 }
	 cb = cb->prev_block_info;
      }
    }
  }
  exp = decl;
  type = TREE_TYPE (exp);
  if (TREE_CODE (type) == ARRAY_TYPE) {
    exp = array_to_pointer_conversion (decl);
    type = TREE_TYPE (exp);
  }
  else if (TREE_CODE (type) == FUNCTION_TYPE) {
    exp = function_to_pointer_conversion (exp);
    type = TREE_TYPE (exp);
  }
  ref_decl = build_decl (VAR_DECL, name,
	                  build_qualified_type (type, TYPE_QUAL_CONST));
  DECL_SOURCE_LOCATION (ref_decl) = DECL_SOURCE_LOCATION 
	                                        (cur_block->helper_func_decl);
  DECL_INITIAL (ref_decl) = error_mark_node;
  c_apply_type_quals_to_decl (TYPE_QUAL_CONST, ref_decl);
  BLOCK_DECL_COPIED (ref_decl) = 1;
  while (scope && !scope->function_body)
    scope = scope->outer;
  gcc_assert (scope);
  bind (name, ref_decl,
	 scope, false, false);
  cur_block->block_ref_decl_list =
    tree_cons (NULL_TREE, ref_decl, cur_block->block_ref_decl_list);
  cur_block->block_original_ref_decl_list =
    tree_cons (NULL_TREE, exp, cur_block->block_original_ref_decl_list);
  return ref_decl;
}
tree build_block_ref_decl ( tree name , tree decl ) { struct c_scope * scope = current_scope ; tree ref_decl ; tree type , exp ; if ( TREE_CODE ( decl ) == VAR_DECL && COPYABLE_BYREF_LOCAL_VAR ( decl ) ) decl = build_byref_local_var_access ( decl , DECL_NAME ( decl ) ) ; else { if ( cur_block -> prev_block_info ) { struct block_sema_info * cb = cur_block -> prev_block_info ; while ( cb ) { struct c_binding * b = I_SYMBOL_BINDING ( name ) ; while ( b && b -> decl && ( TREE_CODE ( b -> decl ) == VAR_DECL || TREE_CODE ( b -> decl ) == PARM_DECL ) && b -> depth >= cur_block -> the_scope -> depth ) b = b -> shadowed ; if ( b && b -> decl && ( TREE_CODE ( b -> decl ) == VAR_DECL || TREE_CODE ( b -> decl ) == PARM_DECL ) && b -> depth < cb -> the_scope -> depth ) { struct c_scope * save_scope = current_scope ; struct block_sema_info * save_current_block = cur_block ; current_scope = cb -> the_scope ; cur_block = cb ; decl = build_block_ref_decl ( name , decl ) ; cur_block = save_current_block ; current_scope = save_scope ; } cb = cb -> prev_block_info ; } } } exp = decl ; type = TREE_TYPE ( exp ) ; if ( TREE_CODE ( type ) == ARRAY_TYPE ) { exp = array_to_pointer_conversion ( decl ) ; type = TREE_TYPE ( exp ) ; } else if ( TREE_CODE ( type ) == FUNCTION_TYPE ) { exp = function_to_pointer_conversion ( exp ) ; type = TREE_TYPE ( exp ) ; } ref_decl = build_decl ( VAR_DECL , name , build_qualified_type ( type , TYPE_QUAL_CONST ) ) ; DECL_SOURCE_LOCATION ( ref_decl ) = DECL_SOURCE_LOCATION ( cur_block -> helper_func_decl ) ; DECL_INITIAL ( ref_decl ) = error_mark_node ; c_apply_type_quals_to_decl ( TYPE_QUAL_CONST , ref_decl ) ; BLOCK_DECL_COPIED ( ref_decl ) = 1 ; while ( scope && ! scope -> function_body ) scope = scope -> outer ; gcc_assert ( scope ) ; bind ( name , ref_decl , scope , false , false ) ; cur_block -> block_ref_decl_list = tree_cons ( NULL_TREE , ref_decl , cur_block -> block_ref_decl_list ) ; cur_block -> block_original_ref_decl_list = tree_cons ( NULL_TREE , exp , cur_block -> block_original_ref_decl_list ) ; return ref_decl ; }
build_block_ref_decl - This routine inserts a copied-in variable (a variable
referenced in the block but whose scope is outside the block) in helper
function's outer-most scope.
build_block_ref_decl - This routine inserts a copied - in variable ( a variable referenced in the block but whose scope is outside the block ) in helper function ' s outer - most scope .
/* APPLE LOCAL radar 6212722 */ /* APPLE LOCAL begin radar 5932809 - copyable byref blocks (C++ ch) */ /* 'decl' was previously declared as __block. Simply, copy the value
     embedded in the above variable. */ /* APPLE LOCAL begin radar 5988451 (C++ ch) */ /* Traverse enclosing blocks. Insert a copied-in variable in
	  each enclosing block which has no declaration of this
	  variable. This is to ensure that the current (inner) block
	  has the 'frozen' value of the copied-in variable; which means
	  the value of the copied in variable is at the point of the
	  block declaration and *not* when the inner block is
	  invoked.  */ /* Find the first declaration not in current block. */ /* Is the next declaration not in enclosing block? */ /* No declaration of variable seen in the block. Must insert one,
	      so it 'freezes' the variable in this block. */ /* APPLE LOCAL end radar 5988451 (C++ ch) */ /* APPLE LOCAL end radar 5932809 - copyable byref blocks (C++ ch) */ /* APPLE LOCAL begin radar 6212722 */ /* APPLE LOCAL end radar 6212722 */ /* APPLE LOCAL begin radars 6144664 & 6145471  */ /* APPLE LOCAL end radars 6144664 & 6145471  */ /* APPLE LOCAL radar 5805175 - blocks (C++ ch) */ /* Find the scope for function body (outer-most scope) and insert
     this variable in that scope. This is to avoid duplicate
     declaration of the save variable. */ /* We are enterring the copied-in variable in helper function's
     outer scope; that of its main body. */ /*invisible=*/ /*nested=*/ /* APPLE LOCAL radar 6212722 */