跟在模板模板参数后的符号是“ = ::Loki::SingleThreaded ”,它是模板模板参数的缺省实参。“ ::Loki::SingleThreaded ”是 id-expression 形式。
cp_parser_type_parameter (continue)
7804 /* If the next token is an `=', then there is a
7805 default-argument. */
7806 if (cp_lexer_next_token_is (parser->lexer, CPP_EQ))
7807 {
7808 bool is_template;
7809
7810 /* Consume the `='. */
7811 cp_lexer_consume_token (parser->lexer);
7812 /* Parse the id-expression. */
7813 default_argument
7814 = cp_parser_id_expression (parser,
7815 /*template_keyword_p=*/ false,
7816 /*check_dependency_p=*/ true,
7817 /*template_p=*/ &is_template,
7818 /*declarator_p=*/ false);
7819 if (TREE_CODE (default_argument) == TYPE_DECL)
7820 /* If the id-expression was a template-id that refers to
7821 a template-class, we already have the declaration here,
7822 so no further lookup is needed. */
7823 ;
7824 else
7825 /* Look up the name. */
7826 default_argument
7827 = cp_parser_lookup_name (parser, default_argument,
7828 /*is_type=*/ false,
7829 /*is_template=*/ is_template,
7830 /*is_namespace=*/ false,
7831 /*check_dependency=*/ true);
7832 /* See if the default argument is valid. */
7833 default_argument
7834 = check_template_template_default_arg (default_argument);
7835 }
7836 else
7837 default_argument = NULL_TREE;
7838
7839 /* Create the combined representation of the parameter and the
7840 default argument. */
7841 parameter = build_tree_list (default_argument, parameter);
7842 }
7843 break ;
7844
7845 default :
7846 abort ();
7847 break ;
7848 }
7849
7850 return parameter;
7851 }
为了方便起见,我们重新显示 cp_parser_id_expression 如下。该函数将返回对应的 IDENTIFIER_NODE 节点。对于这个例子,这个标识符是“ SingleThreaded ”。
2685 static tree
2686 cp_parser_id_expression (cp_parser *parser, in parser.c
2687 bool template_keyword_p,
2688 bool check_dependency_p,
2689 bool *template_p,
2690 bool declarator_p)
2691 {
2692 bool global_scope_p;
2693 bool nested_name_specifier_p;
2694
2695 /* Assume the `template' keyword was not used. */
2696 if (template_p)
2697 *template_p = false;
2698
2699 /* Look for the optional `::' operator. */
2700 global_scope_p
2701 = (cp_parser_global_scope_opt (parser, /*current_scope_valid_p=*/ false)
2702 != NULL_TREE);
2703 /* Look for the optional nested-name-specifier. */
2704 nested_name_specifier_p
2705 = (cp_parser_nested_name_specifier_opt (parser,
2706 /*typename_keyword_p=*/ false,
2707 check_dependency_p,
2708 /*type_p=*/ false,
2709 declarator_p)
2710 != NULL_TREE);
2711 /* If there is a nested-name-specifier, then we are looking at
2712 the first qualified-id production. */
2713 if (nested_name_specifier_p)
2714 {
2715 tree saved_scope;
2716 tree saved_object_scope;
2717 tree saved_qualifying_scope;
2718 tree unqualified_id;
2719 bool is_template;
2720
2721 /* See if the next token is the `template' keyword. */
2722 if (!template_p)
2723 template_p = &is_template;
2724 *template_p = cp_parser_optional_template_keyword (parser);
2725 /* Name lookup we do during the processing of the
2726 unqualified-id might obliterate SCOPE. */
2727 saved_scope = parser->scope;
2728 saved_object_scope = parser->object_scope;
2729 saved_qualifying_scope = parser->qualifying_scope;
2730 /* Process the final unqualified-id. */
2731 unqualified_id = cp_parser_unqualified_id (parser, *template_p,
2732 check_dependency_p,
2733 declarator_p);
2734 /* Restore the SAVED_SCOPE for our caller. */
2735 parser->scope = saved_scope;
2736 parser->object_scope = saved_object_scope;
2737 parser->qualifying_scope = saved_qualifying_scope;
2738
2739 return unqualified_id;
2740 }
…
2792 }
首先,如果“ :: ”存在, cp_parser_global_scope_opt 将返回 global_namespace 作为全局名字空间作用域,并且同时相应的 NAMESPACE_DECL 节点被设置入 parser 的 scope 域。符号“ Loki:: ”构成了 nested-name-specifier ,在 2705 行的 cp_parser_nested_name_specifier_opt 返回由该指定符( specifier )指定的类或名字空间作用域。对于这个例子,它是名字空间 “Loki” 的作用域。同样 parser 的 scope 域被更新为相关的 NAMESPACE_DECL 节点。在 2731 行, cp_parser_unqualified_id 将返回绑定在该作用域中的 IDENTIFIER_NODE 节点。不过, IDNETIFIER_NODE 并不是我们期望的。这里我们需要 TEMPLATE_DECL 节点。因此这个名字由 cp_parser_lookup_name 来查找以返回期望的节点。
5.12.4.1.1.2.1. 名字查找的细节
函数 cp_parser_lookup_name 在中间树中查找指定的名字。不过对于依赖类型( dependent type ),不能应用普通的名字查找,因为类型仍然未知。
对于这个函数最后 4 个参数控制查找的过程:
如果 is_type 是 true ,忽略不是引用类型的绑定。
如果 it_template 是 true ,忽略不是引用模板的绑定。
如果 is_namespace 是 true ,忽略不是引用名字空间的绑定。
如果 check_dependency 是 true ,不在依赖类型内查找名字。
除了过滤掉不期望的结果,函数还需要检查重复对象。
13692 static tree
13693 cp_parser_lookup_name (cp_parser *parser, tree name, in parser.c
13694 bool is_type, bool is_template, bool is_namespace,
13695 bool check_dependency)
13696 {
13697 int flags = 0;
13698 tree decl;
13699 tree object_type = parser->context->object_type;
13700
13701 /* Now that we have looked up the name, the OBJECT_TYPE (if any) is
13702 no longer valid. Note that if we are parsing tentatively, and
13703 the parse fails, OBJECT_TYPE will be automatically restored. */
13704 parser->context->object_type = NULL_TREE;
13705
13706 if (name == error_mark_node)
13707 return error_mark_node;
13708
13709 if (!cp_parser_parsing_tentatively (parser)
13710 || cp_parser_committed_to_tentative_parse (parser))
13711 flags |= LOOKUP_COMPLAIN;
13712
13713 /* A template-id has already been resolved; there is no lookup to
13714 do. */
13715 if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
13716 return name;
13717 if (BASELINK_P (name))
13718 {
13719 my_friendly_assert ((TREE_CODE (BASELINK_FUNCTIONS (name))
13720 == TEMPLATE_ID_EXPR),
13721 20020909);
13722 return name;
13723 }
13724
13725 /* A BIT_NOT_EXPR is used to represent a destructor. By this point,
13726 it should already have been checked to make sure that the name
13727 used matches the type being destroyed. */
13728 if (TREE_CODE (name) == BIT_NOT_EXPR)
13729 {
13730 tree type;
13731
13732 /* Figure out to which type this destructor applies. */
13733 if (parser->scope)
13734 type = parser->scope;
13735 else if (object_type)
13736 type = object_type;
13737 else
13738 type = current_class_type ;
13739 /* If that's not a class type, there is no destructor. */
13740 if (!type || !CLASS_TYPE_P (type))
13741 return error_mark_node;
13742 if (!CLASSTYPE_DESTRUCTORS (type))
13743 return error_mark_node;
13744 /* If it was a class type, return the destructor. */
13745 return CLASSTYPE_DESTRUCTORS (type);
13746 }
注意 13719 行的断言,如果找到了 BASELINK (这是对一个或一组基类的成员函数的引用。 BASELINK_FUNCTIONS 根据这些函数给出对应的 FUNCTION_DECL , TEMPLATE_DECL , OVERLOAD 或 TEMPLATE_ID_EXPR 节点),它必须指向一个 template-id-expr 。为什么? 考虑:
struct A { void f(); };
struct B: public A {};
B b;
b.f();
BASELINK 节点将为“ b.f() ”而构建,因为“ b.f() ”实际上是“ a.f() ”,但这是名字查找的结果。这个 BASELINK 不会在查找过程中出现。
而对于析构函数,如果在类外部,它必须或者是 nested-name-specifier ,或者是声明符(即,“ a.~A() ”或“ A::~A() ”)。在解析“ a. ”或“ A:: ”部分之后(通常由前一次 cp_parser_lookup_name 来完成),将填充 parser 的 scope (对于“ A:: ”)或 object_type (对于“ a. ”)域。否则,它应该在当前类中,该由 current_class_type 所指向。在 13745 行, CLASSTYPE_DESTRUCTORS 返回这个析构函数。
5.12.4.1.1.2.1.1. 在指定域中查找
parser 的 scope 域表示进行名字查找的区域。如果是 NULL_TREE ,那么我们要在源程序中当前打开的作用域内查找名字。如果不是 NULL ,它是一个代表所要查找的作用域的 *_TYPE 或者 NAMESPACE_DECL 节点。
cp_parser_lookup_name (continue)
13754 /* Perform the lookup. */
13755 if (parser->scope)
13756 {
13757 bool dependent_p;
13758
13759 if (parser->scope == error_mark_node)
13760 return error_mark_node;
13761
13762 /* If the SCOPE is dependent, the lookup must be deferred until
13763 the template is instantiated -- unless we are explicitly
13764 looking up names in uninstantiated templates. Even then, we
13765 cannot look up the name if the scope is not a class type; it
13766 might, for example, be a template type parameter. */
13767 dependent_p = (TYPE_P (parser->scope)
13768 && !(parser->in_declarator_p
13769 && currently_open_class (parser->scope))
13770 && dependent_type_p (parser->scope));
13771 if ((check_dependency || !CLASS_TYPE_P (parser->scope))
13772 && dependent_p)
13773 {
13774 if (is_type)
13775 /* The resolution to Core Issue 180 says that `struct A::B'
13776 should be considered a type-name, even if `A' is
13777 dependent. */
13778 decl = TYPE_NAME (make_typename_type (parser->scope,
13779 name,
13780 /*complain=*/ 1));
13781 else if (is_template)
13782 decl = make_unbound_class_template (parser->scope,
13783 name,
13784 /*complain=*/ 1);
13785 else
13786 decl = build_nt (SCOPE_REF, parser->scope, name);
13787 }
如果 parser 的 scope 域是依赖的,查找的结果依赖于传入函数的查找控制标志,不过注意在 is_type , is_template , is_namespace 标志中,在调用时,最多设置一个标志。
如果我们正在查找类型,这里有所谓的 Core Iusse 180 问题。其具体描述在 http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#180 。
180. typename 及阐述类型( elaborated types ) Section: 14.7 [temp.res] Status: CD1 Submitter: Mike Miller Date: 21 Dec 1999 [Moved to DR at 4/02 meeting.] Mike Miller : 在对 issue 68 的讨论中,提及了一个关于 typename 的问题。在一定程度上,它与在一个能明确知道要求一个类型的上下文中忽略 typename 的这个想法相关。考虑: template <class T> class X { friend class T::nested; }; 这里要求 typename 吗?如果是这样,它应该出现在哪里呢?(语法看起来不允许它出现在一个具有 class-key 的 elaborated-type-specifier 里)。 Bill Gibbons : class 应用到限定名中的最后一个标识符,因为所有之前的名字必须是 类或者名字空间。因为这个名字被限定为作为一个类,它不需要 typename 。 [ 不过, ] 看起来 14.7 [temp.res] 的段落 3 要求 typename 并且后面的段落没有豁免这个情况。这是我们所不同意的。 Proposed resolution (04/01): 在 14.7 [temp.res] 段落 5 ,修改 关键字 typename 在一个 base-specifier 或 mem-initializer 中是不被允许的,在这些上下文中一个依赖于一个 template-parameter ( 14.7.2 [temp.dep] )的限定名( qualified-name )隐含地假定为是一个类型的名字。 为 一个在 mem-initializer-id , base-specifier ,或 elaborated-type-specifier (以 class-key 及 enum 形式)中用作名字的限定名隐含地假定为命名一个类型,而不需要关键字 typename 。 [ 注意:关键字 typename 不为这些结构的句法( syntax )所不允许 ] ( issue 254 的期望的解决方案将从 elaborated-type-specifier 的语法中移去那个 typename 的形式。如果这个解决方案被采纳,在先前措辞中的括号短语“ ( 以 class-key 及 enum 形式 ) ”将被移去,因为那将是仅有的 elaborated-type-specifier 形式)。 |
简而言之, A::B 如果 A 是依赖性的, B 将被认为是 typename 。而如果 is_template 是 true ,它就是由【 3 】,条款 14.2 “模板特化的名字( Names of template specializations )”,条件 4 。
当一个成员模板特化的名字,在一个 postfix-expression 中出现在“ . ”或“ -> ”之后,或在一个 qualified-id 中出现在 nested-name-specifier 之后,并且该 postfix-expression 或 qualified-id 明确地依赖于一个模板参数,该成员模板的名字必须以关键字 template 为前缀。否则该名字被假定为一个非模板。例如:
class X { public : template <size_t> X* alloc(); template <size_t> static X* adjust(); }; template <class T> void f(T* p) { T* p1 = p->alloc<200>(); // ill-formed: < means less than T* p2 = p->template alloc<200>(); // OK: < starts template argument list T::adjust<100>(); // ill-formed: < means less than T::template adjust<100>(); // OK: < starts template argument list } |
在这个例子中,形如:“ T::template adjust<100>(); ”的表达式,是这里由 make_unbound_class_template 处理的目标。
2724 tree
2725 make_unbound_class_template (tree context, tree name, tsubst_flags_t complain) in decl.c
2726 {
2727 tree t;
2728 tree d;
2729
2730 if (TYPE_P (name))
2731 name = TYPE_IDENTIFIER (name);
2732 else if (DECL_P (name))
2733 name = DECL_NAME (name);
2734 if (TREE_CODE (name) != IDENTIFIER_NODE)
2735 abort ();
2736
2737 if (!dependent_type_p (context)
2738 || currently_open_class (context))
2739 {
2740 tree tmpl = NULL_TREE;
2741
2742 if (IS_AGGR_TYPE (context))
2743 tmpl = lookup_field (context, name, 0, false);
2744
2745 if (!tmpl || !DECL_CLASS_TEMPLATE_P (tmpl))
2746 {
2747 if (complain & tf_error)
2748 error ("no class template named `%#T' in `%#T'", name, context);
2749 return error_mark_node;
2750 }
2751
2752 if (complain & tf_error)
2753 perform_or_defer_access_check (TYPE_BINFO (context), tmpl);
2754
2755 return tmpl;
2756 }
2757
2758 /* Build the UNBOUND_CLASS_TEMPLATE. */
2759 t = make_aggr_type (UNBOUND_CLASS_TEMPLATE);
2760 TYPE_CONTEXT (t) = FROB_CONTEXT (context);
2761 TREE_TYPE (t) = NULL_TREE;
2762
2763 /* Build the corresponding TEMPLATE_DECL. */
2764 d = build_decl (TEMPLATE_DECL, name, t);
2765 TYPE_NAME (TREE_TYPE (d)) = d;
2766 TYPE_STUB_DECL (TREE_TYPE (d)) = d;
2767 DECL_CONTEXT (d) = FROB_CONTEXT (context);
2768 DECL_ARTIFICIAL (d) = 1;
2769
2770 return t;
2771 }
在 2743 行, lookup_field 在里面调用 lookup_member ,它返回 NULL 如果找到的是函数( function )而不是方法( member )。看到在上面的表达式中,如果“ T ”不是依赖的,或者它是当前打开的类,这个表达式就是错误的,除非“ adjust ”是一个类模板。
否则,如果 T 是依赖性的并且不是当前打开的, UNBOUND_CLASS_TEMPLATE 为之构建。它被命名为 UNBOUND ,因为类似“ T ”的上下文仍然是未知的。
而在 cp_parser_lookup_name 的 13785 行,如果不期待类型或者模板,那么将它作为普通的 SCOPE_REF 来处理。
cp_parser_lookup_name (continue)
13788 else
13789 {
13790 bool pop_p = false;
13791
13792 /* If PARSER->SCOPE is a dependent type, then it must be a
13793 class type, and we must not be checking dependencies;
13794 otherwise, we would have processed this lookup above. So
13795 that PARSER->SCOPE is not considered a dependent base by
13796 lookup_member, we must enter the scope here. */
13797 if (dependent_p)
13798 pop_p = push_scope (parser->scope);
13799 /* If the PARSER->SCOPE is a a template specialization, it
13800 may be instantiated during name lookup. In that case,
13801 errors may be issued. Even if we rollback the current
13802 tentative parse, those errors are valid. */
13803 decl = lookup_qualified_name (parser->scope, name, is_type,
13804 /*complain=*/ true);
13805 if (pop_p)
13806 pop_scope (parser->scope);
13807 }
13808 parser->qualifying_scope = parser->scope;
13809 parser->object_scope = NULL_TREE;
13810 }
如果 scope 不是依赖的,它构成了限定名。函数 lookup_qualified_name 执行名字解析。
3775 tree
3776 lookup_qualified_name (tree scope, tree name, bool is_type_p, bool complain) in name-lookup.c
3777 {
3778 int flags = 0;
3779
3780 if (TREE_CODE (scope) == NAMESPACE_DECL)
3781 {
3782 cxx_binding binding;
3783
3784 cxx_binding_clear (&binding);
3785 flags |= LOOKUP_COMPLAIN;
3786 if (is_type_p)
3787 flags |= LOOKUP_PREFER_TYPES;
3788 if (qualified_lookup_using_namespace (name, scope, &binding, flags))
3789 return select_decl (&binding, flags);
3790 }
3791 else if (is_aggr_type (scope, complain))
3792 {
3793 tree t;
3794 t = lookup_member (scope, name, 0, is_type_p);
3795 if (t)
3796 return t;
3797 }
3798
3799 return error_mark_node;
3800 }
根据指定的作用域的性质不同,查找分为以下 2 种。
5.12.4.1.1.2.1.1.1. 在指定名字空间中的查找
如果指定的作用域是名字空间,那么查找工作由下面的函数接手。
3835 static bool
3836 qualified_lookup_using_namespace (tree name, tree scope, in name-lookup.c
3837 cxx_binding *result, int flags)
3838 {
3839 /* Maintain a list of namespaces visited... */
3840 tree seen = NULL_TREE;
3841 /* ... and a list of namespace yet to see. */
3842 tree todo = NULL_TREE;
3843 tree todo_maybe = NULL_TREE;
3844 tree usings;
3845 timevar_push (TV_NAME_LOOKUP);
3846 /* Look through namespace aliases. */
3847 scope = ORIGINAL_NAMESPACE (scope);
3848 while (scope && result->value != error_mark_node)
3849 {
3850 cxx_binding *binding =
3851 cxx_scope_find_binding_for_name (NAMESPACE_LEVEL (scope), name);
3852 seen = tree_cons (scope, NULL_TREE, seen);
3853 if (binding)
3854 result = ambiguous_decl (name, result, binding, flags);
3855
3856 /* Consider strong using directives always, and non-strong ones
3857 if we haven't found a binding yet. ??? Shouldn't we consider
3858 non-strong ones if the initial RESULT is non-NULL, but the
3859 binding in the given namespace is? */
3860 for (usings = DECL_NAMESPACE_USING (scope); usings;
3861 usings = TREE_CHAIN (usings))
3862 /* If this was a real directive, and we have not seen it. */
3863 if (!TREE_INDIRECT_USING (usings))
3864 {
3865 /* Try to avoid queuing the same namespace more than once,
3866 the exception being when a namespace was already
3867 enqueued for todo_maybe and then a strong using is
3868 found for it. We could try to remove it from
3869 todo_maybe, but it's probably not worth the effort. */
3870 if (is_associated_namespace (scope, TREE_PURPOSE (usings))
3871 && !purpose_member (TREE_PURPOSE (usings), seen)
3872 && !purpose_member (TREE_PURPOSE (usings), todo))
3873 todo = tree_cons (TREE_PURPOSE (usings), NULL_TREE, todo);
3874 else if ((!result->value && !result->type)
3875 && !purpose_member (TREE_PURPOSE (usings), seen)
3876 && !purpose_member (TREE_PURPOSE (usings), todo)
3877 && !purpose_member (TREE_PURPOSE (usings), todo_maybe))
3878 todo_maybe = tree_cons (TREE_PURPOSE (usings), NULL_TREE,
3879 todo_maybe);
3880 }
3881 if (todo)
3882 {
3883 scope = TREE_PURPOSE (todo);
3884 todo = TREE_CHAIN (todo);
3885 }
3886 else if (todo_maybe
3887 && (!result->value && !result->type))
3888 {
3889 scope = TREE_PURPOSE (todo_maybe);
3890 todo = TREE_CHAIN (todo_maybe);
3891 todo_maybe = NULL_TREE;
3892 }
3893 else
3894 scope = NULL_TREE; /* If there never was a todo list. */
3895 }
3896 POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, result->value != error_mark_node);
3897 }
如果在该名字空间查不出这个名字,在 3860 行的 FOR 循环处理在该名字空间中的“ using namespace xxx ”语句。看到在 3883 及 3889 行,“ using namespace xxx ”中的名字空间“ xxx ”被设置入 scope ,进入回到 3848 行 WHILE 循环开头,通过 cxx_scope_find_binding_for_name 来查找名字。
在一个作用域域中,如果可以同时看到同名的多个声明,则需要检查是否发生了错误。
3474 static cxx_binding *
3475 ambiguous_decl (tree name, cxx_binding *old, cxx_binding *new, int flags) in name-lookup.c
3476 {
3477 tree val, type;
3478 my_friendly_assert (old != NULL, 393);
3479 /* Copy the value. */
3480 val = new->value;
3481 if (val)
3482 switch (TREE_CODE (val))
3483 {
3484 case TEMPLATE_DECL:
3485 /* If we expect types or namespaces, and not templates,
3486 or this is not a template class. */
3487 if (LOOKUP_QUALIFIERS_ONLY (flags)
3488 && !DECL_CLASS_TEMPLATE_P (val))
3489 val = NULL_TREE;
3490 break ;
3491 case TYPE_DECL:
3492 if (LOOKUP_NAMESPACES_ONLY (flags))
3493 val = NULL_TREE;
3494 break ;
3495 case NAMESPACE_DECL:
3496 if (LOOKUP_TYPES_ONLY (flags))
3497 val = NULL_TREE;
3498 break ;
3499 case FUNCTION_DECL:
3500 /* Ignore built-in functions that are still anticipated. */
3501 if (LOOKUP_QUALIFIERS_ONLY (flags) || DECL_ANTICIPATED (val))
3502 val = NULL_TREE;
3503 break ;
3504 default :
3505 if (LOOKUP_QUALIFIERS_ONLY (flags))
3506 val = NULL_TREE;
3507 }
在指定的名字空间中,所谓的二义性发生在出现一个以上同名的同一类的声明时。比如,变量和函数可以同名,而不会导致二义性。因为在引用点,编译器能识别出是函数还是变量。因此函数 ambiguous_decl 首先滤掉不期望的结果。上面用到的宏的定义如下。
3366 #define LOOKUP_PREFER_BOTH (LOOKUP_PREFER_TYPES | LOOKUP_PREFER_NAMESPACES)
3369 #define LOOKUP_NAMESPACES_ONLY(F) / in cp-tree.h
3370 (((F) & LOOKUP_PREFER_NAMESPACES) && !((F) & LOOKUP_PREFER_TYPES))
3371 #define LOOKUP_TYPES_ONLY(F) /
3372 (!((F) & LOOKUP_PREFER_NAMESPACES) && ((F) & LOOKUP_PREFER_TYPES))
3373 #define LOOKUP_QUALIFIERS_ONLY(F) ((F) & LOOKUP_PREFER_BOTH)
ambiguous_decl (continue)
3509 if (!old->value)
3510 old->value = val;
3511 else if (val && val != old->value)
3512 {
3513 if (is_overloaded_fn (old->value) && is_overloaded_fn (val))
3514 old->value = merge_functions (old->value, val);
3515 else
3516 {
3517 /* Some declarations are functions, some are not. */
3518 if (flags & LOOKUP_COMPLAIN)
3519 {
3520 /* If we've already given this error for this lookup,
3521 old->value is error_mark_node, so let's not
3522 repeat ourselves. */
3523 if (old->value != error_mark_node)
3524 {
3525 error ("use of `%D' is ambiguous", name);
3526 cp_error_at (" first declared as `%#D' here",
3527 old->value);
3528 }
3529 cp_error_at (" also declared as `%#D' here", val);
3530 }
3531 old->value = error_mark_node;
3532 }
3533 }
3534 /* ... and copy the type. */
3535 type = new->type;
3536 if (LOOKUP_NAMESPACES_ONLY (flags))
3537 type = NULL_TREE;
3538 if (!old->type)
3539 old->type = type;
3540 else if (type && old->type != type)
3541 {
3542 if (flags & LOOKUP_COMPLAIN)
3543 {
3544 error ("`%D' denotes an ambiguous type",name);
3545 error ("%J first type here", TYPE_MAIN_DECL (old->type));
3546 error ("%J other type here", TYPE_MAIN_DECL (type));
3547 }
3548 }
3549 return old;
3550 }
在指定名字空间中一个以上同类同名的声明意味着二义性,即编译器无从选择。除非有其他信息能帮助编译器进行抉择。典型的例子有函数重载,及模板的具现,引用时的函数实参列表及模板实参列表,使得编译器可以从一组候选者中挑出最合适的一个(如果没有最合适者,但有候选者,即引发二义性错误)。对于可以重载的声明,必须把所有的这些声明记录起来。
852 int
853 is_overloaded_fn (tree x) in tree.c
854 {
855 /* A baselink is also considered an overloaded function. */
856 if (TREE_CODE (x) == OFFSET_REF)
857 x = TREE_OPERAND (x, 1);
858 if (BASELINK_P (x))
859 x = BASELINK_FUNCTIONS (x);
860 return (TREE_CODE (x) == FUNCTION_DECL
861 || TREE_CODE (x) == TEMPLATE_ID_EXPR
862 || DECL_FUNCTION_TEMPLATE_P (x)
863 || TREE_CODE (x) == OVERLOAD);
864 }
那么函数 merge_functions 检查声明是否重复,并把非重复的声明加入重载记录。
3437 static tree
3438 merge_functions (tree s1, tree s2) in name-lookup.c
3439 {
3440 for (; s2; s2 = OVL_NEXT (s2))
3441 {
3442 tree fn2 = OVL_CURRENT (s2);
3443 tree fns1;
3444
3445 for (fns1 = s1; fns1; fns1 = OVL_NEXT (fns1))
3446 {
3447 tree fn1 = OVL_CURRENT (fns1);
3448
3449 /* If the function from S2 is already in S1, there is no
3450 need to add it again. For `extern "C"' functions, we
3451 might have two FUNCTION_DECLs for the same function, in
3452 different namespaces; again, we only need one of them. */
3453 if (fn1 == fn2
3454 || (DECL_EXTERN_C_P (fn1) && DECL_EXTERN_C_P (fn2)
3455 && DECL_NAME (fn1) == DECL_NAME (fn2)))
3456 break ;
3457 }
3458
3459 /* If we exhausted all of the functions in S1, FN2 is new. */
3460 if (!fns1)
3461 s1 = build_overload (fn2, s1);
3462 }
3463 return s1;
3464 }
上面,注意对于普通的函数( FUNCTION_DECL 节点), OVL_CURRENT 返回节点本身,而 OVL_NEXT 返回 NULL 。因此看到如果 s2 是 FUNCTION_DECL 并且尚未记录在 s1 中,那么在 3461 行, fn2 是 s2 。
916 tree
917 build_overload (tree decl, tree chain) in tree.c
918 {
919 if (! chain && TREE_CODE (decl) != TEMPLATE_DECL)
920 return decl;
921 if (chain && TREE_CODE (chain) != OVERLOAD)
922 chain = ovl_cons (chain, NULL_TREE);
923 return ovl_cons (decl, chain);
924 }
在上面的函数中,看到如果 chain 是 NULL 而且 decl 是 TEMPLATE_DECL ,将执行 923 行的代码,为一个新链表构建头节点。重载对象将被 tree_overload 类型的链表所记录。
306 struct tree_overload GTY(()) in cp-tree.h
307 {
308 struct tree_common common;
309 tree function;
310 };
而函数 ovl_cons 构建这些节点并依序串接它们。
902 tree
903 ovl_cons (tree decl, tree chain) in tree.c
904 {
905 tree result = make_node (OVERLOAD);
906 TREE_TYPE (result) = unknown_type_node;
907 OVL_FUNCTION (result) = decl;
908 TREE_CHAIN (result) = chain;
909
910 return result;
911 }
在 qualified_lookup_using_namespace 中,注意在“ using namespace xxx ”语句所指定的名字空间中的声明不在二义性检查之列,除非是“ using namespace xxx __attribute ((strong)) ”所引入的名字空间关联( namespace association )。