[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