aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2003-11-11 17:27:32 -0500
committerJason Merrill <jason@gcc.gnu.org>2003-11-11 17:27:32 -0500
commit86098eb892eb05e5da0c9eba207a75024c0fb91b (patch)
tree8082fe968555564efdd07e3add06e1110ab8b493 /gcc
parent292d9f2bcd1b1f21ae717064c7c9823b3a9c83cc (diff)
downloadgcc-86098eb892eb05e5da0c9eba207a75024c0fb91b.zip
gcc-86098eb892eb05e5da0c9eba207a75024c0fb91b.tar.gz
gcc-86098eb892eb05e5da0c9eba207a75024c0fb91b.tar.bz2
cp-tree.h (DECL_NAMESPACE_ASSOCIATIONS): New macro.
* cp-tree.h (DECL_NAMESPACE_ASSOCIATIONS): New macro. * name-lookup.c (parse_using_directive): New fn. (is_associated_namespace): New fn. (arg_assoc_namespace): Also check associated namespaces. * name-lookup.h: Declare new fns. * pt.c (maybe_process_partial_specialization): Allow specialization in associated namespace. * parser.c (cp_parser_using_directive): Accept attributes. Use parse_using_directive. From-SVN: r73468
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog12
-rw-r--r--gcc/cp/cp-tree.h5
-rw-r--r--gcc/cp/name-lookup.c61
-rw-r--r--gcc/cp/name-lookup.h2
-rw-r--r--gcc/cp/parser.c5
-rw-r--r--gcc/cp/pt.c6
-rw-r--r--gcc/doc/extend.texi40
7 files changed, 128 insertions, 3 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 5ea6d94..d3b8316 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,15 @@
+2003-11-11 Jason Merrill <jason@redhat.com>
+
+ * cp-tree.h (DECL_NAMESPACE_ASSOCIATIONS): New macro.
+ * name-lookup.c (parse_using_directive): New fn.
+ (is_associated_namespace): New fn.
+ (arg_assoc_namespace): Also check associated namespaces.
+ * name-lookup.h: Declare new fns.
+ * pt.c (maybe_process_partial_specialization): Allow
+ specialization in associated namespace.
+ * parser.c (cp_parser_using_directive): Accept attributes. Use
+ parse_using_directive.
+
2003-11-10 Richard Henderson <rth@redhat.com>
* cvt.c (convert_to_void): Use void_zero_node after overload failure.
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 0603160..def9b81 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -2063,6 +2063,11 @@ struct lang_decl GTY(())
of a namespace, to record the transitive closure of using namespace. */
#define DECL_NAMESPACE_USERS(NODE) DECL_INITIAL (NAMESPACE_DECL_CHECK (NODE))
+/* In a NAMESPACE_DECL, the list of namespaces which have associated
+ themselves with this one. */
+#define DECL_NAMESPACE_ASSOCIATIONS(NODE) \
+ (NAMESPACE_DECL_CHECK (NODE)->decl.saved_tree)
+
/* In a NAMESPACE_DECL, points to the original namespace if this is
a namespace alias. */
#define DECL_NAMESPACE_ALIAS(NODE) \
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index 624e86e..185c04f 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -3286,6 +3286,33 @@ do_using_directive (tree namespace)
add_using_namespace (current_namespace, namespace, 0);
}
+/* Deal with a using-directive seen by the parser. Currently we only
+ handle attributes here, since they cannot appear inside a template. */
+
+void
+parse_using_directive (tree namespace, tree attribs)
+{
+ tree a;
+
+ do_using_directive (namespace);
+
+ for (a = attribs; a; a = TREE_CHAIN (a))
+ {
+ tree name = TREE_PURPOSE (a);
+ if (is_attribute_p ("strong", name))
+ {
+ if (!toplevel_bindings_p ())
+ error ("strong using only meaningful at namespace scope");
+ else
+ DECL_NAMESPACE_ASSOCIATIONS (namespace)
+ = tree_cons (current_namespace, 0,
+ DECL_NAMESPACE_ASSOCIATIONS (namespace));
+ }
+ else
+ warning ("`%D' attribute directive ignored", name);
+ }
+}
+
/* Like pushdecl, only it places X in the global scope if appropriate.
Calls cp_finish_decl to register the variable, initializing it with
*INIT, if INIT is non-NULL. */
@@ -4011,6 +4038,34 @@ add_function (struct arg_lookup *k, tree fn)
return false;
}
+/* Returns true iff CURRENT has declared itself to be an associated
+ namespace of SCOPE via a strong using-directive (or transitive chain
+ thereof). Both are namespaces. */
+
+bool
+is_associated_namespace (tree current, tree scope)
+{
+ tree seen = NULL_TREE;
+ tree todo = NULL_TREE;
+ tree t;
+ while (1)
+ {
+ if (scope == current)
+ return true;
+ seen = tree_cons (scope, NULL_TREE, seen);
+ for (t = DECL_NAMESPACE_ASSOCIATIONS (scope); t; t = TREE_CHAIN (t))
+ if (!purpose_member (TREE_PURPOSE (t), seen))
+ todo = tree_cons (TREE_PURPOSE (t), NULL_TREE, todo);
+ if (todo)
+ {
+ scope = TREE_PURPOSE (todo);
+ todo = TREE_CHAIN (todo);
+ }
+ else
+ return false;
+ }
+}
+
/* Add functions of a namespace to the lookup structure.
Returns true on error. */
@@ -4022,6 +4077,12 @@ arg_assoc_namespace (struct arg_lookup *k, tree scope)
if (purpose_member (scope, k->namespaces))
return 0;
k->namespaces = tree_cons (scope, NULL_TREE, k->namespaces);
+
+ /* Check out our super-users. */
+ for (value = DECL_NAMESPACE_ASSOCIATIONS (scope); value;
+ value = TREE_CHAIN (value))
+ if (arg_assoc_namespace (k, TREE_PURPOSE (value)))
+ return true;
value = namespace_binding (k->name, scope);
if (!value)
diff --git a/gcc/cp/name-lookup.h b/gcc/cp/name-lookup.h
index 36643b2..df7615a 100644
--- a/gcc/cp/name-lookup.h
+++ b/gcc/cp/name-lookup.h
@@ -306,6 +306,8 @@ extern void do_local_using_decl (tree);
extern tree do_class_using_decl (tree);
extern void do_using_directive (tree);
extern tree lookup_arg_dependent (tree, tree, tree);
+extern bool is_associated_namespace (tree, tree);
+extern void parse_using_directive (tree, tree);
/* Set *DECL to the (non-hidden) declaration for ID at global scope,
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 9b040f5..d08588f 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -9078,6 +9078,7 @@ static void
cp_parser_using_directive (cp_parser* parser)
{
tree namespace_decl;
+ tree attribs;
/* Look for the `using' keyword. */
cp_parser_require_keyword (parser, RID_USING, "`using'");
@@ -9092,8 +9093,10 @@ cp_parser_using_directive (cp_parser* parser)
/*type_p=*/false);
/* Get the namespace being used. */
namespace_decl = cp_parser_namespace_name (parser);
+ /* And any specified attributes. */
+ attribs = cp_parser_attributes_opt (parser);
/* Update the symbol table. */
- do_using_directive (namespace_decl);
+ parse_using_directive (namespace_decl, attribs);
/* Look for the final `;'. */
cp_parser_require (parser, CPP_SEMICOLON, "`;'");
}
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index e464af3..cd93423 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -731,8 +731,10 @@ maybe_process_partial_specialization (tree type)
if (CLASSTYPE_IMPLICIT_INSTANTIATION (type)
&& !COMPLETE_TYPE_P (type))
{
- if (current_namespace
- != decl_namespace_context (CLASSTYPE_TI_TEMPLATE (type)))
+ tree tpl_ns = decl_namespace_context (CLASSTYPE_TI_TEMPLATE (type));
+ if (is_associated_namespace (current_namespace, tpl_ns))
+ /* Same or super-using namespace. */;
+ else
{
pedwarn ("specializing `%#T' in different namespace", type);
cp_pedwarn_at (" from definition of `%#D'",
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index fdc1c7c..7825a12 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -7649,6 +7649,7 @@ Predefined Macros,cpp,The GNU C Preprocessor}).
* Bound member functions:: You can extract a function pointer to the
method denoted by a @samp{->*} or @samp{.*} expression.
* C++ Attributes:: Variable, function, and type attributes for C++ only.
+* Strong Using:: Strong using-directives for namespace composition.
* Java Exceptions:: Tweaking exception handling to work with Java.
* Deprecated Features:: Things will disappear from g++.
* Backwards Compatibility:: Compatibilities with earlier definitions of C++.
@@ -8249,6 +8250,45 @@ interface table mechanism, instead of regular virtual table dispatch.
@end table
+See also @xref{Strong Using}.
+
+@node Strong Using
+@section Strong Using
+
+A using-directive with @code{__attribute ((strong))} is stronger
+than a normal using-directive in two ways:
+
+@itemize @bullet
+@item
+Templates from the used namespace can be specialized as though they were members of the using namespace.
+
+@item
+The using namespace is considered an associated namespace of all
+templates in the used namespace for purposes of argument-dependent
+name lookup.
+@end itemize
+
+This is useful for composing a namespace transparently from
+implementation namespaces. For example:
+
+@smallexample
+namespace std @{
+ namespace debug @{
+ template <class T> struct A @{ @};
+ @}
+ using namespace debug __attribute ((__strong__));
+ template <> struct A<int> @{ @}; // ok to specialize
+
+ template <class T> void f (A<T>);
+@}
+
+int main()
+@{
+ f (std::A<float>()); // lookup finds std::f
+ f (std::A<int>());
+@}
+@end smallexample
+
@node Java Exceptions
@section Java Exceptions