public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [C++ PATCH] Special identifier marking
@ 2017-06-22 18:49 Nathan Sidwell
  0 siblings, 0 replies; only message in thread
From: Nathan Sidwell @ 2017-06-22 18:49 UTC (permalink / raw)
  To: GCC Patches

[-- Attachment #1: Type: text/plain, Size: 1371 bytes --]

This patch starts cleaning up how we mark special identifiers.  We 
currently use some of the TREE_LANG_FLAGS on IDENTIFIER_NODEs for 
various things, but most of those things are mutually exclusive, so an 
enumeration is better -- it allows us to distinguish more things with 
fewer bits.  This patch shrinks us from using 4 bits to using 3 bits.

We were using TREE_LANG_FLAG directly, rather than checking we were 
looking at an identifier node.  It turned out that in a few places 
(mainly grokdecl and friends), we'd treat TEMPLATE_ID_EXPRs and 
BITNOT_EXPRs as-if they were identifiers.  I guess we lucked out. 
Anyway, this patch adds the checking we now expect.

Finally, the names were somewhat random, now the accessor macros are all 
IDENTIFIER_something_P.

Specifically:
   C_RESERVED_WORD_P --> IDENTIFIER_KEYWORD_P
   IDENTIFIER_CTOR_OR_DTOR_P --> IDENTIFIER_CDTOR_P
   IDENTIFIER_OPNAME_P --> IDENTIFIER_ANY_OP_P
   IDENTIFIER_TYPENAME_P --> IDENTIFIER_CONV_OP_P
(TYPENAME means something else, so it's confusing the name conversion 
operators that way).
New accessors are:
   IDENTIFIER_CTOR_P  a constructor name
   IDENTIFIER_DTOR_P  a destructor name
   IDENTIFIER_ASSIGN_OP_P any of the assignment operators
   IDENTIFIER_NEWDEL_OP_P a new or delete operator

Followup patches will take more advantage of the new features.

nathan
-- 
Nathan Sidwell

[-- Attachment #2: ident-flags.diff --]
[-- Type: text/x-patch, Size: 43494 bytes --]

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.

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 <lang_identif
   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))
 
@@ -987,29 +981,89 @@ enum GTY(()) abstract_class_use {
 #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
+};
+
+/* 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 prefix for a mangled C++ operator
-   name.  */
-#define IDENTIFIER_OPNAME_P(NODE) TREE_LANG_FLAG_2 (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) \
@@ -1718,14 +1772,6 @@ struct GTY(()) language_function {
 #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) \
@@ -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)
 \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
@@ -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 ("<unnamed>");
-      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 %<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;
+	    }
 	}
     }
 
@@ -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 %<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;
 		  }
 	      }
 
@@ -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 %<auto%> 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 ("<invalid operator>");
 
@@ -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))

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2017-06-22 18:49 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-06-22 18:49 [C++ PATCH] Special identifier marking Nathan Sidwell

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).