[llvm-commits] [llvm-gcc-4.2] r75463 - in /llvm-gcc-4.2/trunk/gcc/cp: decl.c name-lookup.c parser.c

Rafael Espindola rafael.espindola at gmail.com
Mon Jul 13 06:02:46 PDT 2009


Author: rafael
Date: Mon Jul 13 08:02:40 2009
New Revision: 75463

URL: http://llvm.org/viewvc/llvm-project?rev=75463&view=rev
Log:
Backport some patches from gcc trunk:

http://gcc.gnu.org/ml/gcc-cvs/2007-05/msg00662.html
http://gcc.gnu.org/ml/gcc-cvs/2007-07/msg00019.html
http://gcc.gnu.org/ml/gcc-cvs/2007-08/msg00240.html
http://gcc.gnu.org/ml/gcc-cvs/2007-08/msg00493.html

The first two were always GPL2. The last two were
added after the GPL3 transition, but were written
by aaw at google.com and I got permission to relicense
them under the GPL2 for inclusion in llvm-gcc.


Modified:
    llvm-gcc-4.2/trunk/gcc/cp/decl.c
    llvm-gcc-4.2/trunk/gcc/cp/name-lookup.c
    llvm-gcc-4.2/trunk/gcc/cp/parser.c

Modified: llvm-gcc-4.2/trunk/gcc/cp/decl.c
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/cp/decl.c?rev=75463&r1=75462&r2=75463&view=diff

==============================================================================
--- llvm-gcc-4.2/trunk/gcc/cp/decl.c (original)
+++ llvm-gcc-4.2/trunk/gcc/cp/decl.c Mon Jul 13 08:02:40 2009
@@ -10433,6 +10433,14 @@
 					   | DECL_SELF_REFERENCE_P (decl));
       return t;
     }
+  //LLVM LOCAL begin mainline
+  else if (decl && TREE_CODE (decl) == TREE_LIST)
+    {
+      error ("reference to %qD is ambiguous", name);
+      print_candidates (decl);
+      return error_mark_node;
+    }
+  //LLVM LOCAL end mainline
   else
     return NULL_TREE;
 }

Modified: llvm-gcc-4.2/trunk/gcc/cp/name-lookup.c
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/cp/name-lookup.c?rev=75463&r1=75462&r2=75463&view=diff

==============================================================================
--- llvm-gcc-4.2/trunk/gcc/cp/name-lookup.c (original)
+++ llvm-gcc-4.2/trunk/gcc/cp/name-lookup.c Mon Jul 13 08:02:40 2009
@@ -42,7 +42,6 @@
 #define EMPTY_SCOPE_BINDING { NULL_TREE, NULL_TREE }
 
 static cxx_scope *innermost_nonclass_level (void);
-static tree select_decl (const struct scope_binding *, int);
 static cxx_binding *binding_for_name (cxx_scope *, tree);
 static tree lookup_name_innermost_nonclass_level (tree);
 static tree push_overloaded_decl (tree, int, bool);
@@ -2115,6 +2114,22 @@
       return;
     }
 
+  //LLVM LOCAL begin mainline
+  /* Shift the old and new bindings around so we're comparing class and
+     enumeration names to each other.  */
+  if (oldval && DECL_IMPLICIT_TYPEDEF_P (oldval))
+    {
+      oldtype = oldval;
+      oldval = NULL_TREE;
+    }
+
+  if (decls.value && DECL_IMPLICIT_TYPEDEF_P (decls.value))
+    {
+      decls.type = decls.value;
+      decls.value = NULL_TREE;
+    }
+  //LLVM LOCAL end mainline
+
   /* It is impossible to overload a built-in function; any explicit
      declaration eliminates the built-in declaration.  So, if OLDVAL
      is a built-in, then we can just pretend it isn't there.  */
@@ -2124,95 +2139,112 @@
       && !DECL_HIDDEN_FRIEND_P (oldval))
     oldval = NULL_TREE;
 
-  /* Check for using functions.  */
-  if (decls.value && is_overloaded_fn (decls.value))
+  //LLVM LOCAL begin mainline
+  if (decls.value)
     {
-      tree tmp, tmp1;
-
-      if (oldval && !is_overloaded_fn (oldval))
+      /* Check for using functions.  */
+      if (is_overloaded_fn (decls.value))
 	{
-	  if (!DECL_IMPLICIT_TYPEDEF_P (oldval))
-	    error ("%qD is already declared in this scope", name);
-	  oldval = NULL_TREE;
-	}
+	  tree tmp, tmp1;
 
-      *newval = oldval;
-      for (tmp = decls.value; tmp; tmp = OVL_NEXT (tmp))
-	{
-	  tree new_fn = OVL_CURRENT (tmp);
-
-	  /* [namespace.udecl]
+	  if (oldval && !is_overloaded_fn (oldval))
+	    {
+	      error ("%qD is already declared in this scope", name);
+	      oldval = NULL_TREE;
+	    }
 
-	     If a function declaration in namespace scope or block
-	     scope has the same name and the same parameter types as a
-	     function introduced by a using declaration the program is
-	     ill-formed.  */
-	  for (tmp1 = oldval; tmp1; tmp1 = OVL_NEXT (tmp1))
+	  *newval = oldval;
+	  for (tmp = decls.value; tmp; tmp = OVL_NEXT (tmp))
 	    {
-	      tree old_fn = OVL_CURRENT (tmp1);
+	      tree new_fn = OVL_CURRENT (tmp);
 
-	      if (new_fn == old_fn)
-		/* The function already exists in the current namespace.  */
-		break;
-	      else if (OVL_USED (tmp1))
-		continue; /* this is a using decl */
-	      else if (compparms (TYPE_ARG_TYPES (TREE_TYPE (new_fn)),
-				  TYPE_ARG_TYPES (TREE_TYPE (old_fn))))
+	      /* [namespace.udecl]
+
+		 If a function declaration in namespace scope or block
+		 scope has the same name and the same parameter types as a
+		 function introduced by a using declaration the program is
+		 ill-formed.  */
+	      for (tmp1 = oldval; tmp1; tmp1 = OVL_NEXT (tmp1))
 		{
-		  gcc_assert (!DECL_ANTICIPATED (old_fn)
-			      || DECL_HIDDEN_FRIEND_P (old_fn));
+		  tree old_fn = OVL_CURRENT (tmp1);
 
-		  /* There was already a non-using declaration in
-		     this scope with the same parameter types. If both
-		     are the same extern "C" functions, that's ok.  */
-		  if (decls_match (new_fn, old_fn))
+		  if (new_fn == old_fn)
+		    /* The function already exists in the current namespace.  */
 		    break;
-		  else
+		  else if (OVL_USED (tmp1))
+		    continue; /* this is a using decl */
+		  else if (compparms (TYPE_ARG_TYPES (TREE_TYPE (new_fn)),
+				      TYPE_ARG_TYPES (TREE_TYPE (old_fn))))
 		    {
-		      error ("%qD is already declared in this scope", name);
-		      break;
+		      gcc_assert (!DECL_ANTICIPATED (old_fn)
+				  || DECL_HIDDEN_FRIEND_P (old_fn));
+
+		      /* There was already a non-using declaration in
+			 this scope with the same parameter types. If both
+			 are the same extern "C" functions, that's ok.  */
+		      if (decls_match (new_fn, old_fn))
+			break;
+		      else
+			{
+			  error ("%qD is already declared in this scope", name);
+			  break;
+			}
 		    }
 		}
-	    }
-
-	  /* If we broke out of the loop, there's no reason to add
-	     this function to the using declarations for this
-	     scope.  */
-	  if (tmp1)
-	    continue;
 
-	  /* If we are adding to an existing OVERLOAD, then we no
-	     longer know the type of the set of functions.  */
-	  if (*newval && TREE_CODE (*newval) == OVERLOAD)
-	    TREE_TYPE (*newval) = unknown_type_node;
-	  /* Add this new function to the set.  */
-	  *newval = build_overload (OVL_CURRENT (tmp), *newval);
-	  /* If there is only one function, then we use its type.  (A
-	     using-declaration naming a single function can be used in
-	     contexts where overload resolution cannot be
-	     performed.)  */
-	  if (TREE_CODE (*newval) != OVERLOAD)
-	    {
-	      *newval = ovl_cons (*newval, NULL_TREE);
-	      TREE_TYPE (*newval) = TREE_TYPE (OVL_CURRENT (tmp));
+	      /* If we broke out of the loop, there's no reason to add
+		 this function to the using declarations for this
+		 scope.  */
+	      if (tmp1)
+		continue;
+
+	      /* If we are adding to an existing OVERLOAD, then we no
+		 longer know the type of the set of functions.  */
+	      if (*newval && TREE_CODE (*newval) == OVERLOAD)
+		TREE_TYPE (*newval) = unknown_type_node;
+	      /* Add this new function to the set.  */
+	      *newval = build_overload (OVL_CURRENT (tmp), *newval);
+	      /* If there is only one function, then we use its type.  (A
+		 using-declaration naming a single function can be used in
+		 contexts where overload resolution cannot be
+		 performed.)  */
+	      if (TREE_CODE (*newval) != OVERLOAD)
+		{
+		  *newval = ovl_cons (*newval, NULL_TREE);
+		  TREE_TYPE (*newval) = TREE_TYPE (OVL_CURRENT (tmp));
+		}
+	      OVL_USED (*newval) = 1;
 	    }
-	  OVL_USED (*newval) = 1;
+	}
+      else
+	{
+	  *newval = decls.value;
+	  if (oldval && !decls_match (*newval, oldval))
+	    error ("%qD is already declared in this scope", name);
 	}
     }
   else
+    *newval = oldval;
+
+  if (decls.type && TREE_CODE (decls.type) == TREE_LIST)
     {
-      *newval = decls.value;
-      if (oldval && !decls_match (*newval, oldval))
+      error ("reference to %qD is ambiguous", name);
+      print_candidates (decls.type);
+    }
+  else
+    {
+      *newtype = decls.type;
+      if (oldtype && *newtype && !decls_match (oldtype, *newtype))
 	error ("%qD is already declared in this scope", name);
     }
 
-  *newtype = decls.type;
-  if (oldtype && *newtype && !same_type_p (oldtype, *newtype))
+  /* If *newval is empty, shift any class or enumeration name down.  */
+  if (!*newval)
     {
-      error ("using declaration %qD introduced ambiguous type %qT",
-	     name, oldtype);
-      return;
+      *newval = *newtype;
+      *newtype = NULL_TREE;
     }
+  //LLVM LOCAL end mainline
 }
 
 /* Process a using-declaration at function scope.  */
@@ -3532,43 +3564,63 @@
    XXX In what way should I treat extern declarations?
    XXX I don't want to repeat the entire duplicate_decls here */
 
+//LLVM LOCAL begin mainline
 static void
-ambiguous_decl (tree name, struct scope_binding *old, cxx_binding *new,
-		int flags)
+ambiguous_decl (struct scope_binding *old, cxx_binding *new, int flags)
 {
   tree val, type;
   gcc_assert (old != NULL);
+
+  /* Copy the type.  */
+  type = new->type;
+  if (LOOKUP_NAMESPACES_ONLY (flags)
+      || (type && hidden_name_p (type) && !(flags & LOOKUP_HIDDEN)))
+    type = NULL_TREE;
+
   /* Copy the value.  */
   val = new->value;
   if (val)
-    switch (TREE_CODE (val))
-      {
-      case TEMPLATE_DECL:
-	/* If we expect types or namespaces, and not templates,
-	   or this is not a template class.  */
-	if ((LOOKUP_QUALIFIERS_ONLY (flags)
-	     && !DECL_CLASS_TEMPLATE_P (val))
-	    || hidden_name_p (val))
-	  val = NULL_TREE;
-	break;
-      case TYPE_DECL:
-	if (LOOKUP_NAMESPACES_ONLY (flags) || hidden_name_p (val))
-	  val = NULL_TREE;
-	break;
-      case NAMESPACE_DECL:
-	if (LOOKUP_TYPES_ONLY (flags))
-	  val = NULL_TREE;
-	break;
-      case FUNCTION_DECL:
-	/* Ignore built-in functions that are still anticipated.  */
-	if (LOOKUP_QUALIFIERS_ONLY (flags) || hidden_name_p (val))
-	  val = NULL_TREE;
-	break;
-      default:
-	if (LOOKUP_QUALIFIERS_ONLY (flags))
-	  val = NULL_TREE;
-      }
+    {
+      if (hidden_name_p (val) && !(flags & LOOKUP_HIDDEN))
+	val = NULL_TREE;
+      else
+	switch (TREE_CODE (val))
+	  {
+	  case TEMPLATE_DECL:
+	    /* If we expect types or namespaces, and not templates,
+	       or this is not a template class.  */
+	    if ((LOOKUP_QUALIFIERS_ONLY (flags)
+		 && !DECL_CLASS_TEMPLATE_P (val)))
+	      val = NULL_TREE;
+	    break;
+	  case TYPE_DECL:
+	    if (LOOKUP_NAMESPACES_ONLY (flags)
+		|| (type && (flags & LOOKUP_PREFER_TYPES)))
+	      val = NULL_TREE;
+	    break;
+	  case NAMESPACE_DECL:
+	    if (LOOKUP_TYPES_ONLY (flags))
+	      val = NULL_TREE;
+	    break;
+	  case FUNCTION_DECL:
+	    /* Ignore built-in functions that are still anticipated.  */
+	    if (LOOKUP_QUALIFIERS_ONLY (flags))
+	      val = NULL_TREE;
+	    break;
+	  default:
+	    if (LOOKUP_QUALIFIERS_ONLY (flags))
+	      val = NULL_TREE;
+	  }
+    }
 
+  /* If val is hidden, shift down any class or enumeration name.  */
+  if (!val)
+    {
+      val = type;
+      type = NULL_TREE;
+    }
+
+//LLVM LOCAL end mainline
   if (!old->value)
     old->value = val;
   /* APPLE LOCAL C++ using lookup 4329536 */
@@ -3579,25 +3631,23 @@
       else
 	{
 	  old->value = tree_cons (NULL_TREE, old->value,
-				  build_tree_list (NULL_TREE, new->value));
+				  //LLVM LOCAL begin mainline
+				  build_tree_list (NULL_TREE, val));
+	                         //LLVM LOCAL end mainline
 	  TREE_TYPE (old->value) = error_mark_node;
 	}
     }
-  /* ... and copy the type.  */
-  type = new->type;
-  if (LOOKUP_NAMESPACES_ONLY (flags))
-    type = NULL_TREE;
+
+  //LLVM LOCAL begin mainline
   if (!old->type)
     old->type = type;
   else if (type && old->type != type)
     {
-      if (flags & LOOKUP_COMPLAIN)
-	{
-	  error ("%qD denotes an ambiguous type",name);
-	  error ("%J  first type here", TYPE_MAIN_DECL (old->type));
-	  error ("%J  other type here", TYPE_MAIN_DECL (type));
-	}
+      old->type = tree_cons (NULL_TREE, old->type,
+			     build_tree_list (NULL_TREE, type));
+      TREE_TYPE (old->type) = error_mark_node;
     }
+  //LLVM LOCAL end mainline
 }
 
 /* Return the declarations that are members of the namespace NS.  */
@@ -3686,36 +3736,6 @@
   return fns;
 }
 
-/* Select the right _DECL from multiple choices.  */
-
-static tree
-select_decl (const struct scope_binding *binding, int flags)
-{
-  tree val;
-  val = binding->value;
-
-  timevar_push (TV_NAME_LOOKUP);
-  if (LOOKUP_NAMESPACES_ONLY (flags))
-    {
-      /* We are not interested in types.  */
-      if (val && (TREE_CODE (val) == NAMESPACE_DECL
-		  || TREE_CODE (val) == TREE_LIST))
-	POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val);
-      POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
-    }
-
-  /* If looking for a type, or if there is no non-type binding, select
-     the value binding.  */
-  if (binding->type && (!val || (flags & LOOKUP_PREFER_TYPES)))
-    val = binding->type;
-  /* Don't return non-types if we really prefer types.  */
-  else if (val && LOOKUP_TYPES_ONLY (flags)
-	   && ! DECL_DECLARES_TYPE_P (val))
-    val = NULL_TREE;
-
-  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val);
-}
-
 /* Unscoped lookup of a global: iterate over current namespaces,
    considering using-directives.  */
 
@@ -3727,22 +3747,21 @@
   tree siter;
   struct cp_binding_level *level;
   tree val = NULL_TREE;
-  struct scope_binding binding = EMPTY_SCOPE_BINDING;
 
   timevar_push (TV_NAME_LOOKUP);
 
   for (; !val; scope = CP_DECL_CONTEXT (scope))
     {
+      //LLVM LOCAL begin mainline
+      struct scope_binding binding = EMPTY_SCOPE_BINDING;
+      //LLVM LOCAL end mainline
       cxx_binding *b =
 	 cxx_scope_find_binding_for_name (NAMESPACE_LEVEL (scope), name);
 
       if (b)
-	{
-	  if (b->value
-	      && ((flags & LOOKUP_HIDDEN) || !hidden_name_p (b->value)))
-	    binding.value = b->value;
-	  binding.type = b->type;
-	}
+	//LLVM LOCAL begin mainline
+	ambiguous_decl (&binding, b, flags);
+	//LLVM LOCAL end mainline
 
       /* Add all _DECLs seen through local using-directives.  */
       for (level = current_binding_level;
@@ -3767,7 +3786,9 @@
 	  siter = CP_DECL_CONTEXT (siter);
 	}
 
-      val = select_decl (&binding, flags);
+      //LLVM LOCAL begin mainline
+      val = binding.value;
+      //LLVM LOCAL end mainline
       if (scope == global_namespace)
 	break;
     }
@@ -3797,7 +3818,9 @@
       if (is_type_p)
 	flags |= LOOKUP_PREFER_TYPES;
       if (qualified_lookup_using_namespace (name, scope, &binding, flags))
-	t = select_decl (&binding, flags);
+	//LLVM LOCAL begin mainline
+	t = binding.value;
+	//LLVM LOCAL end mainline
     }
   else if (is_aggr_type (scope, complain))
     t = lookup_member (scope, name, 2, is_type_p);
@@ -3830,7 +3853,9 @@
 	  cxx_scope_find_binding_for_name (NAMESPACE_LEVEL (used), name);
 	/* Resolve ambiguities.  */
 	if (val1)
-	  ambiguous_decl (name, val, val1, flags);
+	  //LLVM LOCAL begin mainline
+	  ambiguous_decl (val, val1, flags);
+	  //LLVM LOCAL end mainline
       }
   POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val->value != error_mark_node);
 }
@@ -3859,7 +3884,9 @@
 	cxx_scope_find_binding_for_name (NAMESPACE_LEVEL (scope), name);
       seen = tree_cons (scope, NULL_TREE, seen);
       if (binding)
-	ambiguous_decl (name, result, binding, flags);
+	//LLVM LOCAL begin mainline
+	ambiguous_decl (result, binding, flags);
+	//LLVM LOCAL end mainline
 
       /* Consider strong using directives always, and non-strong ones
 	 if we haven't found a binding yet.  ??? Shouldn't we consider

Modified: llvm-gcc-4.2/trunk/gcc/cp/parser.c
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/cp/parser.c?rev=75463&r1=75462&r2=75463&view=diff

==============================================================================
--- llvm-gcc-4.2/trunk/gcc/cp/parser.c (original)
+++ llvm-gcc-4.2/trunk/gcc/cp/parser.c Mon Jul 13 08:02:40 2009
@@ -11177,13 +11177,25 @@
       if (parser->scope)
 	{
 	  tree decl;
+	  //LLVM LOCAL begin mainline
+	  tree ambiguous_decls;
+	  //LLVM LOCAL end mainline
 
 	  decl = cp_parser_lookup_name (parser, identifier,
 					tag_type,
 					/*is_template=*/false,
 					/*is_namespace=*/false,
 					/*check_dependency=*/true,
-					/*ambiguous_decls=*/NULL);
+					//LLVM LOCAL begin mainline
+					&ambiguous_decls);
+	                                //LLVM LOCAL end mainline
+
+	  //LLVM LOCAL begin mainline
+	  /* If the lookup was ambiguous, an error will already have been
+	     issued.  */
+	  if (ambiguous_decls)
+	    return error_mark_node;
+	  //LLVM LOCAL end mainline
 
 	  /* If we are parsing friend declaration, DECL may be a
 	     TEMPLATE_DECL tree node here.  However, we need to check





More information about the llvm-commits mailing list