diff options
author | Jason Merrill <jason@yorick.cygnus.com> | 1997-09-25 18:56:40 +0000 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 1997-09-25 14:56:40 -0400 |
commit | 653cc74afc6785458eee2791fde774fb23ec3d8f (patch) | |
tree | 0e2ab47b18732e9a6b88e92e405a180726d99a24 /gcc | |
parent | 6d4312ddbf30f452fd9c93254e0be63c4fcbda9a (diff) | |
download | gcc-653cc74afc6785458eee2791fde774fb23ec3d8f.zip gcc-653cc74afc6785458eee2791fde774fb23ec3d8f.tar.gz gcc-653cc74afc6785458eee2791fde774fb23ec3d8f.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 17 | ||||
-rw-r--r-- | gcc/cp/call.c | 14 | ||||
-rw-r--r-- | gcc/cp/decl.c | 8 | ||||
-rw-r--r-- | gcc/cp/parse.y | 90 |
4 files changed, 104 insertions, 25 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index b33c996..c5e34ac 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,20 @@ +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 diff --git a/gcc/cp/call.c b/gcc/cp/call.c index a080c04..6855181 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -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: diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index e60cef6..df8066b 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -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) diff --git a/gcc/cp/parse.y b/gcc/cp/parse.y index 7d9d5db..16e5db9 100644 --- a/gcc/cp/parse.y +++ b/gcc/cp/parse.y @@ -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 { |