2017-06-22 Nathan Sidwell Reorder IDENTIFIER flags gcc/cp/ * cp-tree.h (enum cp_identifier_kind): New. (IDENTIFIER_KIND_BIT_0, IDENTIFIER_KIND_BIT_1, IDENTIFIER_KIND_BIT_2): New. (IDENTIFIER_MARKED): Move to TREE_LANG_FLAG_4. (IDENTIFIER_VIRTUAL_P, IDENTIFIER_REPO_CHOSEN): Add IDENTIFIER_CHECK. (C_IS_RESERVED_WORD): Replace with ... (IDENTIFIER_KEYWORD_P): ... this. (IDENTIFIER_CTOR_OR_DTOR_P): Replace with ... (IDENTIFIER_CDTOR_P): ... this. (IDENTIFIER_CTOR_P, IDENTIFIER_DTOR_P): New. (IDENTIFIER_OPNAME_P): Replace with ... (IDENTIFIER_ANY_OP_P): ... this. (IDENTIFIER_ASSIGN_OP_P): New. (IDENTIFIER_TYPENAME_P): Replace with ... (IDENTIFIER_CONV_OP_P): ... this. (NEW_DELETE_OPNAME_P): Replace with ... (IDENTIFIER_NEWDEL_OP_P): ... this. (DECL_CONV_FN_P, DECL_OVERLOADED_OPERATOR_P): Adjust. (get_identifier_kind_name, set_identifier_kind): Declare. * lex.c (get_identifier_kind_name, set_identifier_kind): New. (init_operators): Adjust to avoid keywords, use set_identifier_kind. Copy TYPE_EXPR slot. (init_reswords): Call set_identifier_kind. (unqualified_name_lookup_error): Adjust. * operators.def (TYPE_EXPR): Remove. * decl.c (struct predefined_identifier): Move into ... (initialize_predefined_identifiers): ... here. Call set_identifier_kind. (grokfndecl, check_var_type, grokdeclarator): Adjust. (grok_op_properties): Use IDENTIFIER_ANY_ASSIGN_OP to halve search space. Adjust. * call.c (name_as_c_string): Adjust. (build_new_method_call_1): Likewise. * cp-cilkplus.c (is_conversion_operator_function_decl_p): Likewise. * cxx-pretty-print.c (pp_cxx_unqualified_id): Adjust. * dump.c (cp_dump_tree): Adjust. * error.c (dump_decl_name): Adjust. * mangle.c (write_unqualified_id, write_member_name, write_expression): Adjust. (mangle_conv_op_name_for_type): Use set_identifier_kind. * name-lookup.c (do_class_using_decl): Adjust. (lookup_name_fuzzy, lookup_name_real_1): Likewise. * parser.c (cp_lexer_get_preprocessor_token, cp_parser_direct_declarator): Likewise. * pt.c (push_template_decl_real, tsubst_decl, tsubst_baselink, tsubst_copy, tsubst_copy_and_build): Adjust. * ptree.c (cxx_print_identifier): Print identifier kind. * search.c (lookup_field_r, lookup_member, lookup_fnfields_idx_nolazy): Adjust. * semantics.c (finish_id_expression): Adjust.. * typeck.c (cp_build_addr_expr_1): Adjust. Index: call.c =================================================================== --- call.c (revision 249569) +++ call.c (working copy) @@ -8884,21 +8884,19 @@ name_as_c_string (tree name, tree type, /* Assume that we will not allocate memory. */ *free_p = false; /* Constructors and destructors are special. */ - if (IDENTIFIER_CTOR_OR_DTOR_P (name)) + if (IDENTIFIER_CDTOR_P (name)) { pretty_name = CONST_CAST (char *, identifier_to_locale (IDENTIFIER_POINTER (constructor_name (type)))); /* For a destructor, add the '~'. */ - if (name == complete_dtor_identifier - || name == base_dtor_identifier - || name == deleting_dtor_identifier) + if (IDENTIFIER_DTOR_P (name)) { pretty_name = concat ("~", pretty_name, NULL); /* Remember that we need to free the memory allocated. */ *free_p = true; } } - else if (IDENTIFIER_TYPENAME_P (name)) + else if (IDENTIFIER_CONV_OP_P (name)) { pretty_name = concat ("operator ", type_as_string_translate (TREE_TYPE (name), @@ -9015,7 +9013,7 @@ build_new_method_call_1 (tree instance, pointer if this is a call to a base-class constructor or destructor. */ skip_first_for_error = false; - if (IDENTIFIER_CTOR_OR_DTOR_P (name)) + if (IDENTIFIER_CDTOR_P (name)) { /* Callers should explicitly indicate whether they want to construct the complete object or just the part without virtual bases. */ @@ -9143,7 +9141,7 @@ build_new_method_call_1 (tree instance, { tree arglist = build_tree_list_vec (user_args); tree errname = name; - if (IDENTIFIER_CTOR_OR_DTOR_P (errname)) + if (IDENTIFIER_CDTOR_P (errname)) { tree fn = DECL_ORIGIN (OVL_FIRST (fns)); errname = DECL_NAME (fn); Index: cp-cilkplus.c =================================================================== --- cp-cilkplus.c (revision 249569) +++ cp-cilkplus.c (working copy) @@ -36,7 +36,7 @@ is_conversion_operator_function_decl_p ( if (TREE_CODE (t) != FUNCTION_DECL) return false; - return DECL_NAME (t) && IDENTIFIER_TYPENAME_P (DECL_NAME (t)); + return DECL_CONV_FN_P (t); } /* Recursively traverse EXP to search for a CILK_SPAWN_STMT subtree. Index: cp-tree.h =================================================================== --- cp-tree.h (revision 249569) +++ cp-tree.h (working copy) @@ -298,7 +298,7 @@ extern GTY(()) tree cp_global_trees[CPTI #include "name-lookup.h" /* Usage of TREE_LANG_FLAG_?: - 0: IDENTIFIER_MARKED (IDENTIFIER_NODEs) + 0: IDENTIFIER_KIND_BIT_0 (in IDENTIFIER_NODE) NEW_EXPR_USE_GLOBAL (in NEW_EXPR). COND_EXPR_IS_VEC_DELETE (in COND_EXPR). DELETE_EXPR_USE_GLOBAL (in DELETE_EXPR). @@ -339,7 +339,7 @@ extern GTY(()) tree cp_global_trees[CPTI IF_STMT_CONSTEXPR_P (IF_STMT) TEMPLATE_TYPE_PARM_FOR_CLASS (TEMPLATE_TYPE_PARM) DECL_NAMESPACE_INLINE_P (in NAMESPACE_DECL) - 1: IDENTIFIER_VIRTUAL_P (in IDENTIFIER_NODE) + 1: IDENTIFIER_KIND_BIT_1 (in IDENTIFIER_NODE) TI_PENDING_TEMPLATE_FLAG. TEMPLATE_PARMS_FOR_INLINE. DELETE_EXPR_USE_VEC (in DELETE_EXPR). @@ -357,7 +357,7 @@ extern GTY(()) tree cp_global_trees[CPTI TINFO_USED_TEMPLATE_ID (in TEMPLATE_INFO) PACK_EXPANSION_SIZEOF_P (in *_PACK_EXPANSION) OVL_USING_P (in OVERLOAD) - 2: IDENTIFIER_OPNAME_P (in IDENTIFIER_NODE) + 2: IDENTIFIER_KIND_BIT_2 (in IDENTIFIER_NODE) ICS_THIS_FLAG (in _CONV) DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (in VAR_DECL) STATEMENT_LIST_TRY_BLOCK (in STATEMENT_LIST) @@ -372,21 +372,20 @@ extern GTY(()) tree cp_global_trees[CPTI 3: (TREE_REFERENCE_EXPR) (in NON_LVALUE_EXPR) (commented-out). ICS_BAD_FLAG (in _CONV) FN_TRY_BLOCK_P (in TRY_BLOCK) - IDENTIFIER_CTOR_OR_DTOR_P (in IDENTIFIER_NODE) BIND_EXPR_BODY_BLOCK (in BIND_EXPR) DECL_NON_TRIVIALLY_INITIALIZED_P (in VAR_DECL) CALL_EXPR_ORDERED_ARGS (in CALL_EXPR, AGGR_INIT_EXPR) DECLTYPE_FOR_REF_CAPTURE (in DECLTYPE_TYPE) CONSTUCTOR_C99_COMPOUND_LITERAL (in CONSTRUCTOR) OVL_NESTED_P (in OVERLOAD) - 4: TREE_HAS_CONSTRUCTOR (in INDIRECT_REF, SAVE_EXPR, CONSTRUCTOR, + 4: IDENTIFIER_MARKED (IDENTIFIER_NODEs) + TREE_HAS_CONSTRUCTOR (in INDIRECT_REF, SAVE_EXPR, CONSTRUCTOR, CALL_EXPR, or FIELD_DECL). - IDENTIFIER_TYPENAME_P (in IDENTIFIER_NODE) DECL_TINFO_P (in VAR_DECL) FUNCTION_REF_QUALIFIED (in FUNCTION_TYPE, METHOD_TYPE) OVL_LOOKUP_P (in OVERLOAD) LOOKUP_FOUND_P (in RECORD_TYPE, UNION_TYPE, NAMESPACE_DECL) - 5: C_IS_RESERVED_WORD (in IDENTIFIER_NODE) + 5: IDENTIFIER_VIRTUAL_P (in IDENTIFIER_NODE) DECL_VTABLE_OR_VTT_P (in VAR_DECL) FUNCTION_RVALUE_QUALIFIED (in FUNCTION_TYPE, METHOD_TYPE) CALL_EXPR_REVERSE_ARGS (in CALL_EXPR, AGGR_INIT_EXPR) @@ -566,11 +565,6 @@ struct default_hash_traits x_auto_return_pattern) -/* True if NAME is the IDENTIFIER_NODE for an overloaded "operator - new" or "operator delete". */ -#define NEW_DELETE_OPNAME_P(NAME) \ - ((NAME) == cp_operator_id (NEW_EXPR) \ - || (NAME) == cp_operator_id (VEC_NEW_EXPR) \ - || (NAME) == cp_operator_id (DELETE_EXPR) \ - || (NAME) == cp_operator_id (VEC_DELETE_EXPR)) - #define cp_operator_id(CODE) \ (operator_name_info[(int) (CODE)].identifier) #define cp_assignment_operator_id(CODE) \ @@ -2313,9 +2359,6 @@ struct GTY(()) lang_type { /* Nonzero if this BINFO is a primary base class. */ #define BINFO_PRIMARY_P(NODE) BINFO_FLAG_5(NODE) - -/* Used by various search routines. */ -#define IDENTIFIER_MARKED(NODE) TREE_LANG_FLAG_0 (NODE) /* A vec of the vcall indices associated with the class NODE. The PURPOSE of each element is a FUNCTION_DECL for a virtual @@ -2766,7 +2809,7 @@ struct GTY(()) lang_decl { /* Nonzero if NODE is a user-defined conversion operator. */ #define DECL_CONV_FN_P(NODE) \ - (DECL_NAME (NODE) && IDENTIFIER_TYPENAME_P (DECL_NAME (NODE))) + (DECL_NAME (NODE) && IDENTIFIER_CONV_OP_P (DECL_NAME (NODE))) /* If FN is a conversion operator, the type to which it converts. Otherwise, NULL_TREE. */ @@ -2800,7 +2843,7 @@ struct GTY(()) lang_decl { value of ERROR_MARK is zero, this macro can be used as a predicate to test whether or not NODE is an overloaded operator. */ #define DECL_OVERLOADED_OPERATOR_P(NODE) \ - (IDENTIFIER_OPNAME_P (DECL_NAME (NODE)) \ + (IDENTIFIER_ANY_OP_P (DECL_NAME (NODE)) \ ? LANG_DECL_FN_CHECK (NODE)->operator_code : ERROR_MARK) /* Nonzero if NODE is an assignment operator (including += and such). */ @@ -6305,6 +6348,8 @@ extern tree copy_decl (tree CXX_MEM_S extern tree copy_type (tree CXX_MEM_STAT_INFO); extern tree cxx_make_type (enum tree_code); extern tree make_class_type (enum tree_code); +extern const char *get_identifier_kind_name (tree); +extern void set_identifier_kind (tree, cp_identifier_kind); extern bool cxx_init (void); extern void cxx_finish (void); extern bool in_main_input_context (void); Index: cxx-pretty-print.c =================================================================== --- cxx-pretty-print.c (revision 249569) +++ cxx-pretty-print.c (working copy) @@ -159,7 +159,7 @@ pp_cxx_unqualified_id (cxx_pretty_printe case IDENTIFIER_NODE: if (t == NULL) pp->translate_string (""); - else if (IDENTIFIER_TYPENAME_P (t)) + else if (IDENTIFIER_CONV_OP_P (t)) pp_cxx_conversion_function_id (pp, t); else { Index: decl.c =================================================================== --- decl.c (revision 249569) +++ decl.c (working copy) @@ -3948,62 +3948,56 @@ record_unknown_type (tree type, const ch SET_TYPE_MODE (type, TYPE_MODE (void_type_node)); } -/* A string for which we should create an IDENTIFIER_NODE at - startup. */ - -struct predefined_identifier -{ - /* The name of the identifier. */ - const char *const name; - /* The place where the IDENTIFIER_NODE should be stored. */ - tree *const node; - /* Nonzero if this is the name of a constructor or destructor. */ - const int ctor_or_dtor_p; -}; - /* Create all the predefined identifiers. */ static void initialize_predefined_identifiers (void) { - const predefined_identifier *pid; + struct predefined_identifier + { + const char *name; /* Name. */ + tree *node; /* Node to store it in. */ + cp_identifier_kind kind; /* Kind of identifier. */ + }; /* A table of identifiers to create at startup. */ static const predefined_identifier predefined_identifiers[] = { - { "C++", &lang_name_cplusplus, 0 }, - { "C", &lang_name_c, 0 }, + {"C++", &lang_name_cplusplus, cik_normal}, + {"C", &lang_name_c, cik_normal}, /* Some of these names have a trailing space so that it is impossible for them to conflict with names written by users. */ - { "__ct ", &ctor_identifier, 1 }, - { "__base_ctor ", &base_ctor_identifier, 1 }, - { "__comp_ctor ", &complete_ctor_identifier, 1 }, - { "__dt ", &dtor_identifier, 1 }, - { "__comp_dtor ", &complete_dtor_identifier, 1 }, - { "__base_dtor ", &base_dtor_identifier, 1 }, - { "__deleting_dtor ", &deleting_dtor_identifier, 1 }, - { IN_CHARGE_NAME, &in_charge_identifier, 0 }, - { THIS_NAME, &this_identifier, 0 }, - { VTABLE_DELTA_NAME, &delta_identifier, 0 }, - { VTABLE_PFN_NAME, &pfn_identifier, 0 }, - { "_vptr", &vptr_identifier, 0 }, - { "__vtt_parm", &vtt_parm_identifier, 0 }, - { "::", &global_identifier, 0 }, - { "std", &std_identifier, 0 }, + {"__ct ", &ctor_identifier, cik_ctor}, + {"__base_ctor ", &base_ctor_identifier, cik_ctor}, + {"__comp_ctor ", &complete_ctor_identifier, cik_ctor}, + {"__dt ", &dtor_identifier, cik_dtor}, + {"__comp_dtor ", &complete_dtor_identifier, cik_dtor}, + {"__base_dtor ", &base_dtor_identifier, cik_dtor}, + {"__deleting_dtor ", &deleting_dtor_identifier, cik_dtor}, + {IN_CHARGE_NAME, &in_charge_identifier, cik_normal}, + {THIS_NAME, &this_identifier, cik_normal}, + {VTABLE_DELTA_NAME, &delta_identifier, cik_normal}, + {VTABLE_PFN_NAME, &pfn_identifier, cik_normal}, + {"_vptr", &vptr_identifier, cik_normal}, + {"__vtt_parm", &vtt_parm_identifier, cik_normal}, + {"::", &global_identifier, cik_normal}, + {"std", &std_identifier, cik_normal}, /* The demangler expects anonymous namespaces to be called something starting with '_GLOBAL__N_'. It no longer needs to be unique to the TU. */ - { "_GLOBAL__N_1", &anon_identifier, 0 }, - { "auto", &auto_identifier, 0 }, - { "decltype(auto)", &decltype_auto_identifier, 0 }, - { "initializer_list", &init_list_identifier, 0 }, - { NULL, NULL, 0 } + {"_GLOBAL__N_1", &anon_identifier, cik_normal}, + {"auto", &auto_identifier, cik_normal}, + {"decltype(auto)", &decltype_auto_identifier, cik_normal}, + {"initializer_list", &init_list_identifier, cik_normal}, + {NULL, NULL, cik_normal} }; - for (pid = predefined_identifiers; pid->name; ++pid) + for (const predefined_identifier *pid = predefined_identifiers; + pid->name; ++pid) { *pid->node = get_identifier (pid->name); - if (pid->ctor_or_dtor_p) - IDENTIFIER_CTOR_OR_DTOR_P (*pid->node) = 1; + /* Some of these identifiers already have a special kind. */ + if (pid->kind != cik_normal) + set_identifier_kind (*pid->node, pid->kind); } } @@ -8721,7 +8715,7 @@ grokfndecl (tree ctype, error_at (location, "deduction guide %qD must not have a function body", decl); } - else if (IDENTIFIER_OPNAME_P (DECL_NAME (decl)) + else if (IDENTIFIER_ANY_OP_P (DECL_NAME (decl)) && !grok_op_properties (decl, /*complain=*/true)) return NULL_TREE; else if (UDLIT_OPER_P (DECL_NAME (decl))) @@ -9773,7 +9767,7 @@ check_var_type (tree identifier, tree ty error ("unnamed variable or field declared void"); else if (identifier_p (identifier)) { - gcc_assert (!IDENTIFIER_OPNAME_P (identifier)); + gcc_assert (!IDENTIFIER_ANY_OP_P (identifier)); error ("variable or field %qE declared void", identifier); } else @@ -10114,12 +10108,7 @@ grokdeclarator (const cp_declarator *dec dname = fns; if (!identifier_p (dname)) - { - if (variable_template_p (dname)) - dname = DECL_NAME (dname); - else - dname = OVL_NAME (dname); - } + dname = OVL_NAME (dname); } /* Fall through. */ @@ -10127,13 +10116,13 @@ grokdeclarator (const cp_declarator *dec if (identifier_p (decl)) dname = decl; - if (C_IS_RESERVED_WORD (dname)) + if (IDENTIFIER_KEYWORD_P (dname)) { error ("declarator-id missing; using reserved word %qD", dname); name = identifier_to_locale (IDENTIFIER_POINTER (dname)); } - else if (!IDENTIFIER_TYPENAME_P (dname)) + else if (!IDENTIFIER_CONV_OP_P (dname)) name = identifier_to_locale (IDENTIFIER_POINTER (dname)); else { @@ -10192,26 +10181,27 @@ grokdeclarator (const cp_declarator *dec return error_mark_node; } - if (dname - && identifier_p (dname) - && UDLIT_OPER_P (dname) - && innermost_code != cdk_function) + if (dname && identifier_p (dname)) { - error ("declaration of %qD as non-function", dname); - return error_mark_node; - } - - if (dname && IDENTIFIER_OPNAME_P (dname)) - { - if (typedef_p) + if (UDLIT_OPER_P (dname) + && innermost_code != cdk_function) { - error ("declaration of %qD as %", dname); + error ("declaration of %qD as non-function", dname); return error_mark_node; } - else if (decl_context == PARM || decl_context == CATCHPARM) + + if (IDENTIFIER_ANY_OP_P (dname)) { - error ("declaration of %qD as parameter", dname); - return error_mark_node; + if (typedef_p) + { + error ("declaration of %qD as %", dname); + return error_mark_node; + } + else if (decl_context == PARM || decl_context == CATCHPARM) + { + error ("declaration of %qD as parameter", dname); + return error_mark_node; + } } } @@ -11708,22 +11698,20 @@ grokdeclarator (const cp_declarator *dec return error_mark_node; } - /* Only functions may be declared using an operator-function-id. */ - if (unqualified_id - && IDENTIFIER_OPNAME_P (unqualified_id) - && TREE_CODE (type) != FUNCTION_TYPE - && TREE_CODE (type) != METHOD_TYPE) + if (!FUNC_OR_METHOD_TYPE_P (type)) { - error ("declaration of %qD as non-function", unqualified_id); - return error_mark_node; - } + /* Only functions may be declared using an operator-function-id. */ + if (dname && IDENTIFIER_ANY_OP_P (dname)) + { + error ("declaration of %qD as non-function", dname); + return error_mark_node; + } - if (reqs - && TREE_CODE (type) != FUNCTION_TYPE - && TREE_CODE (type) != METHOD_TYPE) - error_at (location_of (reqs), - "requires-clause on declaration of non-function type %qT", - type); + if (reqs) + error_at (location_of (reqs), + "requires-clause on declaration of non-function type %qT", + type); + } /* We don't check parameter types here because we can emit a better error message later. */ @@ -11768,7 +11756,8 @@ grokdeclarator (const cp_declarator *dec } if (ctype && TREE_CODE (type) == FUNCTION_TYPE && staticp < 2 - && !NEW_DELETE_OPNAME_P (unqualified_id)) + && !(identifier_p (unqualified_id) + && IDENTIFIER_NEWDEL_OP_P (unqualified_id))) { cp_cv_quals real_quals = memfn_quals; if (cxx_dialect < cxx14 && constexpr_p @@ -11879,15 +11868,13 @@ grokdeclarator (const cp_declarator *dec return error_mark_node; } - if (NEW_DELETE_OPNAME_P (unqualified_id)) + if (virtualp + && identifier_p (unqualified_id) + && IDENTIFIER_NEWDEL_OP_P (unqualified_id)) { - if (virtualp) - { - error ("%qD cannot be declared %, since it " - "is always static", - unqualified_id); - virtualp = 0; - } + error ("%qD cannot be declared %, since it " + "is always static", unqualified_id); + virtualp = 0; } } @@ -12149,6 +12136,7 @@ grokdeclarator (const cp_declarator *dec original_name = dname; else original_name = unqualified_id; + // FIXME:gcc_assert (original_name == dname); if (storage_class == sc_auto) error ("storage class % invalid for function %qs", name); @@ -12943,27 +12931,24 @@ grok_op_properties (tree decl, bool comp if (class_type && !CLASS_TYPE_P (class_type)) class_type = NULL_TREE; - if (DECL_CONV_FN_P (decl)) + if (IDENTIFIER_CONV_OP_P (name)) operator_code = TYPE_EXPR; else - do - { -#define DEF_OPERATOR(NAME, CODE, MANGLING, ARITY, ASSN_P) \ - if (cp_operator_id (CODE) == name) \ - { \ - operator_code = (CODE); \ - break; \ - } \ - else if (cp_assignment_operator_id (CODE) == name) \ - { \ - operator_code = (CODE); \ - DECL_ASSIGNMENT_OPERATOR_P (decl) = 1; \ - break; \ - } - + { + /* It'd be nice to hang something else of the identifier to + find CODE more directly. */ + const operator_name_info_t *oni + = (IDENTIFIER_ASSIGN_OP_P (name) + ? assignment_operator_name_info : operator_name_info); + DECL_ASSIGNMENT_OPERATOR_P (decl) = IDENTIFIER_ASSIGN_OP_P (name); + if (false) + ; +#define DEF_OPERATOR(NAME, CODE, MANGLING, ARITY, KIND) \ + else if (oni[int (CODE)].identifier == name) \ + operator_code = (CODE); #include "operators.def" #undef DEF_OPERATOR - + else gcc_unreachable (); } while (0); @@ -13082,7 +13067,7 @@ grok_op_properties (tree decl, bool comp return true; /* Warn about conversion operators that will never be used. */ - if (IDENTIFIER_TYPENAME_P (name) + if (IDENTIFIER_CONV_OP_P (name) && ! DECL_TEMPLATE_INFO (decl) && warn_conversion /* Warn only declaring the function; there is no need to Index: dump.c =================================================================== --- dump.c (revision 249569) +++ dump.c (working copy) @@ -226,12 +226,12 @@ cp_dump_tree (void* dump_info, tree t) switch (code) { case IDENTIFIER_NODE: - if (IDENTIFIER_OPNAME_P (t)) + if (IDENTIFIER_ANY_OP_P (t)) { dump_string_field (di, "note", "operator"); return true; } - else if (IDENTIFIER_TYPENAME_P (t)) + else if (IDENTIFIER_CONV_OP_P (t)) { dump_child ("tynm", TREE_TYPE (t)); return true; Index: error.c =================================================================== --- error.c (revision 249569) +++ error.c (working copy) @@ -1051,7 +1051,7 @@ dump_decl_name (cxx_pretty_printer *pp, { /* These special cases are duplicated here so that other functions can feed identifiers to error and get them demangled properly. */ - if (IDENTIFIER_TYPENAME_P (t)) + if (IDENTIFIER_CONV_OP_P (t)) { pp_cxx_ws_string (pp, "operator"); /* Not exactly IDENTIFIER_TYPE_VALUE. */ Index: lex.c =================================================================== --- lex.c (revision 249569) +++ lex.c (working copy) @@ -89,6 +89,37 @@ operator_name_info_t assignment_operator #include "operators.def" #undef DEF_OPERATOR +/* Get the name of the kind of identifier T. */ + +const char * +get_identifier_kind_name (tree id) +{ + /* Keep in sync with cp_id_kind enumeration. */ + static const char *const names[cik_max] = { + "normal", "keyword", "constructor", "destructor", + "assign-op", "op-assign-op", "simple-op", "conv-op", }; + + unsigned kind = 0; + kind |= IDENTIFIER_KIND_BIT_2 (id) << 2; + kind |= IDENTIFIER_KIND_BIT_1 (id) << 1; + kind |= IDENTIFIER_KIND_BIT_0 (id) << 0; + + return names[kind]; +} + +/* Set the identifier kind, which we expect to currently be zero. */ + +void +set_identifier_kind (tree id, cp_identifier_kind kind) +{ + gcc_checking_assert (!IDENTIFIER_KIND_BIT_2 (id) + & !IDENTIFIER_KIND_BIT_1 (id) + & !IDENTIFIER_KIND_BIT_0 (id)); + IDENTIFIER_KIND_BIT_2 (id) |= (kind >> 2) & 1; + IDENTIFIER_KIND_BIT_1 (id) |= (kind >> 1) & 1; + IDENTIFIER_KIND_BIT_0 (id) |= (kind >> 0) & 1; +} + static void init_operators (void) { @@ -96,22 +127,26 @@ init_operators (void) char buffer[256]; struct operator_name_info_t *oni; -#define DEF_OPERATOR(NAME, CODE, MANGLING, ARITY, ASSN_P) \ - sprintf (buffer, ISALPHA (NAME[0]) ? "operator %s" : "operator%s", NAME); \ - identifier = get_identifier (buffer); \ - IDENTIFIER_OPNAME_P (identifier) = 1; \ - \ - oni = (ASSN_P \ - ? &assignment_operator_name_info[(int) CODE] \ - : &operator_name_info[(int) CODE]); \ - oni->identifier = identifier; \ - oni->name = NAME; \ - oni->mangled_name = MANGLING; \ +#define DEF_OPERATOR(NAME, CODE, MANGLING, ARITY, KIND) \ + sprintf (buffer, "operator%s%s", !NAME[0] \ + || NAME[0] == '_' || ISALPHA (NAME[0]) ? " " : "", NAME); \ + identifier = get_identifier (buffer); \ + \ + if (KIND != cik_simple_op || !IDENTIFIER_ANY_OP_P (identifier)) \ + set_identifier_kind (identifier, KIND); \ + \ + oni = (KIND == cik_assign_op \ + ? &assignment_operator_name_info[(int) CODE] \ + : &operator_name_info[(int) CODE]); \ + oni->identifier = identifier; \ + oni->name = NAME; \ + oni->mangled_name = MANGLING; \ oni->arity = ARITY; #include "operators.def" #undef DEF_OPERATOR + operator_name_info[(int) TYPE_EXPR] = operator_name_info[(int) CAST_EXPR]; operator_name_info[(int) ERROR_MARK].identifier = get_identifier (""); @@ -123,6 +158,7 @@ init_operators (void) operator_name_info [(int) INIT_EXPR].name = operator_name_info [(int) MODIFY_EXPR].name; + operator_name_info [(int) EXACT_DIV_EXPR].name = "(ceiling /)"; operator_name_info [(int) CEIL_DIV_EXPR].name = "(ceiling /)"; operator_name_info [(int) FLOOR_DIV_EXPR].name = "(floor /)"; @@ -130,26 +166,20 @@ init_operators (void) operator_name_info [(int) CEIL_MOD_EXPR].name = "(ceiling %)"; operator_name_info [(int) FLOOR_MOD_EXPR].name = "(floor %)"; operator_name_info [(int) ROUND_MOD_EXPR].name = "(round %)"; + operator_name_info [(int) ABS_EXPR].name = "abs"; operator_name_info [(int) TRUTH_AND_EXPR].name = "strict &&"; operator_name_info [(int) TRUTH_OR_EXPR].name = "strict ||"; operator_name_info [(int) RANGE_EXPR].name = "..."; operator_name_info [(int) UNARY_PLUS_EXPR].name = "+"; - assignment_operator_name_info [(int) EXACT_DIV_EXPR].name - = "(exact /=)"; - assignment_operator_name_info [(int) CEIL_DIV_EXPR].name - = "(ceiling /=)"; - assignment_operator_name_info [(int) FLOOR_DIV_EXPR].name - = "(floor /=)"; - assignment_operator_name_info [(int) ROUND_DIV_EXPR].name - = "(round /=)"; - assignment_operator_name_info [(int) CEIL_MOD_EXPR].name - = "(ceiling %=)"; - assignment_operator_name_info [(int) FLOOR_MOD_EXPR].name - = "(floor %=)"; - assignment_operator_name_info [(int) ROUND_MOD_EXPR].name - = "(round %=)"; + assignment_operator_name_info [(int) EXACT_DIV_EXPR].name = "(exact /=)"; + assignment_operator_name_info [(int) CEIL_DIV_EXPR].name = "(ceiling /=)"; + assignment_operator_name_info [(int) FLOOR_DIV_EXPR].name = "(floor /=)"; + assignment_operator_name_info [(int) ROUND_DIV_EXPR].name = "(round /=)"; + assignment_operator_name_info [(int) CEIL_MOD_EXPR].name = "(ceiling %=)"; + assignment_operator_name_info [(int) FLOOR_MOD_EXPR].name = "(floor %=)"; + assignment_operator_name_info [(int) ROUND_MOD_EXPR].name = "(round %=)"; } /* Initialize the reserved words. */ @@ -184,7 +214,7 @@ init_reswords (void) C_SET_RID_CODE (id, c_common_reswords[i].rid); ridpointers [(int) c_common_reswords[i].rid] = id; if (! (c_common_reswords[i].disable & mask)) - C_IS_RESERVED_WORD (id) = 1; + set_identifier_kind (id, cik_keyword); } for (i = 0; i < NUM_INT_N_ENTS; i++) @@ -193,7 +223,7 @@ init_reswords (void) sprintf (name, "__int%d", int_n_data[i].bitsize); id = get_identifier (name); C_SET_RID_CODE (id, RID_FIRST_INT_N + i); - C_IS_RESERVED_WORD (id) = 1; + set_identifier_kind (id, cik_keyword); } } @@ -431,7 +461,7 @@ unqualified_name_lookup_error (tree name if (loc == UNKNOWN_LOCATION) loc = EXPR_LOC_OR_LOC (name, input_location); - if (IDENTIFIER_OPNAME_P (name)) + if (IDENTIFIER_ANY_OP_P (name)) { if (name != cp_operator_id (ERROR_MARK)) error_at (loc, "%qD not defined", name); Index: mangle.c =================================================================== --- mangle.c (revision 249569) +++ mangle.c (working copy) @@ -1261,9 +1261,9 @@ write_template_prefix (const tree node) static void write_unqualified_id (tree identifier) { - if (IDENTIFIER_TYPENAME_P (identifier)) + if (IDENTIFIER_CONV_OP_P (identifier)) write_conversion_operator_name (TREE_TYPE (identifier)); - else if (IDENTIFIER_OPNAME_P (identifier)) + else if (IDENTIFIER_ANY_OP_P (identifier)) { int i; const char *mangled_name = NULL; @@ -2825,14 +2825,16 @@ write_template_args (tree args) static void write_member_name (tree member) { - if (abi_version_at_least (11) && IDENTIFIER_OPNAME_P (member)) + if (identifier_p (member)) { - write_string ("on"); - if (abi_warn_or_compat_version_crosses (11)) - G.need_abi_warning = 1; + if (abi_version_at_least (11) && IDENTIFIER_ANY_OP_P (member)) + { + write_string ("on"); + if (abi_warn_or_compat_version_crosses (11)) + G.need_abi_warning = 1; + } + write_unqualified_id (member); } - if (identifier_p (member)) - write_unqualified_id (member); else if (DECL_P (member)) write_unqualified_name (member); else if (TREE_CODE (member) == TEMPLATE_ID_EXPR) @@ -3050,7 +3052,7 @@ write_expression (tree expr) /* An operator name appearing as a dependent name needs to be specially marked to disambiguate between a use of the operator name and a use of the operator in an expression. */ - if (IDENTIFIER_OPNAME_P (expr)) + if (IDENTIFIER_ANY_OP_P (expr)) write_string ("on"); write_unqualified_id (expr); } @@ -3058,7 +3060,7 @@ write_expression (tree expr) { tree fn = TREE_OPERAND (expr, 0); fn = OVL_NAME (fn); - if (IDENTIFIER_OPNAME_P (fn)) + if (IDENTIFIER_ANY_OP_P (fn)) write_string ("on"); write_unqualified_id (fn); write_template_args (TREE_OPERAND (expr, 1)); @@ -4241,9 +4243,8 @@ mangle_conv_op_name_for_type (const tree when performing conversions. */ TREE_TYPE (identifier) = type; - /* Set bits on the identifier so we know later it's a conversion. */ - IDENTIFIER_OPNAME_P (identifier) = 1; - IDENTIFIER_TYPENAME_P (identifier) = 1; + /* Set the identifier kind so we know later it's a conversion. */ + set_identifier_kind (identifier, cik_conv_op); } return identifier; Index: name-lookup.c =================================================================== --- name-lookup.c (revision 249569) +++ name-lookup.c (working copy) @@ -4161,7 +4161,7 @@ do_class_using_decl (tree scope, tree na scope_dependent_p = dependent_scope_p (scope); name_dependent_p = (scope_dependent_p - || (IDENTIFIER_TYPENAME_P (name) + || (IDENTIFIER_CONV_OP_P (name) && dependent_type_p (TREE_TYPE (name)))); bases_dependent_p = any_dependent_bases_p (); @@ -5066,7 +5066,7 @@ lookup_name_fuzzy (tree name, enum looku /* Only consider reserved words that survived the filtering in init_reswords (e.g. for -std). */ - if (!C_IS_RESERVED_WORD (resword_identifier)) + if (!IDENTIFIER_KEYWORD_P (resword_identifier)) continue; bm.consider (IDENTIFIER_POINTER (resword_identifier)); @@ -5228,7 +5228,7 @@ lookup_name_real_1 (tree name, int prefe /* Conversion operators are handled specially because ordinary unqualified name lookup will not find template conversion operators. */ - if (IDENTIFIER_TYPENAME_P (name)) + if (IDENTIFIER_CONV_OP_P (name)) { cp_binding_level *level; Index: operators.def =================================================================== --- operators.def (revision 249569) +++ operators.def (working copy) @@ -67,20 +67,20 @@ along with GCC; see the file COPYING3. an ASSIGNMENT_P argument; it is always zero. */ #define DEF_SIMPLE_OPERATOR(NAME, CODE, MANGLING, ARITY) \ - DEF_OPERATOR(NAME, CODE, MANGLING, ARITY, 0) + DEF_OPERATOR(NAME, CODE, MANGLING, ARITY, cik_simple_op) /* Use DEF_ASSN_OPERATOR to define an assignment operator. Its arguments are as for DEF_OPERATOR, but there is no need to provide an ASSIGNMENT_P argument; it is always one. */ #define DEF_ASSN_OPERATOR(NAME, CODE, MANGLING, ARITY) \ - DEF_OPERATOR(NAME, CODE, MANGLING, ARITY, 1) + DEF_OPERATOR(NAME, CODE, MANGLING, ARITY, cik_assign_op) /* Memory allocation operators. */ -DEF_SIMPLE_OPERATOR ("new", NEW_EXPR, "nw", -1) -DEF_SIMPLE_OPERATOR ("new []", VEC_NEW_EXPR, "na", -1) -DEF_SIMPLE_OPERATOR ("delete", DELETE_EXPR, "dl", -1) -DEF_SIMPLE_OPERATOR ("delete []", VEC_DELETE_EXPR, "da", -1) +DEF_OPERATOR ("new", NEW_EXPR, "nw", -1, cik_newdel_op) +DEF_OPERATOR ("new []", VEC_NEW_EXPR, "na", -1, cik_newdel_op) +DEF_OPERATOR ("delete", DELETE_EXPR, "dl", -1, cik_newdel_op) +DEF_OPERATOR ("delete []", VEC_DELETE_EXPR, "da", -1, cik_newdel_op) /* Unary operators. */ DEF_SIMPLE_OPERATOR ("+", UNARY_PLUS_EXPR, "ps", 1) @@ -97,8 +97,7 @@ DEF_SIMPLE_OPERATOR ("alignof", ALIGNOF_ DEF_SIMPLE_OPERATOR ("__imag__", IMAGPART_EXPR, "v18__imag__", 1) DEF_SIMPLE_OPERATOR ("__real__", REALPART_EXPR, "v18__real__", 1) -/* The cast operator. */ -DEF_SIMPLE_OPERATOR ("", TYPE_EXPR, "cv", 1) +/* The cast operators. */ DEF_SIMPLE_OPERATOR ("", CAST_EXPR, "cv", 1) DEF_SIMPLE_OPERATOR ("dynamic_cast", DYNAMIC_CAST_EXPR, "dc", 1) DEF_SIMPLE_OPERATOR ("reinterpret_cast", REINTERPRET_CAST_EXPR, "rc", 1) Index: parser.c =================================================================== --- parser.c (revision 249569) +++ parser.c (working copy) @@ -806,7 +806,7 @@ cp_lexer_get_preprocessor_token (cp_lexe /* Check to see if this token is a keyword. */ if (token->type == CPP_NAME) { - if (C_IS_RESERVED_WORD (token->u.value)) + if (IDENTIFIER_KEYWORD_P (token->u.value)) { /* Mark this token as a keyword. */ token->type = CPP_KEYWORD; @@ -20089,7 +20089,8 @@ cp_parser_direct_declarator (cp_parser* { if (TREE_CODE (unqualified_name) == BIT_NOT_EXPR) sfk = sfk_destructor; - else if (IDENTIFIER_TYPENAME_P (unqualified_name)) + else if (identifier_p (unqualified_name) + && IDENTIFIER_CONV_OP_P (unqualified_name)) sfk = sfk_conversion; else if (/* There's no way to declare a constructor for an unnamed type, even if the type Index: pt.c =================================================================== --- pt.c (revision 249569) +++ pt.c (working copy) @@ -5333,11 +5333,11 @@ push_template_decl_real (tree decl, bool error ("destructor %qD declared as member template", decl); return error_mark_node; } - if (NEW_DELETE_OPNAME_P (DECL_NAME (decl)) + if (IDENTIFIER_NEWDEL_OP_P (DECL_NAME (decl)) && (!prototype_p (TREE_TYPE (decl)) || TYPE_ARG_TYPES (TREE_TYPE (decl)) == void_list_node || !TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (decl))) - || (TREE_CHAIN (TYPE_ARG_TYPES ((TREE_TYPE (decl)))) + || (TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (decl))) == void_list_node))) { /* [basic.stc.dynamic.allocation] @@ -12416,7 +12416,7 @@ tsubst_decl (tree t, tree args, tsubst_f /* If we aren't complaining now, return on error before we register the specialization so that we'll complain eventually. */ if ((complain & tf_error) == 0 - && IDENTIFIER_OPNAME_P (DECL_NAME (r)) + && IDENTIFIER_ANY_OP_P (DECL_NAME (r)) && !grok_op_properties (r, /*complain=*/false)) RETURN (error_mark_node); @@ -12487,7 +12487,7 @@ tsubst_decl (tree t, tree args, tsubst_f clone_function_decl (r, /*update_methods=*/false); } else if ((complain & tf_error) != 0 - && IDENTIFIER_OPNAME_P (DECL_NAME (r)) + && IDENTIFIER_ANY_OP_P (DECL_NAME (r)) && !grok_op_properties (r, /*complain=*/true)) RETURN (error_mark_node); @@ -14247,7 +14247,7 @@ tsubst_baselink (tree baselink, tree obj } tree name = OVL_NAME (fns); - if (IDENTIFIER_TYPENAME_P (name)) + if (IDENTIFIER_CONV_OP_P (name)) name = mangle_conv_op_name_for_type (optype); baselink = lookup_fnfields (qualifying_scope, name, /*protect=*/1); @@ -15035,7 +15035,7 @@ tsubst_copy (tree t, tree args, tsubst_f t = DECL_NAME (t); /* Fall through. */ case IDENTIFIER_NODE: - if (IDENTIFIER_TYPENAME_P (t)) + if (IDENTIFIER_CONV_OP_P (t)) { tree new_type = tsubst (TREE_TYPE (t), args, complain, in_decl); return mangle_conv_op_name_for_type (new_type); @@ -16668,7 +16668,7 @@ tsubst_copy_and_build (tree t, bool non_integral_constant_expression_p; const char *error_msg; - if (IDENTIFIER_TYPENAME_P (t)) + if (IDENTIFIER_CONV_OP_P (t)) { tree new_type = tsubst (TREE_TYPE (t), args, complain, in_decl); t = mangle_conv_op_name_for_type (new_type); Index: ptree.c =================================================================== --- ptree.c (revision 249569) +++ ptree.c (working copy) @@ -178,7 +178,8 @@ cxx_print_identifier (FILE *file, tree n fprintf (file, " "); else indent_to (file, indent + 4); - fprintf (file, "local bindings <%p>", (void *) IDENTIFIER_BINDING (node)); + fprintf (file, "%s local bindings <%p>", get_identifier_kind_name (node), + (void *) IDENTIFIER_BINDING (node)); print_node (file, "label", IDENTIFIER_LABEL_VALUE (node), indent + 4); print_node (file, "template", IDENTIFIER_TEMPLATE (node), indent + 4); } Index: search.c =================================================================== --- search.c (revision 249569) +++ search.c (working copy) @@ -1187,7 +1187,7 @@ lookup_field_r (tree binfo, void *data) done: /* Don't look for constructors or destructors in base classes. */ - if (IDENTIFIER_CTOR_OR_DTOR_P (lfi->name)) + if (IDENTIFIER_CDTOR_P (lfi->name)) return dfs_skip_bases; return NULL_TREE; } @@ -1352,7 +1352,7 @@ lookup_member (tree xbasetype, tree name if (rval && is_overloaded_fn (rval)) rval = build_baselink (rval_binfo, basetype_path, rval, - (IDENTIFIER_TYPENAME_P (name) + (IDENTIFIER_CONV_OP_P (name) ? TREE_TYPE (name): NULL_TREE)); return rval; } @@ -1595,7 +1595,7 @@ lookup_fnfields_idx_nolazy (tree type, t fn = CLASSTYPE_DESTRUCTORS (type); return fn ? CLASSTYPE_DESTRUCTOR_SLOT : -1; } - if (IDENTIFIER_TYPENAME_P (name)) + if (IDENTIFIER_CONV_OP_P (name)) return lookup_conversion_operator (type, TREE_TYPE (name)); /* Skip the conversion operators. */ Index: semantics.c =================================================================== --- semantics.c (revision 249569) +++ semantics.c (working copy) @@ -3496,7 +3496,7 @@ finish_id_expression (tree id_expression && (!TYPE_P (scope) || (!dependent_type_p (scope) && !(identifier_p (id_expression) - && IDENTIFIER_TYPENAME_P (id_expression) + && IDENTIFIER_CONV_OP_P (id_expression) && dependent_type_p (TREE_TYPE (id_expression)))))) { /* If the qualifying type is non-dependent (and the name Index: typeck.c =================================================================== --- typeck.c (revision 249569) +++ typeck.c (working copy) @@ -5652,7 +5652,7 @@ cp_build_addr_expr_1 (tree arg, bool str arg = mark_lvalue_use (arg); argtype = lvalue_type (arg); - gcc_assert (!identifier_p (arg) || !IDENTIFIER_OPNAME_P (arg)); + gcc_assert (!(identifier_p (arg) && IDENTIFIER_ANY_OP_P (arg))); if (TREE_CODE (arg) == COMPONENT_REF && type_unknown_p (arg) && !really_overloaded_fn (arg))