diff mbox series

[pushed] c++: Add make_temp_override generator functions

Message ID 20201210203717.596516-1-jason@redhat.com
State New
Headers show
Series [pushed] c++: Add make_temp_override generator functions | expand

Commit Message

Jason Merrill Dec. 10, 2020, 8:37 p.m. UTC
A common pattern before C++17 is the generator function, used to avoid
having to specify the type of a container element by using a function call
to get type deduction; for example, std::make_pair.  C++17 added class type
argument deduction, making generator functions unnecessary for many uses,
but GCC won't be written in C++17 for years yet.

Tested x86_64-pc-linux-gnu, applying to trunk.

gcc/cp/ChangeLog:

	* cp-tree.h (struct type_identity): New.
	(make_temp_override): New.
	* decl.c (grokdeclarator): Use it.
	* except.c (maybe_noexcept_warning): Use it.
	* parser.c (cp_parser_enum_specifier): Use it.
	(cp_parser_parameter_declaration_clause): Use it.
	(cp_parser_gnu_attributes_opt): Use it.
	(cp_parser_std_attribute): Use it.
---
 gcc/cp/cp-tree.h | 32 ++++++++++++++++++++++++++++++++
 gcc/cp/decl.c    |  2 +-
 gcc/cp/except.c  |  2 +-
 gcc/cp/parser.c  |  8 ++++----
 4 files changed, 38 insertions(+), 6 deletions(-)


base-commit: 445430e16bd08ade34637d2346ded40dd49de508
diff mbox series

Patch

diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 5304f6b86a2..5cd2999ca85 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -1932,6 +1932,38 @@  public:
   ~temp_override() { overridden_variable = saved_value; }
 };
 
+/* Wrapping a template parameter in type_identity_t hides it from template
+   argument deduction.  */
+#if __cpp_lib_type_identity
+using std::type_identity_t;
+#else
+template <typename T>
+struct type_identity { typedef T type; };
+template <typename T>
+using type_identity_t = typename type_identity<T>::type;
+#endif
+
+/* Object generator function for temp_override, so you don't need to write the
+   type of the object as a template argument.
+
+   Use as auto x = make_temp_override (flag); */
+
+template <typename T>
+inline temp_override<T>
+make_temp_override (T& var)
+{
+  return { var };
+}
+
+/* Likewise, but use as auto x = make_temp_override (flag, value); */
+
+template <typename T>
+inline temp_override<T>
+make_temp_override (T& var, type_identity_t<T> overrider)
+{
+  return { var, overrider };
+}
+
 /* The cached class binding level, from the most recently exited
    class, or NULL if none.  */
 
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index ae93fe1d7f0..b56eb113fd6 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -11513,7 +11513,7 @@  grokdeclarator (const cp_declarator *declarator,
 
   /* An object declared as __attribute__((deprecated)) suppresses
      warnings of uses of other deprecated items.  */
-  temp_override<deprecated_states> ds (deprecated_state);
+  auto ds = make_temp_override (deprecated_state);
   if (attrlist && lookup_attribute ("deprecated", *attrlist))
     deprecated_state = DEPRECATED_SUPPRESS;
 
diff --git a/gcc/cp/except.c b/gcc/cp/except.c
index 0f6c76b9892..e76ade2f925 100644
--- a/gcc/cp/except.c
+++ b/gcc/cp/except.c
@@ -1101,7 +1101,7 @@  maybe_noexcept_warning (tree fn)
       && (!DECL_IN_SYSTEM_HEADER (fn)
 	  || global_dc->dc_warn_system_headers))
     {
-      temp_override<bool> s (global_dc->dc_warn_system_headers, true);
+      auto s = make_temp_override (global_dc->dc_warn_system_headers, true);
       auto_diagnostic_group d;
       if (warning (OPT_Wnoexcept, "noexcept-expression evaluates to %<false%> "
 		   "because of a call to %qD", fn))
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 39957d4b6a9..7ea8c28830e 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -19732,7 +19732,7 @@  cp_parser_enum_specifier (cp_parser* parser)
   bool is_unnamed = false;
   tree underlying_type = NULL_TREE;
   cp_token *type_start_token = NULL;
-  temp_override<bool> cleanup (parser->colon_corrects_to_scope_p, false);
+  auto cleanup = make_temp_override (parser->colon_corrects_to_scope_p, false);
 
   /* Parse tentatively so that we can back up if we don't find a
      enum-specifier.  */
@@ -23381,7 +23381,7 @@  cp_parser_parameter_declaration_clause (cp_parser* parser,
   cp_token *token;
   bool ellipsis_p;
 
-  temp_override<bool> cleanup
+  auto cleanup = make_temp_override
     (parser->auto_is_implicit_function_template_parm_p);
 
   if (!processing_specialization
@@ -27488,7 +27488,7 @@  cp_parser_gnu_attributes_opt (cp_parser* parser)
 {
   tree attributes = NULL_TREE;
 
-  temp_override<bool> cleanup
+  auto cleanup = make_temp_override
     (parser->auto_is_implicit_function_template_parm_p, false);
 
   while (true)
@@ -27688,7 +27688,7 @@  cp_parser_std_attribute (cp_parser *parser, tree attr_ns)
   tree attribute, attr_id = NULL_TREE, arguments;
   cp_token *token;
 
-  temp_override<bool> cleanup
+  auto cleanup = make_temp_override
     (parser->auto_is_implicit_function_template_parm_p, false);
 
   /* First, parse name of the attribute, a.k.a attribute-token.  */