2011-01-20 Lawrence Crowl <crowl@google.com>
* g++.dg/pph/x4overset1.cc: Make passing.
* g++.dg/pph/x4overset2.cc: Make wanted assembly diff.
* g++.dg/pph/x4overset3.cc: Make passing.
* g++.dg/pph/x4overset4.cc: Make wanted assembly diff.
* g++.dg/pph/x6dynarray3.cc: Change xfail signature.
2012-01-20 Lawrence Crowl <crowl@google.com>
* parser.c (cp_debug_parser_where): Protect against null pointers.
* name-lookup.c (cxx_binding_make_for_name): New.
(binding_for_name): Factor construction into the above.
(modify_binding_for_overload): New.
(push_overloaded_decl_1): Factor out above function.
(pph_foreach_on_chain_bl): Add filter parameter.
(pph_set_identifier_bindings): Likewise.
(pph_set_chain_identifier_bindings): Likewise.
(pph_set_chain_namespace_bindings): Likewise.
(pph_set_namespace_bindings): Likewise. Correct overloading.
(pph_set_namespace_namespace_bindings): Add filter parameter in calls.
(pph_set_global_identifier_bindings): Likewise.
===================================================================
@@ -1,8 +1,6 @@
-// { dg-bogus "a0dynarray-dfn1b.hi:8:13: error: no matching function for call to 'operator new" "" { xfail *-*-* } 0 }
// { dg-bogus "a0dynarray-dfn1b.hi:22:5: error: no suitable 'operator delete" "" { xfail *-*-* } 0 }
-// { dg-bogus "a0dynarray-dfn2b.hi:8:13: error: no matching function for call to 'operator new" "" { xfail *-*-* } 0 }
// { dg-bogus "a0dynarray-dfn2b.hi:13:9: error: no suitable 'operator delete" "" { xfail *-*-* } 0 }
-// { dg-bogus "a0dynarray-dcl3.hi:11:60: warning: no corresponding deallocation function for 'void. operator new" "" { xfail *-*-* } 0 }
+// { dg-bogus "a0dynarray-dcl3.hi:11:60: error: call of overloaded 'operator new" "" { xfail *-*-* } 0 }
#include "x5dynarray3.h"
===================================================================
@@ -1,5 +1,3 @@
-// pph asm xdiff 56596
-
#include "x1overset1.h"
#include "x1overset2.h"
===================================================================
@@ -1,5 +1,4 @@
-// pph asm xdiff 01525
-// wanted 57625
+// pph asm xwant 19882
// This test produces overload differences because the declaration and
// call orders are different between pph and textual parsing.
===================================================================
@@ -1,5 +1,3 @@
-// pph asm xdiff 56596
-
#include "x1overset1.h"
#include "x1overset2.h"
#include "x1overset1.h"
===================================================================
@@ -1,5 +1,4 @@
-// pph asm xdiff 01525
-// wanted 57625
+// pph asm xwant 19882
// This test produces overload differences because the declaration and
// call orders are different between pph and textual parsing.
===================================================================
@@ -471,12 +471,34 @@ void
cp_debug_parser_where (FILE *file, cp_parser *parser)
{
const size_t window_size = 20;
- cp_token *token = parser->lexer->next_token;
- expanded_location eloc = expand_location (token->location);
+ cp_lexer *lexer;
+ cp_token *token;
+ expanded_location eloc;
if (file == NULL)
file = stderr;
+ if (parser == NULL)
+ {
+ fprintf (file, "No parser available.\n");
+ return;
+ }
+
+ lexer = parser->lexer;
+ if (lexer == NULL)
+ {
+ fprintf (file, "No lexer available.\n");
+ return;
+ }
+
+ token = lexer->next_token;
+ if (token == NULL)
+ {
+ fprintf (file, "No token available.\n");
+ return;
+ }
+
+ eloc = expand_location (token->location);
fprintf (file, "%s:%d:%d ", eloc.file, eloc.line, eloc.column);
cp_debug_parser_tokens (file, parser, window_size);
}
===================================================================
@@ -2035,19 +2035,12 @@ cp_binding_level_find_binding_for_name (
return NULL;
}
-/* Always returns a binding for name in scope. If no binding is
- found, make a new one. */
+/* Return an new cxx_binding initialized for a NAME in SCOPE. */
static cxx_binding *
-binding_for_name (cp_binding_level *scope, tree name)
+cxx_binding_make_for_name (cp_binding_level *scope, tree name)
{
- cxx_binding *result;
-
- result = cp_binding_level_find_binding_for_name (scope, name);
- if (result)
- return result;
- /* Not found, make a new one. */
- result = cxx_binding_make (NULL, NULL);
+ cxx_binding *result = cxx_binding_make (NULL, NULL);
result->previous = IDENTIFIER_NAMESPACE_BINDINGS (name);
result->scope = scope;
result->is_local = false;
@@ -2056,6 +2049,18 @@ binding_for_name (cp_binding_level *scop
return result;
}
+/* Always returns a binding for name in scope. If no binding is
+ found, make a new one. */
+
+static cxx_binding *
+binding_for_name (cp_binding_level *scope, tree name)
+{
+ cxx_binding *result = cp_binding_level_find_binding_for_name (scope, name);
+ if (!result)
+ result = cxx_binding_make_for_name (scope, name);
+ return result;
+}
+
/* Walk through the bindings associated to the name of FUNCTION,
and return the first declaration of a function with a
"C" linkage specification, a.k.a 'extern "C"'.
@@ -2205,6 +2210,29 @@ pushdecl_with_scope (tree x, cp_binding_
return ret;
}
+static tree
+modify_binding_for_overload (tree decl, tree old, int flags)
+{
+ tree new_binding;
+ if (old || TREE_CODE (decl) == TEMPLATE_DECL
+ /* If it's a using declaration, we always need to build an OVERLOAD,
+ because it's the only way to remember that the declaration comes
+ from 'using', and have the lookup behave correctly. */
+ || (flags & PUSH_USING))
+ {
+ if (old && TREE_CODE (old) != OVERLOAD)
+ new_binding = ovl_cons (decl, ovl_cons (old, NULL_TREE));
+ else
+ new_binding = ovl_cons (decl, old);
+ if (flags & PUSH_USING)
+ OVL_USED (new_binding) = 1;
+ }
+ else
+ /* NAME is not ambiguous. */
+ new_binding = decl;
+ return new_binding;
+}
+
/* DECL is a FUNCTION_DECL for a non-member function, which may have
other definitions already in place. We get around this by making
@@ -2294,22 +2322,7 @@ push_overloaded_decl_1 (tree decl, int f
}
}
- if (old || TREE_CODE (decl) == TEMPLATE_DECL
- /* If it's a using declaration, we always need to build an OVERLOAD,
- because it's the only way to remember that the declaration comes
- from 'using', and have the lookup behave correctly. */
- || (flags & PUSH_USING))
- {
- if (old && TREE_CODE (old) != OVERLOAD)
- new_binding = ovl_cons (decl, ovl_cons (old, NULL_TREE));
- else
- new_binding = ovl_cons (decl, old);
- if (flags & PUSH_USING)
- OVL_USED (new_binding) = 1;
- }
- else
- /* NAME is not ambiguous. */
- new_binding = decl;
+ new_binding = modify_binding_for_overload (decl, old, flags);
if (doing_global)
set_namespace_binding (name, current_namespace, new_binding);
@@ -6114,14 +6127,14 @@ pph_debug_binding_inaction (const char *
with argument BL. */
static void
-pph_foreach_on_chain_bl (tree first, cp_binding_level *bl,
- void (*function)(tree, cp_binding_level *))
+pph_foreach_on_chain_bl (tree first, cp_binding_level *bl, int flags,
+ void (*function)(tree, cp_binding_level *, int))
{
unsigned i;
tree decl;
VEC(tree,heap) *w = chain2vec (first);
FOR_EACH_VEC_ELT_REVERSE (tree, w, i, decl)
- (*function) (decl, bl);
+ (*function) (decl, bl, flags);
VEC_free (tree, heap, w);
}
@@ -6129,7 +6142,8 @@ pph_foreach_on_chain_bl (tree first, cp_
/* Set a identifier binding. */
static void
-pph_set_identifier_bindings (tree decl, cp_binding_level *bl)
+pph_set_identifier_bindings (tree decl, cp_binding_level *bl,
+ int flags ATTRIBUTE_UNUSED)
{
/* Set the identifier binding for a single decl. */
tree id = DECL_NAME (decl);
@@ -6141,48 +6155,88 @@ pph_set_identifier_bindings (tree decl,
}
-/* Set the identifier bindings for an individual chain. */
+/* Set the identifier bindings for an individual chain. */
static void
-pph_set_chain_identifier_bindings (tree first, cp_binding_level *bl)
+pph_set_chain_identifier_bindings (tree first, cp_binding_level *bl, int flags)
{
- pph_foreach_on_chain_bl (first, bl, pph_set_identifier_bindings);
+ pph_foreach_on_chain_bl (first, bl, flags, pph_set_identifier_bindings);
+}
+
+
+#if 0
+/* Add an overload to a binding. */
+
+static tree
+pph_add_overload (tree decl, tree older)
+{
+ tree newer;
+ if (older && TREE_CODE (older) != OVERLOAD)
+ newer = ovl_cons (decl, ovl_cons (older, NULL_TREE));
+ else
+ newer = ovl_cons (decl, older);
+ return newer;
}
+#endif
/* Set a namespace identifier binding. */
static void
-pph_set_namespace_bindings (tree decl, cp_binding_level *bl)
+pph_set_namespace_bindings (tree decl, cp_binding_level *bl, int flags)
{
/* Set the namespace identifier binding for a single decl. */
tree id = DECL_NAME (decl);
if (id)
{
- /* This code plagarizes from set_namespace_binding.
+ /* FIXME pph: This code plagarizes from push_overloaded_decl_1 and
+ binding_for_name. It may be incomplete. */
+ cxx_binding *b = cp_binding_level_find_binding_for_name (bl, id);
+ if (b)
+ {
+ tree old = b->value;
+ if (is_overloaded_fn (old))
+ {
+ /* We don't overload implicit built-ins. duplicate_decls()
+ may fail to merge the decls if the new decl is e.g. a
+ template function. */
+ if (TREE_CODE (old) == FUNCTION_DECL
+ && DECL_ANTICIPATED (old)
+ && !DECL_HIDDEN_FRIEND_P (old))
+ old = NULL;
+ decl = modify_binding_for_overload (decl, old, flags);
+ }
+ }
+ else
+ b = cxx_binding_make_for_name (bl, id);
+
+ /* FIXME pph: This code plagarizes from set_namespace_binding.
It has trouble with supplement_binding, methinks. */
- /* FIXME pph: we should do more merging here. */
- cxx_binding *b = binding_for_name (bl, id);
if (!b->value)
{
b->value = decl;
- pph_debug_binding_action ("v-bind", decl);
+ pph_debug_binding_action ("new bind", decl);
+ }
+ if (TREE_CODE (decl) == OVERLOAD)
+ {
+ b->value = decl;
+ pph_debug_binding_action ("ovl bind", decl);
}
else if (TREE_CODE (b->value) == TYPE_DECL &&
TREE_CODE (decl) != TYPE_DECL)
{
b->type = b->value;
b->value = decl;
- pph_debug_binding_action ("p-bind", decl);
+ pph_debug_binding_action ("t/v bind", decl);
}
else if (TREE_CODE (b->value) != TYPE_DECL &&
TREE_CODE (decl) == TYPE_DECL)
{
b->type = decl;
- pph_debug_binding_action ("t-bind", decl);
+ pph_debug_binding_action ("v/t bind", decl);
}
else
- pph_debug_binding_inaction ("n-bind", decl);
+ pph_debug_binding_inaction ("not bind", decl);
}
}
@@ -6190,9 +6244,9 @@ pph_set_namespace_bindings (tree decl, c
/* Set the namespace identifier bindings. */
static void
-pph_set_chain_namespace_bindings (tree first, cp_binding_level *bl)
+pph_set_chain_namespace_bindings (tree first, cp_binding_level *bl, int flags)
{
- pph_foreach_on_chain_bl (first, bl, pph_set_namespace_bindings);
+ pph_foreach_on_chain_bl (first, bl, flags, pph_set_namespace_bindings);
}
@@ -6234,10 +6288,12 @@ pph_set_namespace_namespace_binding (tre
static void
pph_set_namespace_namespace_bindings (cp_binding_level *bl)
{
- pph_set_chain_namespace_bindings (bl->names, bl);
- pph_set_chain_namespace_bindings (bl->namespaces, bl);
- pph_set_chain_namespace_bindings (bl->usings, bl);
- /* FIXME pph: pph_set_chain_namespace_bindings (bl->using_directives, bl); */
+ pph_set_chain_namespace_bindings (bl->names, bl, 0);
+ pph_set_chain_namespace_bindings (bl->namespaces, bl, 0);
+ pph_set_chain_namespace_bindings (bl->usings, bl, PUSH_USING);
+ /* FIXME pph:
+ pph_set_chain_namespace_bindings (bl->using_directives, bl, 0);
+ */
pph_foreach_on_chain (bl->namespaces, pph_set_namespace_namespace_binding);
}
@@ -6249,10 +6305,10 @@ void
pph_set_global_identifier_bindings (void)
{
cp_binding_level *bl = scope_chain->bindings;
- pph_set_chain_identifier_bindings (bl->names, bl);
- pph_set_chain_identifier_bindings (bl->namespaces, bl);
- pph_set_chain_identifier_bindings (bl->usings, bl);
- pph_set_chain_identifier_bindings (bl->using_directives, bl);
+ pph_set_chain_identifier_bindings (bl->names, bl, 0);
+ pph_set_chain_identifier_bindings (bl->namespaces, bl, 0);
+ pph_set_chain_identifier_bindings (bl->usings, bl, PUSH_USING);
+ pph_set_chain_identifier_bindings (bl->using_directives, bl, 0);
pph_set_namespace_namespace_bindings (bl);
}