Commit 653cc74a by Jason Merrill Committed by Jason Merrill

Handle multi-level typenames and implicit typename in base list.

	* parse.y (typename_sub{,[0-2]}): New rules.
	(structsp, rule TYPENAME_KEYWORD): Use typename_sub.
	(nonnested_type): New rule.
	(complete_type_name): Use it.
	(base_class.1): Use typename_sub and nonnested_type.
	(nested_name_specifier): Don't elide std:: here.
	* decl.c (make_typename_type): Handle getting a type for NAME.
	(lookup_name_real): Turn std:: into :: here.

	Rvalue conversions were removed in London.
	* call.c (is_subseq): Don't consider lvalue transformations.
	(build_conv): LVALUE_CONV and RVALUE_CONV get IDENTITY_RANK.
	(joust): Reenable ?: kludge.

From-SVN: r15715
parent 6d4312dd
Thu Sep 25 11:11:13 1997 Jason Merrill <jason@yorick.cygnus.com>
Handle multi-level typenames and implicit typename in base list.
* parse.y (typename_sub{,[0-2]}): New rules.
(structsp, rule TYPENAME_KEYWORD): Use typename_sub.
(nonnested_type): New rule.
(complete_type_name): Use it.
(base_class.1): Use typename_sub and nonnested_type.
(nested_name_specifier): Don't elide std:: here.
* decl.c (make_typename_type): Handle getting a type for NAME.
(lookup_name_real): Turn std:: into :: here.
Rvalue conversions were removed in London.
* call.c (is_subseq): Don't consider lvalue transformations.
(build_conv): LVALUE_CONV and RVALUE_CONV get IDENTITY_RANK.
(joust): Reenable ?: kludge.
1997-09-22 Brendan Kehoe <brendan@lisa.cygnus.com>
* decl.c (start_function): Up warning of no return type to be a
......
......@@ -3021,9 +3021,7 @@ build_conv (code, type, from)
rank = STD_RANK;
break;
case LVALUE_CONV:
case QUAL_CONV:
case RVALUE_CONV:
if (rank < EXACT_RANK)
rank = EXACT_RANK;
......@@ -5649,6 +5647,11 @@ static int
is_subseq (ics1, ics2)
tree ics1, ics2;
{
/* Do not consider lvalue transformations here. */
if (TREE_CODE (ics2) == RVALUE_CONV
|| TREE_CODE (ics2) == LVALUE_CONV)
return 0;
for (;; ics2 = TREE_OPERAND (ics2, 0))
{
if (TREE_CODE (ics2) == TREE_CODE (ics1)
......@@ -6084,10 +6087,10 @@ joust (cand1, cand2)
break;
if (i == TREE_VEC_LENGTH (cand1->convs))
return 1;
#if 0
/* Kludge around broken overloading rules whereby
bool ? void *const & : void *const & is ambiguous. */
/* Huh? Explain the problem better. */
Integer a, b; test ? a : b; is ambiguous, since there's a builtin
that takes references and another that takes values. */
if (cand1->fn == ansi_opname[COND_EXPR])
{
tree c1 = TREE_VEC_ELT (cand1->convs, 1);
......@@ -6103,7 +6106,6 @@ joust (cand1, cand2)
return -1;
}
}
#endif
}
tweak:
......
......@@ -4317,7 +4317,9 @@ make_typename_type (context, name)
{
tree t, d;
if (TREE_CODE (name) == TYPE_DECL)
if (TREE_CODE_CLASS (TREE_CODE (name)) == 't')
name = TYPE_IDENTIFIER (name);
else if (TREE_CODE (name) == TYPE_DECL)
name = DECL_NAME (name);
else if (TREE_CODE (name) != IDENTIFIER_NODE)
my_friendly_abort (2000);
......@@ -4378,6 +4380,10 @@ lookup_name_real (name, prefer_type, nonclass)
yylex = 1;
prefer_type = looking_for_typename;
/* std:: becomes :: for now. */
if (got_scope == std_node)
got_scope = void_type_node;
if (got_scope)
type = got_scope;
else if (got_object != error_mark_node)
......
......@@ -258,12 +258,12 @@ empty_parms ()
%type <ttype> template_type template_arg_list template_arg
%type <ttype> condition xcond paren_cond_or_null
%type <ttype> type_name nested_name_specifier nested_type ptr_to_mem
%type <ttype> complete_type_name notype_identifier
%type <ttype> complete_type_name notype_identifier nonnested_type
%type <ttype> complex_type_name nested_name_specifier_1
%type <itype> nomods_initdecls nomods_initdcl0
%type <ttype> new_initializer new_placement
%type <ttype> using_decl .poplevel
%type <ttype> typename_sub typename_sub0 typename_sub1 typename_sub2
/* in order to recognize aggr tags as defining and thus shadowing. */
%token TYPENAME_DEFN IDENTIFIER_DEFN PTYPENAME_DEFN
%type <ttype> named_class_head_sans_basetype_defn
......@@ -2190,11 +2190,8 @@ structsp:
| ENUM complex_type_name
{ $$.t = xref_tag (enum_type_node, $2, NULL_TREE, 1);
$$.new_type_flag = 0; }
| TYPENAME_KEYWORD nested_name_specifier identifier
{ $$.t = make_typename_type ($2, $3);
$$.new_type_flag = 0; }
| TYPENAME_KEYWORD global_scope nested_name_specifier identifier
{ $$.t = make_typename_type ($3, $4);
| TYPENAME_KEYWORD typename_sub
{ $$.t = $2;
$$.new_type_flag = 0; }
/* C++ extensions, merged with C to avoid shift/reduce conflicts */
| class_head left_curly opt.component_decl_list '}' maybe_attribute
......@@ -2437,11 +2434,8 @@ base_class:
;
base_class.1:
complete_type_name
| TYPENAME_KEYWORD nested_name_specifier identifier
{ $$ = TYPE_MAIN_DECL (make_typename_type ($2, $3)); }
| TYPENAME_KEYWORD global_scope nested_name_specifier identifier
{ $$ = TYPE_MAIN_DECL (make_typename_type ($3, $4)); }
typename_sub
| nonnested_type
| SIGOF '(' expr ')'
{
if (current_aggr == signature_type_node)
......@@ -2945,7 +2939,7 @@ after_type_declarator:
| direct_after_type_declarator
;
complete_type_name:
nonnested_type:
type_name %prec EMPTY
{
if (TREE_CODE ($1) == IDENTIFIER_NODE)
......@@ -2974,6 +2968,10 @@ complete_type_name:
$$ = $2;
got_scope = NULL_TREE;
}
;
complete_type_name:
nonnested_type
| nested_type
| global_scope nested_type
{ $$ = $2; }
......@@ -3119,11 +3117,7 @@ nested_name_specifier_1:
{
if (TREE_CODE ($$) == IDENTIFIER_NODE)
$$ = lastiddecl;
if (TREE_CODE ($$) == NAMESPACE_DECL
&& DECL_NAME ($$) == get_identifier ("std"))
got_scope = void_type_node;
else
got_scope = $$;
got_scope = $$;
}
| template_type SCOPE
{ got_scope = $$ = complete_type (TREE_TYPE ($1)); }
......@@ -3139,6 +3133,66 @@ nested_name_specifier_1:
{ goto failed_scope; } */
;
typename_sub:
typename_sub0
| global_scope typename_sub0
{ $$ = $2; }
;
typename_sub0:
typename_sub1 identifier
{
if (TREE_CODE_CLASS (TREE_CODE ($1)) == 't')
$$ = make_typename_type ($1, $2);
else if (TREE_CODE ($2) == IDENTIFIER_NODE)
cp_error ("`%T' is not a class or namespace", $2);
else
$$ = $2;
}
;
typename_sub1:
typename_sub2
{
if (TREE_CODE ($1) == IDENTIFIER_NODE)
cp_error ("`%T' is not a class or namespace", $1);
}
| typename_sub1 typename_sub2
{
if (TREE_CODE_CLASS (TREE_CODE ($1)) == 't')
$$ = make_typename_type ($1, $2);
else if (TREE_CODE ($2) == IDENTIFIER_NODE)
cp_error ("`%T' is not a class or namespace", $2);
else
$$ = $2;
}
;
typename_sub2:
TYPENAME SCOPE
{
if (TREE_CODE ($1) != IDENTIFIER_NODE)
$$ = lastiddecl;
got_scope = $$ = complete_type (TREE_TYPE ($$));
}
| SELFNAME SCOPE
{
if (TREE_CODE ($1) != IDENTIFIER_NODE)
$$ = lastiddecl;
got_scope = $$ = complete_type (TREE_TYPE ($$));
}
| template_type SCOPE
{ got_scope = $$ = complete_type (TREE_TYPE ($$)); }
| PTYPENAME SCOPE
| IDENTIFIER SCOPE
| NSNAME SCOPE
{
if (TREE_CODE ($$) == IDENTIFIER_NODE)
$$ = lastiddecl;
got_scope = $$;
}
;
complex_type_name:
global_scope type_name
{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment