+2017-06-22 Nathan Sidwell <nathan@acm.org>
+
+ 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.
+
2017-06-21 Jakub Jelinek <jakub@redhat.com>
PR c++/81154
/* 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),
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. */
{
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);
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.
#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).
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).
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)
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)
static void remove (value_type) { gcc_unreachable (); }
};
-/* In an IDENTIFIER_NODE, nonzero if this identifier is actually a
- keyword. C_RID_CODE (node) is then the RID_* value of the keyword. */
-
-#define C_IS_RESERVED_WORD(ID) TREE_LANG_FLAG_5 (ID)
-
#define LANG_IDENTIFIER_CAST(NODE) \
((struct lang_identifier*)IDENTIFIER_NODE_CHECK (NODE))
#define SET_IDENTIFIER_LABEL_VALUE(NODE, VALUE) \
IDENTIFIER_LABEL_VALUE (NODE) = (VALUE)
-/* Nonzero if this identifier is used as a virtual function name somewhere
- (optimizes searches). */
-#define IDENTIFIER_VIRTUAL_P(NODE) TREE_LANG_FLAG_1 (NODE)
+/* Kinds of identifiers. Values are carefully chosen. */
+enum cp_identifier_kind {
+ cik_normal = 0, /* Not a special identifier. */
+ cik_keyword = 1, /* A keyword. */
+ cik_ctor = 2, /* Constructor (in-chg, complete or base). */
+ cik_dtor = 3, /* Destructor (in-chg, deleting, complete or
+ base). */
+ cik_simple_op = 4, /* Non-assignment operator name. */
+ cik_newdel_op = 5, /* New or delete operator name. */
+ cik_assign_op = 6, /* An assignment operator name. */
+ cik_conv_op = 7, /* Conversion operator name. */
+ cik_max
+};
-/* Nonzero if this identifier is the prefix for a mangled C++ operator
- name. */
-#define IDENTIFIER_OPNAME_P(NODE) TREE_LANG_FLAG_2 (NODE)
+/* Kind bits. */
+#define IDENTIFIER_KIND_BIT_0(NODE) \
+ TREE_LANG_FLAG_0 (IDENTIFIER_NODE_CHECK (NODE))
+#define IDENTIFIER_KIND_BIT_1(NODE) \
+ TREE_LANG_FLAG_1 (IDENTIFIER_NODE_CHECK (NODE))
+#define IDENTIFIER_KIND_BIT_2(NODE) \
+ TREE_LANG_FLAG_2 (IDENTIFIER_NODE_CHECK (NODE))
-/* Nonzero if this identifier is the name of a type-conversion
- operator. */
-#define IDENTIFIER_TYPENAME_P(NODE) \
- TREE_LANG_FLAG_4 (NODE)
+/* Used by various search routines. */
+#define IDENTIFIER_MARKED(NODE) \
+ TREE_LANG_FLAG_4 (IDENTIFIER_NODE_CHECK (NODE))
-/* Nonzero if this identifier is the name of a constructor or
- destructor. */
-#define IDENTIFIER_CTOR_OR_DTOR_P(NODE) \
- TREE_LANG_FLAG_3 (NODE)
+/* Nonzero if this identifier is used as a virtual function name somewhere
+ (optimizes searches). */
+#define IDENTIFIER_VIRTUAL_P(NODE) \
+ TREE_LANG_FLAG_5 (IDENTIFIER_NODE_CHECK (NODE))
/* True iff NAME is the DECL_ASSEMBLER_NAME for an entity with vague
linkage which the prelinker has assigned to this translation
unit. */
#define IDENTIFIER_REPO_CHOSEN(NAME) \
- (TREE_LANG_FLAG_6 (NAME))
+ (TREE_LANG_FLAG_6 (IDENTIFIER_NODE_CHECK (NAME)))
+
+/* True if this identifier is a reserved word. C_RID_CODE (node) is
+ then the RID_* value of the keyword. Value 1. */
+#define IDENTIFIER_KEYWORD_P(NODE) \
+ ((!IDENTIFIER_KIND_BIT_2 (NODE)) \
+ & (!IDENTIFIER_KIND_BIT_1 (NODE)) \
+ & IDENTIFIER_KIND_BIT_0 (NODE))
+
+/* True if this identifier is the name of a constructor or
+ destructor. Value 2 or 3. */
+#define IDENTIFIER_CDTOR_P(NODE) \
+ ((!IDENTIFIER_KIND_BIT_2 (NODE)) \
+ & IDENTIFIER_KIND_BIT_1 (NODE))
+
+/* True if this identifier is the name of a constructor. Value 2. */
+#define IDENTIFIER_CTOR_P(NODE) \
+ (IDENTIFIER_CDTOR_P(NODE) \
+ & (!IDENTIFIER_KIND_BIT_0 (NODE)))
+
+/* True if this identifier is the name of a destructor. Value 3. */
+#define IDENTIFIER_DTOR_P(NODE) \
+ (IDENTIFIER_CDTOR_P(NODE) \
+ & IDENTIFIER_KIND_BIT_0 (NODE))
+
+/* True if this identifier is for any operator name (including
+ conversions). Value 4, 5, 6 or 7. */
+#define IDENTIFIER_ANY_OP_P(NODE) \
+ (IDENTIFIER_KIND_BIT_2 (NODE))
+
+/* True if this identifier is for new or delete operator. Value 5. */
+#define IDENTIFIER_NEWDEL_OP_P(NODE) \
+ (IDENTIFIER_KIND_BIT_2 (NODE) \
+ & (!IDENTIFIER_KIND_BIT_1 (NODE)) \
+ & IDENTIFIER_KIND_BIT_0 (NODE))
+
+/* True if this identifier is for any assignment. Values 6. */
+#define IDENTIFIER_ASSIGN_OP_P(NODE) \
+ (IDENTIFIER_KIND_BIT_2 (NODE) \
+ & IDENTIFIER_KIND_BIT_1 (NODE) \
+ & (!IDENTIFIER_KIND_BIT_0 (NODE)))
+
+/* True if this identifier is the name of a type-conversion
+ operator. Value 7. */
+#define IDENTIFIER_CONV_OP_P(NODE) \
+ (IDENTIFIER_KIND_BIT_2 (NODE) \
+ & IDENTIFIER_KIND_BIT_1 (NODE) \
+ & IDENTIFIER_KIND_BIT_0 (NODE))
/* In a RECORD_TYPE or UNION_TYPE, nonzero if any component is read-only. */
#define C_TYPE_FIELDS_READONLY(TYPE) \
#define current_function_auto_return_pattern \
(cp_function_chain->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) \
/* 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)
\f
/* A vec<tree_pair_s> of the vcall indices associated with the class
NODE. The PURPOSE of each element is a FUNCTION_DECL for a virtual
/* 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. */
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). */
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);
case IDENTIFIER_NODE:
if (t == NULL)
pp->translate_string ("<unnamed>");
- else if (IDENTIFIER_TYPENAME_P (t))
+ else if (IDENTIFIER_CONV_OP_P (t))
pp_cxx_conversion_function_id (pp, t);
else
{
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);
}
}
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)))
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
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. */
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
{
return error_mark_node;
}
- if (dname
- && identifier_p (dname)
- && UDLIT_OPER_P (dname)
- && innermost_code != cdk_function)
- {
- error ("declaration of %qD as non-function", dname);
- return error_mark_node;
- }
-
- if (dname && IDENTIFIER_OPNAME_P (dname))
+ if (dname && identifier_p (dname))
{
- if (typedef_p)
+ if (UDLIT_OPER_P (dname)
+ && innermost_code != cdk_function)
{
- error ("declaration of %qD as %<typedef%>", 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 %<typedef%>", dname);
+ return error_mark_node;
+ }
+ else if (decl_context == PARM || decl_context == CATCHPARM)
+ {
+ error ("declaration of %qD as parameter", dname);
+ return error_mark_node;
+ }
}
}
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. */
}
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
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 %<virtual%>, since it "
- "is always static",
- unqualified_id);
- virtualp = 0;
- }
+ error ("%qD cannot be declared %<virtual%>, since it "
+ "is always static", unqualified_id);
+ virtualp = 0;
}
}
original_name = dname;
else
original_name = unqualified_id;
+ // FIXME:gcc_assert (original_name == dname);
if (storage_class == sc_auto)
error ("storage class %<auto%> invalid for function %qs", name);
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);
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
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;
{
/* 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. */
#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)
{
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 ("<invalid operator>");
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 /)";
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. */
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++)
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);
}
}
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);
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;
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)
/* 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);
}
{
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));
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;
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 ();
/* 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));
/* 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;
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)
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)
/* 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;
{
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
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]
/* 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);
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);
}
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);
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);
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);
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);
}
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;
}
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;
}
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. */
&& (!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
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))