In C++11 it's OK to declare a specialization for the first time outside of the template's namespace, so long as the specialization is explicitly qualified. Conversely, C++11 puts the same restrictions on explicit instantiations, whereas C++98 didn't say anything about where they needed to go. So I needed to update a bunch of libstdc++ tests which didn't conform.
To enforce this for class templates I needed to hook into the parser at the places where we still know whether or not a nested-name-specifier was used; for non-class templates we preserve that information long enough for check_explicit_instantiation to find it. Tested x86_64-pc-linux-gnu, applying to trunk.
commit 56bc587a8c075200a19b2175aaed648b8e9d88f5 Author: Jason Merrill <ja...@redhat.com> Date: Fri Nov 11 07:45:01 2016 -0800 DR 374 - specialization in outer namespace PR c++/56840 * pt.c (check_specialization_namespace): Allow any enclosing namespace. (check_unqualified_spec_or_inst): New. (check_explicit_specialization): Call it. * parser.c (cp_parser_elaborated_type_specifier) (cp_parser_class_head): Call it. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 8183775..3e41a33 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -6082,6 +6082,7 @@ extern void reset_specialization (void); extern void end_specialization (void); extern void begin_explicit_instantiation (void); extern void end_explicit_instantiation (void); +extern void check_unqualified_spec_or_inst (tree, location_t); extern tree check_explicit_specialization (tree, tree, int, int); extern int num_template_headers_for_class (tree); extern void check_template_variable (tree); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 185c98b..6101504 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -7868,8 +7868,7 @@ check_class_member_definition_namespace (tree decl) diagnostics. */ if (processing_specialization) return; - /* There are no restrictions on the placement of - explicit instantiations. */ + /* We check this in check_explicit_instantiation_namespace. */ if (processing_explicit_instantiation) return; /* [class.mfct] diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index e574c27..8db6cfd 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -3558,7 +3558,7 @@ set_decl_namespace (tree decl, tree scope, bool friendp) /* Since decl is a function, old should contain a function decl. */ if (!is_overloaded_fn (old)) goto complain; - /* A template can be explicitly specialized in any namespace. */ + /* We handle these in check_explicit_instantiation_namespace. */ if (processing_explicit_instantiation) return; if (processing_template_decl || processing_specialization) diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 7b95dba..b3b69b3 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -17004,24 +17004,28 @@ cp_parser_elaborated_type_specifier (cp_parser* parser, globalscope = cp_parser_global_scope_opt (parser, /*current_scope_valid_p=*/false); /* Look for the nested-name-specifier. */ + tree nested_name_specifier; if (tag_type == typename_type && !globalscope) { - if (!cp_parser_nested_name_specifier (parser, + nested_name_specifier + = cp_parser_nested_name_specifier (parser, /*typename_keyword_p=*/true, /*check_dependency_p=*/true, /*type_p=*/true, - is_declaration)) + is_declaration); + if (!nested_name_specifier) return error_mark_node; } else /* Even though `typename' is not present, the proposed resolution to Core Issue 180 says that in `class A<T>::B', `B' should be considered a type-name, even if `A<T>' is dependent. */ - cp_parser_nested_name_specifier_opt (parser, - /*typename_keyword_p=*/true, - /*check_dependency_p=*/true, - /*type_p=*/true, - is_declaration); + nested_name_specifier + = cp_parser_nested_name_specifier_opt (parser, + /*typename_keyword_p=*/true, + /*check_dependency_p=*/true, + /*type_p=*/true, + is_declaration); /* For everything but enumeration types, consider a template-id. For an enumeration type, consider only a plain identifier. */ if (tag_type != enum_type) @@ -17069,8 +17073,18 @@ cp_parser_elaborated_type_specifier (cp_parser* parser, else if (tag_type == typename_type && TREE_CODE (decl) != TYPE_DECL) ; else if (TREE_CODE (decl) == TYPE_DECL) - type = check_elaborated_type_specifier (tag_type, decl, - /*allow_template_p=*/true); + { + type = check_elaborated_type_specifier (tag_type, decl, + /*allow_template_p=*/true); + + /* If the next token is a semicolon, this must be a specialization, + instantiation, or friend declaration. Check the scope while we + still know whether or not we had a nested-name-specifier. */ + if (type != error_mark_node + && !nested_name_specifier && !is_friend + && cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON)) + check_unqualified_spec_or_inst (type, token->location); + } else if (decl == error_mark_node) type = error_mark_node; } @@ -22336,6 +22350,11 @@ cp_parser_class_head (cp_parser* parser, { type = TREE_TYPE (id); type = maybe_process_partial_specialization (type); + + /* Check the scope while we still know whether or not we had a + nested-name-specifier. */ + if (type != error_mark_node) + check_unqualified_spec_or_inst (type, type_start_token->location); } if (nested_name_specifier) pushed_scope = push_scope (nested_name_specifier); diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index d4855d5..d9499d9 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -772,28 +772,29 @@ check_specialization_namespace (tree tmpl) /* [tmpl.expl.spec] - An explicit specialization shall be declared in the namespace of - which the template is a member, or, for member templates, in the - namespace of which the enclosing class or enclosing class - template is a member. An explicit specialization of a member - function, member class or static data member of a class template - shall be declared in the namespace of which the class template is - a member. */ + An explicit specialization shall be declared in a namespace enclosing the + specialized template. An explicit specialization whose declarator-id is + not qualified shall be declared in the nearest enclosing namespace of the + template, or, if the namespace is inline (7.3.1), any namespace from its + enclosing namespace set. */ if (current_scope() != DECL_CONTEXT (tmpl) && !at_namespace_scope_p ()) { error ("specialization of %qD must appear at namespace scope", tmpl); return false; } - if (is_associated_namespace (current_namespace, tpl_ns)) - /* Same or super-using namespace. */ + + if (cxx_dialect < cxx11 + ? is_associated_namespace (current_namespace, tpl_ns) + : is_ancestor (current_namespace, tpl_ns)) + /* Same or enclosing namespace. */ return true; else { permerror (input_location, "specialization of %qD in different namespace", tmpl); - permerror (DECL_SOURCE_LOCATION (tmpl), - " from definition of %q#D", tmpl); + inform (DECL_SOURCE_LOCATION (tmpl), + " from definition of %q#D", tmpl); return false; } } @@ -2586,6 +2587,36 @@ check_template_variable (tree decl) } } +/* An explicit specialization whose declarator-id or class-head-name is not + qualified shall be declared in the nearest enclosing namespace of the + template, or, if the namespace is inline (7.3.1), any namespace from its + enclosing namespace set. + + If the name declared in the explicit instantiation is an unqualified name, + the explicit instantiation shall appear in the namespace where its template + is declared or, if that namespace is inline (7.3.1), any namespace from its + enclosing namespace set. */ + +void +check_unqualified_spec_or_inst (tree t, location_t loc) +{ + tree tmpl = most_general_template (t); + if (DECL_NAMESPACE_SCOPE_P (tmpl) + && !is_associated_namespace (current_namespace, + CP_DECL_CONTEXT (tmpl))) + { + if (processing_specialization) + permerror (loc, "explicit specialization of %qD outside its " + "namespace must use a nested-name-specifier", tmpl); + else if (processing_explicit_instantiation + && cxx_dialect >= cxx11) + /* This was allowed in C++98, so only pedwarn. */ + pedwarn (loc, OPT_Wpedantic, "explicit instantiation of %qD " + "outside its namespace must use a nested-name-" + "specifier", tmpl); + } +} + /* Check to see if the function just declared, as indicated in DECLARATOR, and in DECL, is a specialization of a function template. We may also discover that the declaration is an explicit @@ -2949,15 +2980,8 @@ check_explicit_specialization (tree declarator, return error_mark_node; else { - if (!ctype && !was_template_id - && (specialization || member_specialization - || explicit_instantiation) - && !is_associated_namespace (CP_DECL_CONTEXT (decl), - CP_DECL_CONTEXT (tmpl))) - error ("%qD is not declared in %qD", - tmpl, current_namespace); - else if (TREE_CODE (decl) == FUNCTION_DECL - && DECL_HIDDEN_FRIEND_P (tmpl)) + if (TREE_CODE (decl) == FUNCTION_DECL + && DECL_HIDDEN_FRIEND_P (tmpl)) { if (pedwarn (DECL_SOURCE_LOCATION (decl), 0, "friend declaration %qD is not visible to " @@ -2965,6 +2989,9 @@ check_explicit_specialization (tree declarator, inform (DECL_SOURCE_LOCATION (tmpl), "friend declaration here"); } + else if (!ctype && !is_friend + && CP_DECL_CONTEXT (decl) == current_namespace) + check_unqualified_spec_or_inst (tmpl, DECL_SOURCE_LOCATION (decl)); tree gen_tmpl = most_general_template (tmpl); diff --git a/gcc/testsuite/g++.dg/cpp0x/explicit-inst1.C b/gcc/testsuite/g++.dg/cpp0x/explicit-inst1.C new file mode 100644 index 0000000..a6455d8 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/explicit-inst1.C @@ -0,0 +1,13 @@ +// In C++11 explicit instantiation without a nested-name-specifier must be in +// the same namespace. + +namespace N { + template <class T> class foo {}; + template <class T> class bar {}; +} + +using N::bar; +template class bar<int>; // { dg-error "" "" { target c++11 } } + +using namespace N; +template class foo<int>; // { dg-error "" "" { target c++11 } } diff --git a/gcc/testsuite/g++.dg/template/spec17.C b/gcc/testsuite/g++.dg/template/spec17.C index 2375576..91c5d56 100644 --- a/gcc/testsuite/g++.dg/template/spec17.C +++ b/gcc/testsuite/g++.dg/template/spec17.C @@ -1,7 +1,7 @@ // PR c++/16224 namespace io { - template <typename> int foo(); // { dg-error "" } + template <typename> int foo(); } using namespace io; diff --git a/gcc/testsuite/g++.dg/template/spec25.C b/gcc/testsuite/g++.dg/template/spec25.C index 385d19a..d6f0f08 100644 --- a/gcc/testsuite/g++.dg/template/spec25.C +++ b/gcc/testsuite/g++.dg/template/spec25.C @@ -1,10 +1,10 @@ namespace N { template <typename T> struct S { - void f() {} // { dg-error "definition" } + void f() {} }; } namespace K { - template <> void N::S<char>::f() {} // { dg-error "different namespace" } + template <> void N::S<char>::f() {} // { dg-error "namespace" } } diff --git a/gcc/testsuite/g++.dg/template/spec36.C b/gcc/testsuite/g++.dg/template/spec36.C index 7e8dc52..5807fc5 100644 --- a/gcc/testsuite/g++.dg/template/spec36.C +++ b/gcc/testsuite/g++.dg/template/spec36.C @@ -8,9 +8,9 @@ struct basic_string namespace MyNS { class MyClass { template <typename T> - T test() { } /* { dg-error "from definition" } */ + T test() { } /* { dg-message "from definition" "" { target c++98_only } } */ }; } template <> -basic_string MyNS::MyClass::test() /* { dg-error "specialization of" } */ +basic_string MyNS::MyClass::test() /* { dg-error "specialization of" "" { target c++98_only } }*/ { return 1; } diff --git a/gcc/testsuite/g++.old-deja/g++.ns/template13.C b/gcc/testsuite/g++.old-deja/g++.ns/template13.C index a9559c71..e8e5304 100644 --- a/gcc/testsuite/g++.old-deja/g++.ns/template13.C +++ b/gcc/testsuite/g++.old-deja/g++.ns/template13.C @@ -4,7 +4,7 @@ namespace bar { // trick it to provide some prior declaration template<class T> - void foo(); // { dg-error "definition" } + void foo(); template<class T>class X; // { dg-message "note: previous declaration" } } @@ -15,7 +15,7 @@ bar::foo(T const &a) // { dg-error "" "" { xfail *-*-* } } not declared in b return a; } -template<> void bar::foo<int>() // { dg-error "different namespace" } +template<> void bar::foo<int>() // { dg-error "different namespace" "" { target c++98_only } } { } diff --git a/gcc/testsuite/g++.old-deja/g++.pt/explicit73.C b/gcc/testsuite/g++.old-deja/g++.pt/explicit73.C index 1d83e34..f8ceaf7 100644 --- a/gcc/testsuite/g++.old-deja/g++.pt/explicit73.C +++ b/gcc/testsuite/g++.old-deja/g++.pt/explicit73.C @@ -7,7 +7,7 @@ // the template namespace N { - template <class T> class foo; // { dg-error "" } referenced below + template <class T> class foo; } using namespace N; diff --git a/gcc/testsuite/g++.old-deja/g++.pt/lookup10.C b/gcc/testsuite/g++.old-deja/g++.pt/lookup10.C index 1c04250..9d2add8 100644 --- a/gcc/testsuite/g++.old-deja/g++.pt/lookup10.C +++ b/gcc/testsuite/g++.old-deja/g++.pt/lookup10.C @@ -13,8 +13,8 @@ namespace Outer { namespace Core = Core_Real; namespace Core_Real { - template<class T> void Foo (T *) {} // { dg-error "definition" } + template<class T> void Foo (T *) {} } - template<> void Core::Foo<> (Render_Real::Type *) {} // { dg-error "" } + template<> void Core::Foo<> (Render_Real::Type *) {} // { dg-error "" "" { target c++98_only } } } diff --git a/libstdc++-v3/testsuite/30_threads/future/requirements/explicit_instantiation.cc b/libstdc++-v3/testsuite/30_threads/future/requirements/explicit_instantiation.cc index 1632523..87d423f 100644 --- a/libstdc++-v3/testsuite/30_threads/future/requirements/explicit_instantiation.cc +++ b/libstdc++-v3/testsuite/30_threads/future/requirements/explicit_instantiation.cc @@ -25,9 +25,8 @@ #include <testsuite_tr1.h> using namespace __gnu_test; -using std::future; -template class future<int>; -template class future<int&>; -template class future<void>; -template class future<ClassType>; -template class future<ClassType&>; +template class std::future<int>; +template class std::future<int&>; +template class std::future<void>; +template class std::future<ClassType>; +template class std::future<ClassType&>; diff --git a/libstdc++-v3/testsuite/30_threads/packaged_task/requirements/explicit_instantiation.cc b/libstdc++-v3/testsuite/30_threads/packaged_task/requirements/explicit_instantiation.cc index db90ff2..e3b61e4 100644 --- a/libstdc++-v3/testsuite/30_threads/packaged_task/requirements/explicit_instantiation.cc +++ b/libstdc++-v3/testsuite/30_threads/packaged_task/requirements/explicit_instantiation.cc @@ -25,9 +25,8 @@ #include <testsuite_tr1.h> using namespace __gnu_test; -using std::packaged_task; -template class packaged_task<int()>; -template class packaged_task<int&()>; -template class packaged_task<void()>; -template class packaged_task<ClassType(int)>; -template class packaged_task<AbstractClass&(int)>; +template class std::packaged_task<int()>; +template class std::packaged_task<int&()>; +template class std::packaged_task<void()>; +template class std::packaged_task<ClassType(int)>; +template class std::packaged_task<AbstractClass&(int)>; diff --git a/libstdc++-v3/testsuite/30_threads/promise/requirements/explicit_instantiation.cc b/libstdc++-v3/testsuite/30_threads/promise/requirements/explicit_instantiation.cc index 9691ab0..4a220a9 100644 --- a/libstdc++-v3/testsuite/30_threads/promise/requirements/explicit_instantiation.cc +++ b/libstdc++-v3/testsuite/30_threads/promise/requirements/explicit_instantiation.cc @@ -25,9 +25,8 @@ #include <testsuite_tr1.h> using namespace __gnu_test; -using std::promise; -template class promise<int>; -template class promise<int&>; -template class promise<void>; -template class promise<ClassType>; -template class promise<ClassType&>; +template class std::promise<int>; +template class std::promise<int&>; +template class std::promise<void>; +template class std::promise<ClassType>; +template class std::promise<ClassType&>; diff --git a/libstdc++-v3/testsuite/30_threads/shared_future/requirements/explicit_instantiation.cc b/libstdc++-v3/testsuite/30_threads/shared_future/requirements/explicit_instantiation.cc index a992b88..715b7fe 100644 --- a/libstdc++-v3/testsuite/30_threads/shared_future/requirements/explicit_instantiation.cc +++ b/libstdc++-v3/testsuite/30_threads/shared_future/requirements/explicit_instantiation.cc @@ -25,9 +25,8 @@ #include <testsuite_tr1.h> using namespace __gnu_test; -using std::shared_future; -template class shared_future<int>; -template class shared_future<int&>; -template class shared_future<void>; -template class shared_future<ClassType>; -template class shared_future<ClassType&>; +template class std::shared_future<int>; +template class std::shared_future<int&>; +template class std::shared_future<void>; +template class std::shared_future<ClassType>; +template class std::shared_future<ClassType&>; diff --git a/libstdc++-v3/testsuite/ext/numeric_traits/numeric_traits.cc b/libstdc++-v3/testsuite/ext/numeric_traits/numeric_traits.cc index 6198743..6653625 100644 --- a/libstdc++-v3/testsuite/ext/numeric_traits/numeric_traits.cc +++ b/libstdc++-v3/testsuite/ext/numeric_traits/numeric_traits.cc @@ -21,7 +21,6 @@ #include <ext/numeric_traits.h> -using __gnu_cxx::__numeric_traits; -template struct __numeric_traits<short>; -template struct __numeric_traits<unsigned short>; -template struct __numeric_traits<double>; +template struct __gnu_cxx::__numeric_traits<short>; +template struct __gnu_cxx::__numeric_traits<unsigned short>; +template struct __gnu_cxx::__numeric_traits<double>; diff --git a/libstdc++-v3/testsuite/tr1/2_general_utilities/enable_shared_from_this/requirements/explicit_instantiation/1.cc b/libstdc++-v3/testsuite/tr1/2_general_utilities/enable_shared_from_this/requirements/explicit_instantiation/1.cc index a7b967f..18d94df 100644 --- a/libstdc++-v3/testsuite/tr1/2_general_utilities/enable_shared_from_this/requirements/explicit_instantiation/1.cc +++ b/libstdc++-v3/testsuite/tr1/2_general_utilities/enable_shared_from_this/requirements/explicit_instantiation/1.cc @@ -23,8 +23,7 @@ // { dg-do compile } using namespace __gnu_test; -using std::tr1::enable_shared_from_this; -template class enable_shared_from_this<int>; -template class enable_shared_from_this<void>; -template class enable_shared_from_this<ClassType>; -template class enable_shared_from_this<IncompleteClass>; +template class std::tr1::enable_shared_from_this<int>; +template class std::tr1::enable_shared_from_this<void>; +template class std::tr1::enable_shared_from_this<ClassType>; +template class std::tr1::enable_shared_from_this<IncompleteClass>; diff --git a/libstdc++-v3/testsuite/tr1/2_general_utilities/shared_ptr/requirements/explicit_instantiation/1.cc b/libstdc++-v3/testsuite/tr1/2_general_utilities/shared_ptr/requirements/explicit_instantiation/1.cc index 794deaf..918822d 100644 --- a/libstdc++-v3/testsuite/tr1/2_general_utilities/shared_ptr/requirements/explicit_instantiation/1.cc +++ b/libstdc++-v3/testsuite/tr1/2_general_utilities/shared_ptr/requirements/explicit_instantiation/1.cc @@ -23,8 +23,7 @@ // { dg-do compile } using namespace __gnu_test; -using std::tr1::shared_ptr; -template class shared_ptr<int>; -template class shared_ptr<void>; -template class shared_ptr<ClassType>; -template class shared_ptr<IncompleteClass>; +template class std::tr1::shared_ptr<int>; +template class std::tr1::shared_ptr<void>; +template class std::tr1::shared_ptr<ClassType>; +template class std::tr1::shared_ptr<IncompleteClass>; diff --git a/libstdc++-v3/testsuite/tr1/2_general_utilities/shared_ptr/requirements/explicit_instantiation/2.cc b/libstdc++-v3/testsuite/tr1/2_general_utilities/shared_ptr/requirements/explicit_instantiation/2.cc index 93587b2..870e888 100644 --- a/libstdc++-v3/testsuite/tr1/2_general_utilities/shared_ptr/requirements/explicit_instantiation/2.cc +++ b/libstdc++-v3/testsuite/tr1/2_general_utilities/shared_ptr/requirements/explicit_instantiation/2.cc @@ -26,8 +26,7 @@ // library this checks the templates can be instantiated for non-default // lock policy, for a single-threaded lib this is redundant but harmless. using namespace __gnu_test; -using std::tr1::__shared_ptr; using std::tr1::_S_single; -template class __shared_ptr<int, _S_single>; -template class __shared_ptr<ClassType, _S_single>; -template class __shared_ptr<IncompleteClass, _S_single>; +template class std::tr1::__shared_ptr<int, _S_single>; +template class std::tr1::__shared_ptr<ClassType, _S_single>; +template class std::tr1::__shared_ptr<IncompleteClass, _S_single>; diff --git a/libstdc++-v3/testsuite/tr1/2_general_utilities/weak_ptr/requirements/explicit_instantiation/1.cc b/libstdc++-v3/testsuite/tr1/2_general_utilities/weak_ptr/requirements/explicit_instantiation/1.cc index d64517c..0680ead 100644 --- a/libstdc++-v3/testsuite/tr1/2_general_utilities/weak_ptr/requirements/explicit_instantiation/1.cc +++ b/libstdc++-v3/testsuite/tr1/2_general_utilities/weak_ptr/requirements/explicit_instantiation/1.cc @@ -23,8 +23,7 @@ // { dg-do compile } using namespace __gnu_test; -using std::tr1::weak_ptr; -template class weak_ptr<int>; -template class weak_ptr<void>; -template class weak_ptr<ClassType>; -template class weak_ptr<IncompleteClass>; +template class std::tr1::weak_ptr<int>; +template class std::tr1::weak_ptr<void>; +template class std::tr1::weak_ptr<ClassType>; +template class std::tr1::weak_ptr<IncompleteClass>; diff --git a/libstdc++-v3/testsuite/tr1/2_general_utilities/weak_ptr/requirements/explicit_instantiation/2.cc b/libstdc++-v3/testsuite/tr1/2_general_utilities/weak_ptr/requirements/explicit_instantiation/2.cc index 672e637..31617c9 100644 --- a/libstdc++-v3/testsuite/tr1/2_general_utilities/weak_ptr/requirements/explicit_instantiation/2.cc +++ b/libstdc++-v3/testsuite/tr1/2_general_utilities/weak_ptr/requirements/explicit_instantiation/2.cc @@ -26,9 +26,8 @@ // library this checks the templates can be instantiated for non-default // lock policy, for a single-threaded lib this is redundant but harmless. using namespace __gnu_test; -using std::tr1::__weak_ptr; using std::tr1::_S_single; -template class __weak_ptr<int, _S_single>; -template class __weak_ptr<void, _S_single>; -template class __weak_ptr<ClassType, _S_single>; -template class __weak_ptr<IncompleteClass, _S_single>; +template class std::tr1::__weak_ptr<int, _S_single>; +template class std::tr1::__weak_ptr<void, _S_single>; +template class std::tr1::__weak_ptr<ClassType, _S_single>; +template class std::tr1::__weak_ptr<IncompleteClass, _S_single>; diff --git a/libstdc++-v3/testsuite/tr1/6_containers/hash/requirements/explicit_instantiation.cc b/libstdc++-v3/testsuite/tr1/6_containers/hash/requirements/explicit_instantiation.cc index aba574d..5f017c7 100644 --- a/libstdc++-v3/testsuite/tr1/6_containers/hash/requirements/explicit_instantiation.cc +++ b/libstdc++-v3/testsuite/tr1/6_containers/hash/requirements/explicit_instantiation.cc @@ -24,27 +24,25 @@ #include <string> #include <tr1/functional> -using namespace std::tr1; - // Verify that we can instantiate hash for every required type. -template class hash<bool>; -template class hash<char>; -template class hash<signed char>; -template class hash<unsigned char>; -template class hash<short>; -template class hash<int>; -template class hash<long>; -template class hash<unsigned short>; -template class hash<unsigned int>; -template class hash<unsigned long>; -template class hash<float>; -template class hash<double>; -template class hash<long double>; -template class hash<void*>; -template class hash<std::string>; +template class std::tr1::hash<bool>; +template class std::tr1::hash<char>; +template class std::tr1::hash<signed char>; +template class std::tr1::hash<unsigned char>; +template class std::tr1::hash<short>; +template class std::tr1::hash<int>; +template class std::tr1::hash<long>; +template class std::tr1::hash<unsigned short>; +template class std::tr1::hash<unsigned int>; +template class std::tr1::hash<unsigned long>; +template class std::tr1::hash<float>; +template class std::tr1::hash<double>; +template class std::tr1::hash<long double>; +template class std::tr1::hash<void*>; +template class std::tr1::hash<std::string>; #ifdef _GLIBCXX_USE_WCHAR_T -template class hash<wchar_t>; -template class hash<std::wstring>; +template class std::tr1::hash<wchar_t>; +template class std::tr1::hash<std::wstring>; #endif diff --git a/libstdc++-v3/testsuite/tr1/6_containers/unordered_map/requirements/explicit_instantiation.cc b/libstdc++-v3/testsuite/tr1/6_containers/unordered_map/requirements/explicit_instantiation.cc index f659817..60ac8a5 100644 --- a/libstdc++-v3/testsuite/tr1/6_containers/unordered_map/requirements/explicit_instantiation.cc +++ b/libstdc++-v3/testsuite/tr1/6_containers/unordered_map/requirements/explicit_instantiation.cc @@ -30,13 +30,13 @@ using std::allocator; using std::pair; using std::equal_to; -template class unordered_map<string, float>; -template class unordered_map<string, int, +template class std::tr1::unordered_map<string, float>; +template class std::tr1::unordered_map<string, int, hash<string>, equal_to<string>, allocator<pair<const string, int> > >; -template class unordered_map<string, float, +template class std::tr1::unordered_map<string, float, hash<string>, equal_to<string>, allocator<char> >; -template class __unordered_map<string, int, +template class std::tr1::__unordered_map<string, int, hash<string>, equal_to<string>, allocator<pair<const string, int> >, true>; diff --git a/libstdc++-v3/testsuite/tr1/6_containers/unordered_multimap/requirements/explicit_instantiation.cc b/libstdc++-v3/testsuite/tr1/6_containers/unordered_multimap/requirements/explicit_instantiation.cc index 5b72ae9..e92da82 100644 --- a/libstdc++-v3/testsuite/tr1/6_containers/unordered_multimap/requirements/explicit_instantiation.cc +++ b/libstdc++-v3/testsuite/tr1/6_containers/unordered_multimap/requirements/explicit_instantiation.cc @@ -30,13 +30,13 @@ using std::equal_to; using std::allocator; using std::pair; -template class unordered_multimap<string, float>; -template class unordered_multimap<string, int, +template class std::tr1::unordered_multimap<string, float>; +template class std::tr1::unordered_multimap<string, int, hash<string>, equal_to<string>, allocator<pair<const string, int> > >; -template class unordered_multimap<string, float, +template class std::tr1::unordered_multimap<string, float, hash<string>, equal_to<string>, allocator<char> >; -template class __unordered_multimap<string, int, +template class std::tr1::__unordered_multimap<string, int, hash<string>, equal_to<string>, allocator<pair<const string, int> >, true>; diff --git a/libstdc++-v3/testsuite/tr1/6_containers/unordered_multiset/requirements/explicit_instantiation.cc b/libstdc++-v3/testsuite/tr1/6_containers/unordered_multiset/requirements/explicit_instantiation.cc index a160526..662184b 100644 --- a/libstdc++-v3/testsuite/tr1/6_containers/unordered_multiset/requirements/explicit_instantiation.cc +++ b/libstdc++-v3/testsuite/tr1/6_containers/unordered_multiset/requirements/explicit_instantiation.cc @@ -27,10 +27,10 @@ using namespace std::tr1; using std::equal_to; using std::allocator; -template class unordered_multiset<int>; -template class unordered_multiset<float, hash<float>, equal_to<float>, +template class std::tr1::unordered_multiset<int>; +template class std::tr1::unordered_multiset<float, hash<float>, equal_to<float>, allocator<float> >; -template class unordered_multiset<int, hash<int>, equal_to<int>, +template class std::tr1::unordered_multiset<int, hash<int>, equal_to<int>, allocator<char> >; -template class __unordered_multiset<float, hash<float>, equal_to<float>, +template class std::tr1::__unordered_multiset<float, hash<float>, equal_to<float>, allocator<float>, true>; diff --git a/libstdc++-v3/testsuite/tr1/6_containers/unordered_set/requirements/explicit_instantiation.cc b/libstdc++-v3/testsuite/tr1/6_containers/unordered_set/requirements/explicit_instantiation.cc index 15679e1..5d4d83d 100644 --- a/libstdc++-v3/testsuite/tr1/6_containers/unordered_set/requirements/explicit_instantiation.cc +++ b/libstdc++-v3/testsuite/tr1/6_containers/unordered_set/requirements/explicit_instantiation.cc @@ -27,10 +27,10 @@ using namespace std::tr1; using std::equal_to; using std::allocator; -template class unordered_set<int>; -template class unordered_set<float, hash<float>, equal_to<float>, - allocator<float> >; -template class unordered_set<int, hash<int>, equal_to<int>, - allocator<char> >; -template class __unordered_set<float, hash<float>, equal_to<float>, - allocator<float>, true>; +template class std::tr1::unordered_set<int>; +template class std::tr1::unordered_set<float, hash<float>, equal_to<float>, + allocator<float> >; +template class std::tr1::unordered_set<int, hash<int>, equal_to<int>, + allocator<char> >; +template class std::tr1::__unordered_set<float, hash<float>, equal_to<float>, + allocator<float>, true>;