FreeBSD/contrib/gcc/cp/name-lookup.c
/* Push a tag name NAME for struct/class/union/enum type TYPE.  In case
   that the NAME is a class template, the tag is processed but not pushed.

   The pushed scope depend on the SCOPE parameter:
   - When SCOPE is TS_CURRENT, put it into the inner-most non-sk_cleanup
     scope.
   - When SCOPE is TS_GLOBAL, put it in the inner-most non-class and
     non-template-parameter scope.  This case is needed for forward
     declarations.
   - When SCOPE is TS_WITHIN_ENCLOSING_NON_CLASS, this is similar to
     TS_GLOBAL case except that names within template-parameter scopes
     are not pushed at all.

   Returns TYPE upon success and ERROR_MARK_NODE otherwise.  */
Push a tag name NAME for struct/class/union/enum type TYPE.  In case
that the NAME is a class template, the tag is processed but not pushed.

The pushed scope depend on the SCOPE parameter:
When SCOPE is TS_CURRENT, put it into the inner-most non-sk_cleanup
scope.
When SCOPE is TS_GLOBAL, put it in the inner-most non-class and
non-template-parameter scope.  This case is needed for forward
declarations.
When SCOPE is TS_WITHIN_ENCLOSING_NON_CLASS, this is similar to
TS_GLOBAL case except that names within template-parameter scopes
are not pushed at all.

Returns TYPE upon success and ERROR_MARK_NODE otherwise.
Push a tag name NAME for struct / class / union / enum type TYPE . In case that the NAME is a class template the tag is processed but not pushed . The pushed scope depend on the SCOPE parameter : When SCOPE is TS_CURRENT put it into the inner - most non - sk_cleanup scope . When SCOPE is TS_GLOBAL put it in the inner - most non - class and non - template - parameter scope . This case is needed for forward declarations . When SCOPE is TS_WITHIN_ENCLOSING_NON_CLASS this is similar to TS_GLOBAL case except that names within template - parameter scopes are not pushed at all . Returns TYPE upon success and ERROR_MARK_NODE otherwise .
tree
pushtag (tree name, tree type, tag_scope scope)
{
  struct cp_binding_level *b;
  tree decl;
  timevar_push (TV_NAME_LOOKUP);
  b = current_binding_level;
  while (
	 b->kind == sk_cleanup
	 || (b->kind == sk_template_parms
	     && (b->explicit_spec_p || scope == ts_global))
	 || (b->kind == sk_class
	     && (scope != ts_current
		 || COMPLETE_TYPE_P (b->this_entity))))
    b = b->level_chain;
  gcc_assert (TREE_CODE (name) == IDENTIFIER_NODE);
  if (IDENTIFIER_TYPE_VALUE (name) != type)
    {
      tree tdef;
      int in_class = 0;
      tree context = TYPE_CONTEXT (type);
      if (! context)
	{
	  tree cs = current_scope ();
	  if (scope == ts_current)
	    context = cs;
	  else if (cs != NULL_TREE && TYPE_P (cs))
	    context = decl_function_context (get_type_decl (cs));
	}
      if (!context)
	context = current_namespace;
      if (b->kind == sk_class
	  || (b->kind == sk_template_parms
	      && b->level_chain->kind == sk_class))
	in_class = 1;
      if (current_lang_name == lang_name_java)
	TYPE_FOR_JAVA (type) = 1;
      tdef = create_implicit_typedef (name, type);
      DECL_CONTEXT (tdef) = FROB_CONTEXT (context);
      if (scope == ts_within_enclosing_non_class)
	{
	  retrofit_lang_decl (tdef);
	  DECL_ANTICIPATED (tdef) = 1;
	  DECL_FRIEND_P (tdef) = 1;
	}
      decl = maybe_process_template_type_declaration
	(type, scope == ts_within_enclosing_non_class, b);
      if (decl == error_mark_node)
	POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl);
      if (! in_class)
	set_identifier_type_value_with_scope (name, tdef, b);
      if (b->kind == sk_class)
	{
	  if (!PROCESSING_REAL_TEMPLATE_DECL_P ())
	    finish_member_declaration (decl);
	  else
	    pushdecl_class_level (decl);
	}
      else if (b->kind != sk_template_parms)
	{
	  decl = pushdecl_with_scope (decl, b, false);
	  if (decl == error_mark_node)
	    POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl);
	}
      TYPE_CONTEXT (type) = DECL_CONTEXT (decl);
      if (TYPE_CONTEXT (type)
	  && TREE_CODE (TYPE_CONTEXT (type)) == FUNCTION_DECL)
	VEC_safe_push (tree, gc, local_classes, type);
    }
  if (b->kind == sk_class
      && !COMPLETE_TYPE_P (current_class_type))
    {
      maybe_add_class_template_decl_list (current_class_type,
					  type, 0);
      if (CLASSTYPE_NESTED_UTDS (current_class_type) == NULL)
	CLASSTYPE_NESTED_UTDS (current_class_type)
	  = binding_table_new (SCOPE_DEFAULT_HT_SIZE);
      binding_table_insert
	(CLASSTYPE_NESTED_UTDS (current_class_type), name, type);
    }
  decl = TYPE_NAME (type);
  gcc_assert (TREE_CODE (decl) == TYPE_DECL);
  TYPE_STUB_DECL (type) = decl;
  TREE_PUBLIC (decl) = 1;
  determine_visibility (decl);
  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, type);
}
tree pushtag ( tree name , tree type , tag_scope scope ) { struct cp_binding_level * b ; tree decl ; timevar_push ( TV_NAME_LOOKUP ) ; b = current_binding_level ; while ( b -> kind == sk_cleanup || ( b -> kind == sk_template_parms && ( b -> explicit_spec_p || scope == ts_global ) ) || ( b -> kind == sk_class && ( scope != ts_current || COMPLETE_TYPE_P ( b -> this_entity ) ) ) ) b = b -> level_chain ; gcc_assert ( TREE_CODE ( name ) == IDENTIFIER_NODE ) ; if ( IDENTIFIER_TYPE_VALUE ( name ) != type ) { tree tdef ; int in_class = 0 ; tree context = TYPE_CONTEXT ( type ) ; if ( ! context ) { tree cs = current_scope ( ) ; if ( scope == ts_current ) context = cs ; else if ( cs != NULL_TREE && TYPE_P ( cs ) ) context = decl_function_context ( get_type_decl ( cs ) ) ; } if ( ! context ) context = current_namespace ; if ( b -> kind == sk_class || ( b -> kind == sk_template_parms && b -> level_chain -> kind == sk_class ) ) in_class = 1 ; if ( current_lang_name == lang_name_java ) TYPE_FOR_JAVA ( type ) = 1 ; tdef = create_implicit_typedef ( name , type ) ; DECL_CONTEXT ( tdef ) = FROB_CONTEXT ( context ) ; if ( scope == ts_within_enclosing_non_class ) { retrofit_lang_decl ( tdef ) ; DECL_ANTICIPATED ( tdef ) = 1 ; DECL_FRIEND_P ( tdef ) = 1 ; } decl = maybe_process_template_type_declaration ( type , scope == ts_within_enclosing_non_class , b ) ; if ( decl == error_mark_node ) POP_TIMEVAR_AND_RETURN ( TV_NAME_LOOKUP , decl ) ; if ( ! in_class ) set_identifier_type_value_with_scope ( name , tdef , b ) ; if ( b -> kind == sk_class ) { if ( ! PROCESSING_REAL_TEMPLATE_DECL_P ( ) ) finish_member_declaration ( decl ) ; else pushdecl_class_level ( decl ) ; } else if ( b -> kind != sk_template_parms ) { decl = pushdecl_with_scope ( decl , b , false ) ; if ( decl == error_mark_node ) POP_TIMEVAR_AND_RETURN ( TV_NAME_LOOKUP , decl ) ; } TYPE_CONTEXT ( type ) = DECL_CONTEXT ( decl ) ; if ( TYPE_CONTEXT ( type ) && TREE_CODE ( TYPE_CONTEXT ( type ) ) == FUNCTION_DECL ) VEC_safe_push ( tree , gc , local_classes , type ) ; } if ( b -> kind == sk_class && ! COMPLETE_TYPE_P ( current_class_type ) ) { maybe_add_class_template_decl_list ( current_class_type , type , 0 ) ; if ( CLASSTYPE_NESTED_UTDS ( current_class_type ) == NULL ) CLASSTYPE_NESTED_UTDS ( current_class_type ) = binding_table_new ( SCOPE_DEFAULT_HT_SIZE ) ; binding_table_insert ( CLASSTYPE_NESTED_UTDS ( current_class_type ) , name , type ) ; } decl = TYPE_NAME ( type ) ; gcc_assert ( TREE_CODE ( decl ) == TYPE_DECL ) ; TYPE_STUB_DECL ( type ) = decl ; TREE_PUBLIC ( decl ) = 1 ; determine_visibility ( decl ) ; POP_TIMEVAR_AND_RETURN ( TV_NAME_LOOKUP , type ) ; }
Push a tag name NAME for struct/class/union/enum type TYPE.
Push a tag name NAME for struct / class / union / enum type TYPE .
/* Cleanup scopes are not scopes from the point of view of
	    the language.  */ /* Neither are the scopes used to hold template parameters
	    for an explicit specialization.  For an ordinary template
	    declaration, these scopes are not scopes from the point of
	    view of the language.  */ /* We may be defining a new type in the initializer
		    of a static member variable. We allow this when
		    not pedantic, and it is particularly useful for
		    type punning via an anonymous union.  */ /* Do C++ gratuitous typedefing.  */ /* When declaring a friend class of a local class, we want
	       to inject the newly named class into the scope
	       containing the local class, not the namespace
	       scope.  */ /* This is a friend.  Make this TYPE_DECL node hidden from
	     ordinary name lookup.  Its corresponding TEMPLATE_DECL
	     will be marked in push_template_decl_real.  */ /* Put this TYPE_DECL on the TYPE_FIELDS list for the
	       class.  But if it's a member template class, we want
	       the TEMPLATE_DECL, not the TYPE_DECL, so this is done
	       later.  */ /*is_friend=*/ /* If this is a local class, keep track of it.  We need this
	 information for name-mangling, and so that it is possible to
	 find all function definitions in a translation unit in a
	 convenient way.  (It's otherwise tricky to find a member
	 function definition it's only pointed to from within a local
	 class.)  */ /*friend_p=*/ /* Set type visibility now if this is a forward declaration.  */