FreeBSD/contrib/gcc/cp/decl.c
/* Lookup NAME in elaborate type specifier in scope according to
   SCOPE and issue diagnostics if necessary.
   Return *_TYPE node upon success, NULL_TREE when the NAME is not
   found, and ERROR_MARK_NODE for type error.  */
Lookup NAME in elaborate type specifier in scope according to
SCOPE and issue diagnostics if necessary.
Return *_TYPE node upon success, NULL_TREE when the NAME is not
found, and ERROR_MARK_NODE for type error.
Lookup NAME in elaborate type specifier in scope according to SCOPE and issue diagnostics if necessary . Return * _TYPE node upon success NULL_TREE when the NAME is not found and ERROR_MARK_NODE for type error .
static tree
lookup_and_check_tag (enum tag_types tag_code, tree name,
		      tag_scope scope, bool template_header_p)
{
  tree t;
  tree decl;
  if (scope == ts_global)
    {
      decl = lookup_name_prefer_type (name, 2);
      if (!decl)
	decl = lookup_type_scope (name, ts_within_enclosing_non_class);
    }
  else
    decl = lookup_type_scope (name, scope);
  if (decl && DECL_CLASS_TEMPLATE_P (decl))
    decl = DECL_TEMPLATE_RESULT (decl);
  if (decl && TREE_CODE (decl) == TYPE_DECL)
    {
      if (scope == ts_current && DECL_SELF_REFERENCE_P (decl))
	{
	  error ("%qD has the same name as the class in which it is "
		 "declared",
		 decl);
	  return error_mark_node;
	}
      t = check_elaborated_type_specifier (tag_code,
					   decl,
					   template_header_p
					   | DECL_SELF_REFERENCE_P (decl));
      return t;
    }
  else if (decl && TREE_CODE (decl) == TREE_LIST)
    {
      error ("reference to %qD is ambiguous", name);
      print_candidates (decl);
      return error_mark_node;
    }
  else
    return NULL_TREE;
}
static tree lookup_and_check_tag ( enum tag_types tag_code , tree name , tag_scope scope , bool template_header_p ) { tree t ; tree decl ; if ( scope == ts_global ) { decl = lookup_name_prefer_type ( name , 2 ) ; if ( ! decl ) decl = lookup_type_scope ( name , ts_within_enclosing_non_class ) ; } else decl = lookup_type_scope ( name , scope ) ; if ( decl && DECL_CLASS_TEMPLATE_P ( decl ) ) decl = DECL_TEMPLATE_RESULT ( decl ) ; if ( decl && TREE_CODE ( decl ) == TYPE_DECL ) { if ( scope == ts_current && DECL_SELF_REFERENCE_P ( decl ) ) { error ( " " " " , decl ) ; return error_mark_node ; } t = check_elaborated_type_specifier ( tag_code , decl , template_header_p | DECL_SELF_REFERENCE_P ( decl ) ) ; return t ; } else if ( decl && TREE_CODE ( decl ) == TREE_LIST ) { error ( " " , name ) ; print_candidates ( decl ) ; return error_mark_node ; } else return NULL_TREE ; }
Lookup NAME in elaborate type specifier in scope according to
SCOPE and issue diagnostics if necessary.
Lookup NAME in elaborate type specifier in scope according to SCOPE and issue diagnostics if necessary .
/* First try ordinary name lookup, ignoring hidden class name
	 injected via friend declaration.  */ /* If that fails, the name will be placed in the smallest
	 non-class, non-function-prototype scope according to 3.3.1/5.
	 We may already have a hidden name declared as friend in this
	 scope.  So lookup again but not ignoring hidden names.
	 If we find one, that name will be made visible rather than
	 creating a new tag.  */ /* Look for invalid nested type:
	   class C {
	     class C {};
	   };  */ /* Two cases we need to consider when deciding if a class
	 template is allowed as an elaborated type specifier:
	 1. It is a self reference to its own class.
	 2. It comes with a template header.

	 For example:

	   template <class T> class C {
	     class C *c1;		// DECL_SELF_REFERENCE_P is true
	     class D;
	   };
	   template <class U> class C; // template_header_p is true
	   template <class T> class C<T>::D {
	     class C *c2;		// DECL_SELF_REFERENCE_P is true
	   };  */