diff options
author | Jason Merrill <jason@redhat.com> | 2003-11-11 17:27:32 -0500 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2003-11-11 17:27:32 -0500 |
commit | 86098eb892eb05e5da0c9eba207a75024c0fb91b (patch) | |
tree | 8082fe968555564efdd07e3add06e1110ab8b493 /gcc | |
parent | 292d9f2bcd1b1f21ae717064c7c9823b3a9c83cc (diff) | |
download | gcc-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/ChangeLog | 12 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 5 | ||||
-rw-r--r-- | gcc/cp/name-lookup.c | 61 | ||||
-rw-r--r-- | gcc/cp/name-lookup.h | 2 | ||||
-rw-r--r-- | gcc/cp/parser.c | 5 | ||||
-rw-r--r-- | gcc/cp/pt.c | 6 | ||||
-rw-r--r-- | gcc/doc/extend.texi | 40 |
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 |