Change C++ to C comments.
[gcc.git] / gcc / cp / parser.c
index e5381b45d033b2843a8d60e26adeaf46d7c19795..165039ef07c00768a2fc4ac3f05b1ea42ceaaa0c 100644 (file)
@@ -1,5 +1,5 @@
 /* -*- C++ -*- Parser.
-   Copyright (C) 2000-2018 Free Software Foundation, Inc.
+   Copyright (C) 2000-2019 Free Software Foundation, Inc.
    Written by Mark Mitchell <mark@codesourcery.com>.
 
    This file is part of GCC.
@@ -247,6 +247,10 @@ static void cp_lexer_stop_debugging
 
 static cp_token_cache *cp_token_cache_new
   (cp_token *, cp_token *);
+static tree cp_parser_late_noexcept_specifier
+  (cp_parser *, tree);
+static void noexcept_override_late_checks
+  (tree, tree);
 
 static void cp_parser_initial_pragma
   (cp_token *);
@@ -536,9 +540,12 @@ cp_debug_parser (FILE *file, cp_parser *parser)
                              parser->allow_non_integral_constant_expression_p);
   cp_debug_print_flag (file, "Seen non-constant expression",
                              parser->non_integral_constant_expression_p);
-  cp_debug_print_flag (file, "Local names and 'this' forbidden in "
-                             "current context",
-                             parser->local_variables_forbidden_p);
+  cp_debug_print_flag (file, "Local names forbidden in current context",
+                             (parser->local_variables_forbidden_p
+                              & LOCAL_VARS_FORBIDDEN));
+  cp_debug_print_flag (file, "'this' forbidden in current context",
+                             (parser->local_variables_forbidden_p
+                              & THIS_FORBIDDEN));
   cp_debug_print_flag (file, "In unbraced linkage specification",
                              parser->in_unbraced_linkage_specification_p);
   cp_debug_print_flag (file, "Parsing a declarator",
@@ -567,8 +574,10 @@ cp_debug_parser (FILE *file, cp_parser *parser)
   cp_debug_print_flag (file, "Colon doesn't start a class definition",
                              parser->colon_doesnt_start_class_def_p);
   if (parser->type_definition_forbidden_message)
-    fprintf (file, "Error message for forbidden type definitions: %s\n",
-            parser->type_definition_forbidden_message);
+    fprintf (file, "Error message for forbidden type definitions: %s %s\n",
+            parser->type_definition_forbidden_message,
+            parser->type_definition_forbidden_message_arg
+            ? parser->type_definition_forbidden_message_arg : "<none>");
   cp_debug_print_unparsed_queues (file, parser->unparsed_queues);
   fprintf (file, "Number of class definitions in progress: %u\n",
           parser->num_classes_being_defined);
@@ -762,6 +771,16 @@ cp_lexer_previous_token (cp_lexer *lexer)
   return cp_lexer_token_at (lexer, tp);
 }
 
+/* Overload for make_location, taking the lexer to mean the location of the
+   previous token.  */
+
+static inline location_t
+make_location (location_t caret, location_t start, cp_lexer *lexer)
+{
+  cp_token *t = cp_lexer_previous_token (lexer);
+  return make_location (caret, start, t->location);
+}
+
 /* nonzero if we are presently saving tokens.  */
 
 static inline int
@@ -813,14 +832,28 @@ cp_lexer_get_preprocessor_token (cp_lexer *lexer, cp_token *token)
             {
               /* Warn about the C++0x keyword (but still treat it as
                  an identifier).  */
-              warning (OPT_Wc__11_compat, 
-                       "identifier %qE is a keyword in C++11",
-                       token->u.value);
+             warning_at (token->location, OPT_Wc__11_compat,
+                         "identifier %qE is a keyword in C++11",
+                         token->u.value);
 
               /* Clear out the C_RID_CODE so we don't warn about this
                  particular identifier-turned-keyword again.  */
               C_SET_RID_CODE (token->u.value, RID_MAX);
             }
+         if (warn_cxx20_compat
+             && C_RID_CODE (token->u.value) >= RID_FIRST_CXX20
+             && C_RID_CODE (token->u.value) <= RID_LAST_CXX20)
+           {
+             /* Warn about the C++20 keyword (but still treat it as
+                an identifier).  */
+             warning_at (token->location, OPT_Wc__20_compat,
+                         "identifier %qE is a keyword in C++20",
+                         token->u.value);
+
+             /* Clear out the C_RID_CODE so we don't warn about this
+                particular identifier-turned-keyword again.  */
+             C_SET_RID_CODE (token->u.value, RID_MAX);
+           }
 
          token->keyword = RID_MAX;
        }
@@ -945,6 +978,7 @@ cp_keyword_starts_decl_specifier_p (enum rid keyword)
     case RID_TYPENAME:
       /* Simple type specifiers.  */
     case RID_CHAR:
+    case RID_CHAR8:
     case RID_CHAR16:
     case RID_CHAR32:
     case RID_WCHAR:
@@ -957,13 +991,14 @@ cp_keyword_starts_decl_specifier_p (enum rid keyword)
     case RID_FLOAT:
     case RID_DOUBLE:
     case RID_VOID:
-      /* GNU extensions.  */ 
+      /* GNU extensions.  */
     case RID_ATTRIBUTE:
     case RID_TYPEOF:
       /* C++0x extensions.  */
     case RID_DECLTYPE:
     case RID_UNDERLYING_TYPE:
     case RID_CONSTEXPR:
+    case RID_CONSTINIT:
       return true;
 
     default:
@@ -1302,7 +1337,7 @@ cp_lexer_start_debugging (cp_lexer* lexer)
 {
   if (!LEXER_DEBUGGING_ENABLED_P)
     fatal_error (input_location,
-                "LEXER_DEBUGGING_ENABLED_P is not set to true");
+                "%<LEXER_DEBUGGING_ENABLED_P%> is not set to true");
 
   lexer->debugging_p = true;
   cp_lexer_debug_stream = stderr;
@@ -1315,7 +1350,7 @@ cp_lexer_stop_debugging (cp_lexer* lexer)
 {
   if (!LEXER_DEBUGGING_ENABLED_P)
     fatal_error (input_location,
-                "LEXER_DEBUGGING_ENABLED_P is not set to true");
+                "%<LEXER_DEBUGGING_ENABLED_P%> is not set to true");
 
   lexer->debugging_p = false;
   cp_lexer_debug_stream = NULL;
@@ -1634,7 +1669,7 @@ make_array_declarator (cp_declarator *element, tree bounds)
 
 /* Determine whether the declarator we've seen so far can be a
    parameter pack, when followed by an ellipsis.  */
-static bool 
+static bool
 declarator_can_be_parameter_pack (cp_declarator *declarator)
 {
   if (declarator && declarator->parameter_pack_p)
@@ -1643,7 +1678,7 @@ declarator_can_be_parameter_pack (cp_declarator *declarator)
 
   /* Search for a declarator name, or any other declarator that goes
      after the point where the ellipsis could appear in a parameter
-     pack. If we find any of these, then this declarator can not be
+     pack. If we find any of these, then this declarator cannot be
      made into a parameter pack.  */
   bool found = false;
   while (declarator && !found)
@@ -1715,7 +1750,7 @@ function_declarator_p (const cp_declarator *declarator)
     }
   return false;
 }
+
 /* The parser.  */
 
 /* Overview
@@ -1793,7 +1828,9 @@ enum
   /* When parsing a decl-specifier-seq, only allow mutable or constexpr.  */
   CP_PARSER_FLAGS_ONLY_MUTABLE_OR_CONSTEXPR = 0x10,
   /* When parsing a decl-specifier-seq, allow missing typename.  */
-  CP_PARSER_FLAGS_TYPENAME_OPTIONAL = 0x20
+  CP_PARSER_FLAGS_TYPENAME_OPTIONAL = 0x20,
+  /* When parsing of the noexcept-specifier should be delayed.  */
+  CP_PARSER_FLAGS_DELAY_NOEXCEPT = 0x40
 };
 
 /* This type is used for parameters and variables which hold
@@ -1968,11 +2005,14 @@ cp_parser_context_new (cp_parser_context* next)
   parser->unparsed_queues->last ().nsdmis
 #define unparsed_classes \
   parser->unparsed_queues->last ().classes
+#define unparsed_noexcepts \
+  parser->unparsed_queues->last ().noexcepts
 
 static void
 push_unparsed_function_queues (cp_parser *parser)
 {
-  cp_unparsed_functions_entry e = {NULL, make_tree_vector (), NULL, NULL};
+  cp_unparsed_functions_entry e = { NULL, make_tree_vector (), NULL, NULL,
+                                   NULL };
   vec_safe_push (parser->unparsed_queues, e);
 }
 
@@ -2077,7 +2117,7 @@ static cp_expr cp_parser_assignment_expression
 static enum tree_code cp_parser_assignment_operator_opt
   (cp_parser *);
 static cp_expr cp_parser_expression
-  (cp_parser *, cp_id_kind * = NULL, bool = false, bool = false);
+  (cp_parser *, cp_id_kind * = NULL, bool = false, bool = false, bool = false);
 static cp_expr cp_parser_constant_expression
   (cp_parser *, bool = false, bool * = NULL, bool = false);
 static cp_expr cp_parser_builtin_offsetof
@@ -2158,7 +2198,7 @@ static tree cp_parser_simple_type_specifier
   (cp_parser *, cp_decl_specifier_seq *, cp_parser_flags);
 static tree cp_parser_type_name
   (cp_parser *, bool);
-static tree cp_parser_nonclass_name 
+static tree cp_parser_nonclass_name
   (cp_parser* parser);
 static tree cp_parser_elaborated_type_specifier
   (cp_parser *, bool, bool);
@@ -2203,9 +2243,10 @@ static tree cp_parser_init_declarator
    location_t *, tree *);
 static cp_declarator *cp_parser_declarator
   (cp_parser *, cp_parser_declarator_kind, cp_parser_flags, int *, bool *,
-   bool, bool);
+   bool, bool, bool);
 static cp_declarator *cp_parser_direct_declarator
-  (cp_parser *, cp_parser_declarator_kind, cp_parser_flags, int *, bool, bool);
+  (cp_parser *, cp_parser_declarator_kind, cp_parser_flags, int *, bool, bool,
+   bool);
 static enum tree_code cp_parser_ptr_operator
   (cp_parser *, tree *, cp_cv_quals *, tree *);
 static cp_cv_quals cp_parser_cv_qualifier_seq_opt
@@ -2235,7 +2276,7 @@ static tree cp_parser_parameter_declaration_list
   (cp_parser *, cp_parser_flags);
 static cp_parameter_declarator *cp_parser_parameter_declaration
   (cp_parser *, cp_parser_flags, bool, bool *);
-static tree cp_parser_default_argument 
+static tree cp_parser_default_argument
   (cp_parser *, bool);
 static void cp_parser_function_body
   (cp_parser *, bool);
@@ -2246,7 +2287,7 @@ static cp_expr cp_parser_initializer_clause
 static cp_expr cp_parser_braced_list
   (cp_parser*, bool*);
 static vec<constructor_elt, va_gc> *cp_parser_initializer_list
-  (cp_parser *, bool *);
+  (cp_parser *, bool *, bool *);
 
 static void cp_parser_ctor_initializer_opt_and_function_body
   (cp_parser *, bool);
@@ -2339,7 +2380,7 @@ static void cp_parser_explicit_instantiation
 static void cp_parser_explicit_specialization
   (cp_parser *);
 
-/* Exception handling [gram.exception] */
+/* Exception handling [gram.except] */
 
 static tree cp_parser_try_block
   (cp_parser *);
@@ -2354,9 +2395,11 @@ static tree cp_parser_exception_declaration
 static tree cp_parser_throw_expression
   (cp_parser *);
 static tree cp_parser_exception_specification_opt
-  (cp_parser *);
+  (cp_parser *, cp_parser_flags);
 static tree cp_parser_type_id_list
   (cp_parser *);
+static tree cp_parser_noexcept_specification_opt
+  (cp_parser *, cp_parser_flags, bool, bool *, bool);
 
 /* GNU Extensions */
 
@@ -2475,9 +2518,9 @@ static tree cp_parser_objc_statement
   (cp_parser *);
 static bool cp_parser_objc_valid_prefix_attributes
   (cp_parser *, tree *);
-static void cp_parser_objc_at_property_declaration 
+static void cp_parser_objc_at_property_declaration
   (cp_parser *) ;
-static void cp_parser_objc_at_synthesize_declaration 
+static void cp_parser_objc_at_synthesize_declaration
   (cp_parser *) ;
 static void cp_parser_objc_at_dynamic_declaration
   (cp_parser *) ;
@@ -2501,7 +2544,7 @@ static cp_expr cp_parser_simple_cast_expression
 static tree cp_parser_global_scope_opt
   (cp_parser *, bool);
 static bool cp_parser_constructor_declarator_p
-  (cp_parser *, bool);
+  (cp_parser *, cp_parser_flags, bool);
 static tree cp_parser_function_definition_from_specifiers_and_declarator
   (cp_parser *, cp_decl_specifier_seq *, tree, const cp_declarator *);
 static tree cp_parser_function_definition_after_declarator
@@ -2981,7 +3024,7 @@ cp_parser_name_lookup_error (cp_parser* parser,
            break;
          default:
            gcc_unreachable ();
-           
+
        }
     }
   else if (parser->scope == global_namespace)
@@ -3049,8 +3092,9 @@ cp_parser_check_type_definition (cp_parser* parser)
   if (parser->type_definition_forbidden_message)
     {
       /* Don't use `%s' to print the string, because quotations (`%<', `%>')
-        in the message need to be interpreted.  */
-      error (parser->type_definition_forbidden_message);
+        or %qs in the message need to be interpreted.  */
+      error (parser->type_definition_forbidden_message,
+            parser->type_definition_forbidden_message_arg);
       return false;
     }
   return true;
@@ -3079,7 +3123,7 @@ cp_parser_check_for_definition_in_return_type (cp_declarator *declarator,
     {
       error_at (type_location,
                "new types may not be defined in a return type");
-      inform (type_location, 
+      inform (type_location,
              "(perhaps a semicolon is missing after the definition of %qT)",
              type);
     }
@@ -3283,7 +3327,7 @@ cp_parser_diagnose_invalid_type_name (cp_parser *parser, tree id,
                decl);
       if (DECL_CLASS_TEMPLATE_P (decl) && cxx_dialect < cxx17)
        inform (location, "class template argument deduction is only available "
-               "with -std=c++17 or -std=gnu++17");
+               "with %<-std=c++17%> or %<-std=gnu++17%>");
       inform (DECL_SOURCE_LOCATION (decl), "%qD declared here", decl);
     }
   else if (TREE_CODE (id) == BIT_NOT_EXPR)
@@ -3317,17 +3361,20 @@ cp_parser_diagnose_invalid_type_name (cp_parser *parser, tree id,
         The user should have said "typename A<T>::X".  */
       if (cxx_dialect < cxx11 && id == ridpointers[(int)RID_CONSTEXPR])
        inform (location, "C++11 %<constexpr%> only available with "
-               "-std=c++11 or -std=gnu++11");
+               "%<-std=c++11%> or %<-std=gnu++11%>");
       else if (cxx_dialect < cxx11 && id == ridpointers[(int)RID_NOEXCEPT])
        inform (location, "C++11 %<noexcept%> only available with "
-               "-std=c++11 or -std=gnu++11");
+               "%<-std=c++11%> or %<-std=gnu++11%>");
       else if (cxx_dialect < cxx11
               && TREE_CODE (id) == IDENTIFIER_NODE
               && id_equal (id, "thread_local"))
        inform (location, "C++11 %<thread_local%> only available with "
-               "-std=c++11 or -std=gnu++11");
+               "%<-std=c++11%> or %<-std=gnu++11%>");
+      else if (cxx_dialect < cxx2a && id == ridpointers[(int)RID_CONSTINIT])
+       inform (location, "C++20 %<constinit%> only available with "
+               "%<-std=c++2a%> or %<-std=gnu++2a%>");
       else if (!flag_concepts && id == ridpointers[(int)RID_CONCEPT])
-       inform (location, "%<concept%> only available with -fconcepts");
+       inform (location, "%<concept%> only available with %<-fconcepts%>");
       else if (processing_template_decl && current_class_type
               && TYPE_BINFO (current_class_type))
        {
@@ -3352,7 +3399,7 @@ cp_parser_diagnose_invalid_type_name (cp_parser *parser, tree id,
                    if (TREE_CODE (field) == TYPE_DECL
                        && DECL_NAME (field) == id)
                      {
-                       inform (location, 
+                       inform (location,
                                "(perhaps %<typename %T::%E%> was intended)",
                                BINFO_TYPE (b), id);
                        break;
@@ -3951,7 +3998,7 @@ cp_parser_new (void)
   parser->non_integral_constant_expression_p = false;
 
   /* Local variable names are not forbidden.  */
-  parser->local_variables_forbidden_p = false;
+  parser->local_variables_forbidden_p = 0;
 
   /* We are not processing an `extern "C"' declaration.  */
   parser->in_unbraced_linkage_specification_p = false;
@@ -4231,9 +4278,14 @@ cp_parser_string_literal (cp_parser *parser, bool translate, bool wide_ok,
        {
        default:
        case CPP_STRING:
-       case CPP_UTF8STRING:
          TREE_TYPE (value) = char_array_type_node;
          break;
+       case CPP_UTF8STRING:
+         if (flag_char8_t)
+           TREE_TYPE (value) = char8_array_type_node;
+         else
+           TREE_TYPE (value) = char_array_type_node;
+         break;
        case CPP_STRING16:
          TREE_TYPE (value) = char16_array_type_node;
          break;
@@ -4332,18 +4384,16 @@ cp_parser_userdef_char_literal (cp_parser *parser)
 
   /* Build up a call to the user-defined operator  */
   /* Lookup the name we got back from the id-expression.  */
-  vec<tree, va_gc> *args = make_tree_vector ();
+  releasing_vec args;
   vec_safe_push (args, value);
   decl = lookup_literal_operator (name, args);
   if (!decl || decl == error_mark_node)
     {
       error ("unable to find character literal operator %qD with %qT argument",
             name, TREE_TYPE (value));
-      release_tree_vector (args);
       return error_mark_node;
     }
   result = finish_call_expr (decl, &args, false, true, tf_warning_or_error);
-  release_tree_vector (args);
   return result;
 }
 
@@ -4430,11 +4480,10 @@ cp_parser_userdef_numeric_literal (cp_parser *parser)
   tree num_string = USERDEF_LITERAL_NUM_STRING (literal);
   tree name = cp_literal_operator_id (IDENTIFIER_POINTER (suffix_id));
   tree decl, result;
-  vec<tree, va_gc> *args;
 
   /* Look for a literal operator taking the exact type of numeric argument
      as the literal value.  */
-  args = make_tree_vector ();
+  releasing_vec args;
   vec_safe_push (args, value);
   decl = lookup_literal_operator (name, args);
   if (decl && decl != error_mark_node)
@@ -4459,30 +4508,26 @@ cp_parser_userdef_numeric_literal (cp_parser *parser)
                        "floating literal truncated to zero");
        }
 
-      release_tree_vector (args);
       return result;
     }
-  release_tree_vector (args);
 
   /* If the numeric argument didn't work, look for a raw literal
      operator taking a const char* argument consisting of the number
      in string format.  */
-  args = make_tree_vector ();
+  args->truncate (0);
   vec_safe_push (args, num_string);
   decl = lookup_literal_operator (name, args);
   if (decl && decl != error_mark_node)
     {
       result = finish_call_expr (decl, &args, false, true,
                                 tf_warning_or_error);
-      release_tree_vector (args);
       return result;
     }
-  release_tree_vector (args);
 
   /* If the raw literal didn't work, look for a non-type template
      function with parameter pack char....  Call the function with
      template parameter characters representing the number.  */
-  args = make_tree_vector ();
+  args->truncate (0);
   decl = lookup_literal_operator (name, args);
   if (decl && decl != error_mark_node)
     {
@@ -4496,12 +4541,9 @@ cp_parser_userdef_numeric_literal (cp_parser *parser)
       decl = lookup_template_function (decl, tmpl_args);
       result = finish_call_expr (decl, &args, false, true,
                                 tf_warning_or_error);
-      release_tree_vector (args);
       return result;
     }
 
-  release_tree_vector (args);
-
   /* In C++14 the standard library defines complex number suffixes that
      conflict with GNU extensions.  Prefer them if <complex> is #included.  */
   bool ext = cpp_get_options (parse_in)->ext_numeric_literals;
@@ -4534,14 +4576,14 @@ cp_parser_userdef_numeric_literal (cp_parser *parser)
   else if (i14)
     {
       inform (token->location, "add %<using namespace std::complex_literals%> "
-             "(from <complex>) to enable the C++14 user-defined literal "
+             "(from %<<complex>%>) to enable the C++14 user-defined literal "
              "suffixes");
       if (ext)
        inform (token->location, "or use %<j%> instead of %<i%> for the "
                "GNU built-in suffix");
     }
   else if (!ext)
-    inform (token->location, "use -fext-numeric-literals "
+    inform (token->location, "use %<-fext-numeric-literals%> "
            "to enable more built-in suffixes");
 
   if (kind == DK_ERROR)
@@ -4589,8 +4631,7 @@ cp_parser_userdef_string_literal (tree literal)
 
   /* Build up a call to the user-defined operator.  */
   /* Lookup the name we got back from the id-expression.  */
-  releasing_vec rargs;
-  vec<tree, va_gc> *&args = rargs.get_ref();
+  releasing_vec args;
   vec_safe_push (args, value);
   vec_safe_push (args, build_int_cst (size_type_node, len));
   decl = lookup_literal_operator (name, args);
@@ -4644,7 +4685,7 @@ static void
 cp_parser_translation_unit (cp_parser* parser)
 {
   gcc_checking_assert (!cp_error_declarator);
-  
+
   /* Create the declarator obstack.  */
   gcc_obstack_init (&declarator_obstack);
   /* Create the error declarator.  */
@@ -4660,7 +4701,7 @@ cp_parser_translation_unit (cp_parser* parser)
   for (;;)
     {
       cp_token *token = cp_lexer_peek_token (parser->lexer);
-      
+
       /* If we're entering or exiting a region that's implicitly
         extern "C", modify the lang context appropriately.  */
       if (implicit_extern_c
@@ -5110,14 +5151,14 @@ cp_parser_fold_expression (cp_parser *parser, tree expr1)
      __builtin_offsetof ( type-id , offsetof-expression )
 
    C++ Extensions:
-     __has_nothrow_assign ( type-id )   
+     __has_nothrow_assign ( type-id )
      __has_nothrow_constructor ( type-id )
      __has_nothrow_copy ( type-id )
-     __has_trivial_assign ( type-id )   
+     __has_trivial_assign ( type-id )
      __has_trivial_constructor ( type-id )
      __has_trivial_copy ( type-id )
      __has_trivial_destructor ( type-id )
-     __has_virtual_destructor ( type-id )     
+     __has_virtual_destructor ( type-id )
      __is_abstract ( type-id )
      __is_base_of ( type-id , type-id )
      __is_class ( type-id )
@@ -5321,7 +5362,7 @@ cp_parser_primary_expression (cp_parser *parser,
                && cxx_dialect < cxx17
                && !in_system_header_at (input_location))
              pedwarn (input_location, 0, "fold-expressions only available "
-                      "with -std=c++17 or -std=gnu++17");
+                      "with %<-std=c++17%> or %<-std=gnu++17%>");
          }
        else
          /* Let the front end know that this expression was
@@ -5405,7 +5446,7 @@ cp_parser_primary_expression (cp_parser *parser,
          /* Recognize the `this' keyword.  */
        case RID_THIS:
          cp_lexer_consume_token (parser->lexer);
-         if (parser->local_variables_forbidden_p)
+         if (parser->local_variables_forbidden_p & THIS_FORBIDDEN)
            {
              error_at (token->location,
                        "%<this%> may not be used in this context");
@@ -5505,10 +5546,10 @@ cp_parser_primary_expression (cp_parser *parser,
 
        case RID_HAS_NOTHROW_ASSIGN:
        case RID_HAS_NOTHROW_CONSTRUCTOR:
-       case RID_HAS_NOTHROW_COPY:        
+       case RID_HAS_NOTHROW_COPY:
        case RID_HAS_TRIVIAL_ASSIGN:
        case RID_HAS_TRIVIAL_CONSTRUCTOR:
-       case RID_HAS_TRIVIAL_COPY:        
+       case RID_HAS_TRIVIAL_COPY:
        case RID_HAS_TRIVIAL_DESTRUCTOR:
        case RID_HAS_UNIQUE_OBJ_REPRESENTATIONS:
        case RID_HAS_VIRTUAL_DESTRUCTOR:
@@ -5681,14 +5722,14 @@ cp_parser_primary_expression (cp_parser *parser,
                      template <int N> struct A {
                        int a[B<N>::i];
                      };
-                    
+
                   is accepted.  At template-instantiation time, we
                   will check that B<N>::i is actually a constant.  */
                return decl;
              }
            /* Check to see if DECL is a local variable in a context
               where that is forbidden.  */
-           if (parser->local_variables_forbidden_p
+           if ((parser->local_variables_forbidden_p & LOCAL_VARS_FORBIDDEN)
                && local_variable_p (decl))
              {
                error_at (id_expression.get_location (),
@@ -5966,6 +6007,7 @@ cp_parser_unqualified_id (cp_parser* parser,
        tree object_scope;
        tree scope;
        bool done;
+       location_t tilde_loc = token->location;
 
        /* Consume the `~' token.  */
        cp_lexer_consume_token (parser->lexer);
@@ -6028,9 +6070,18 @@ cp_parser_unqualified_id (cp_parser* parser,
          }
        gcc_assert (!scope || TYPE_P (scope));
 
+       token = cp_lexer_peek_token (parser->lexer);
+
+       /* Create a location with caret == start at the tilde,
+          finishing at the end of the peeked token, e.g:
+          ~token
+          ^~~~~~.  */
+       location_t loc
+         = make_location (tilde_loc, tilde_loc, token->location);
+
        /* If the name is of the form "X::~X" it's OK even if X is a
           typedef.  */
-       token = cp_lexer_peek_token (parser->lexer);
+
        if (scope
            && token->type == CPP_NAME
            && (cp_lexer_peek_nth_token (parser->lexer, 2)->type
@@ -6040,18 +6091,18 @@ cp_parser_unqualified_id (cp_parser* parser,
                    && constructor_name_p (token->u.value, scope))))
          {
            cp_lexer_consume_token (parser->lexer);
-           return build_nt (BIT_NOT_EXPR, scope);
+           return build_min_nt_loc (loc, BIT_NOT_EXPR, scope);
          }
 
        /* ~auto means the destructor of whatever the object is.  */
        if (cp_parser_is_keyword (token, RID_AUTO))
          {
            if (cxx_dialect < cxx14)
-             pedwarn (input_location, 0,
+             pedwarn (loc, 0,
                       "%<~auto%> only available with "
-                      "-std=c++14 or -std=gnu++14");
+                      "%<-std=c++14%> or %<-std=gnu++14%>");
            cp_lexer_consume_token (parser->lexer);
-           return build_nt (BIT_NOT_EXPR, make_auto ());
+           return build_min_nt_loc (loc, BIT_NOT_EXPR, make_auto ());
          }
 
        /* If there was an explicit qualification (S::~T), first look
@@ -6141,7 +6192,7 @@ cp_parser_unqualified_id (cp_parser* parser,
                   time.  */
                type_decl = cp_parser_identifier (parser);
                if (type_decl != error_mark_node)
-                 type_decl = build_nt (BIT_NOT_EXPR, type_decl);
+                 type_decl = build_min_nt_loc (loc, BIT_NOT_EXPR, type_decl);
                return type_decl;
              }
          }
@@ -6150,7 +6201,7 @@ cp_parser_unqualified_id (cp_parser* parser,
           class.  That allows us to keep parsing after running
           into ill-formed destructor names.  */
        if (type_decl == error_mark_node && scope)
-         return build_nt (BIT_NOT_EXPR, scope);
+         return build_min_nt_loc (loc, BIT_NOT_EXPR, scope);
        else if (type_decl == error_mark_node)
          return error_mark_node;
 
@@ -6158,7 +6209,7 @@ cp_parser_unqualified_id (cp_parser* parser,
        if (declarator_p && scope && !check_dtor_name (scope, type_decl))
          {
            if (!cp_parser_uncommitted_to_tentative_parse_p (parser))
-             error_at (token->location,
+             error_at (loc,
                        "declaration of %<~%T%> as member of %qT",
                        type_decl, scope);
            cp_parser_simulate_error (parser);
@@ -6173,11 +6224,11 @@ cp_parser_unqualified_id (cp_parser* parser,
            && !DECL_IMPLICIT_TYPEDEF_P (type_decl)
            && !DECL_SELF_REFERENCE_P (type_decl)
            && !cp_parser_uncommitted_to_tentative_parse_p (parser))
-         error_at (token->location,
+         error_at (loc,
                    "typedef-name %qD used as destructor declarator",
                    type_decl);
 
-       return build_nt (BIT_NOT_EXPR, TREE_TYPE (type_decl));
+       return build_min_nt_loc (loc, BIT_NOT_EXPR, TREE_TYPE (type_decl));
       }
 
     case CPP_KEYWORD:
@@ -6254,7 +6305,8 @@ cp_parser_nested_name_specifier_opt (cp_parser *parser,
   cp_token *token;
 
   /* Remember where the nested-name-specifier starts.  */
-  if (cp_parser_uncommitted_to_tentative_parse_p (parser))
+  if (cp_parser_uncommitted_to_tentative_parse_p (parser)
+      && cp_lexer_next_token_is_not (parser->lexer, CPP_NESTED_NAME_SPECIFIER))
     {
       start = cp_lexer_token_position (parser->lexer, false);
       push_deferring_access_checks (dk_deferred);
@@ -6388,9 +6440,11 @@ cp_parser_nested_name_specifier_opt (cp_parser *parser,
                  == CPP_SCOPE))
            {
              token = cp_lexer_consume_token (parser->lexer);
-             error_at (token->location, "decltype evaluates to %qT, "
-                       "which is not a class or enumeration type",
-                       token->u.tree_check_value->value);
+             tree dtype = token->u.tree_check_value->value;
+             if (dtype != error_mark_node)
+               error_at (token->location, "%<decltype%> evaluates to %qT, "
+                         "which is not a class or enumeration type",
+                         dtype);
              parser->scope = error_mark_node;
              error_p = true;
              /* As below.  */
@@ -6666,7 +6720,7 @@ cp_parser_qualifying_entity (cp_parser *parser,
   saved_object_scope = parser->object_scope;
   /* Try for a class-name first.  If the SAVED_SCOPE is a type, then
      there is no need to look for a namespace-name.  */
-  only_class_p = template_keyword_p 
+  only_class_p = template_keyword_p
     || (saved_scope && TYPE_P (saved_scope) && cxx_dialect == cxx98);
   if (!only_class_p)
     cp_parser_parse_tentatively (parser);
@@ -6713,7 +6767,7 @@ cp_parser_compound_literal_p (cp_parser *parser)
     = (cp_parser_skip_to_closing_parenthesis (parser, false, false,
                                              /*consume_paren=*/true)
        && cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE));
-  
+
   /* Roll back the tokens we skipped.  */
   cp_lexer_rollback_tokens (parser->lexer);
 
@@ -6863,7 +6917,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
            break;
          case RID_REINTCAST:
            postfix_expression
-             = build_reinterpret_cast (type, expression, 
+             = build_reinterpret_cast (type, expression,
                                         tf_warning_or_error);
            break;
          case RID_CONSTCAST:
@@ -7031,6 +7085,32 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
        break;
       }
 
+    case RID_BUILTIN_CONVERTVECTOR:
+      {
+       tree expression;
+       tree type;
+       /* Consume the `__builtin_convertvector' token.  */
+       cp_lexer_consume_token (parser->lexer);
+       /* Look for the opening `('.  */
+       matching_parens parens;
+       parens.require_open (parser);
+       /* Now, parse the assignment-expression.  */
+       expression = cp_parser_assignment_expression (parser);
+       /* Look for the `,'.  */
+       cp_parser_require (parser, CPP_COMMA, RT_COMMA);
+       location_t type_location
+         = cp_lexer_peek_token (parser->lexer)->location;
+       /* Parse the type-id.  */
+       {
+         type_id_in_expr_sentinel s (parser);
+         type = cp_parser_type_id (parser);
+       }
+       /* Look for the closing `)'.  */
+       parens.require_close (parser);
+       return cp_build_vec_convert (expression, type_location, type,
+                                    tf_warning_or_error);
+      }
+
     default:
       {
        tree type;
@@ -7464,7 +7544,9 @@ cp_parser_postfix_open_square_expression (cp_parser *parser,
          index = cp_parser_braced_list (parser, &expr_nonconst_p);
        }
       else
-       index = cp_parser_expression (parser);
+       index = cp_parser_expression (parser, NULL, /*cast_p=*/false,
+                                     /*decltype_p=*/false,
+                                     /*warn_comma_p=*/warn_comma_subscript);
     }
 
   parser->greater_than_is_operator_p = saved_greater_than_is_operator_p;
@@ -7719,17 +7801,15 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser,
              (name, parser->scope, scope);
          postfix_expression
            = finish_class_member_access_expr (postfix_expression, name,
-                                              template_p, 
+                                              template_p,
                                               tf_warning_or_error);
          /* Build a location e.g.:
               ptr->access_expr
               ~~~^~~~~~~~~~~~~
             where the caret is at the deref token, ranging from
             the start of postfix_expression to the end of the access expr.  */
-         location_t end_loc
-           = get_finish (cp_lexer_previous_token (parser->lexer)->location);
          location_t combined_loc
-           = make_location (input_location, start_loc, end_loc);
+           = make_location (input_location, start_loc, parser->lexer);
          protected_set_expr_location (postfix_expression, combined_loc);
        }
     }
@@ -7957,7 +8037,7 @@ cp_parser_pseudo_destructor_name (cp_parser* parser,
       if (cxx_dialect < cxx14)
        pedwarn (input_location, 0,
                 "%<~auto%> only available with "
-                "-std=c++14 or -std=gnu++14");
+                "%<-std=c++14%> or %<-std=gnu++14%>");
       cp_lexer_consume_token (parser->lexer);
       cp_lexer_consume_token (parser->lexer);
       *scope = NULL_TREE;
@@ -8139,10 +8219,8 @@ cp_parser_unary_expression (cp_parser *parser, cp_id_kind * pidk,
               ^~~~~~~~~~~~~~
               with start == caret at the start of the "alignof"/"sizeof"
               token, with the endpoint at the final closing paren.  */
-           location_t finish_loc
-             = cp_lexer_previous_token (parser->lexer)->location;
            location_t compound_loc
-             = make_location (start_loc, start_loc, finish_loc);
+             = make_location (start_loc, start_loc, parser->lexer);
 
            cp_expr ret_expr (ret);
            ret_expr.set_location (compound_loc);
@@ -8243,8 +8321,6 @@ cp_parser_unary_expression (cp_parser *parser, cp_id_kind * pidk,
 
            parser->type_definition_forbidden_message = saved_message;
 
-           location_t finish_loc
-             = cp_lexer_peek_token (parser->lexer)->location;
            parens.require_close (parser);
 
            /* Construct a location of the form:
@@ -8252,7 +8328,7 @@ cp_parser_unary_expression (cp_parser *parser, cp_id_kind * pidk,
               ^~~~~~~~~~~~~~~
               with start == caret, finishing at the close-paren.  */
            location_t noexcept_loc
-             = make_location (start_loc, start_loc, finish_loc);
+             = make_location (start_loc, start_loc, parser->lexer);
 
            return cp_expr (finish_noexcept_expr (expr, tf_warning_or_error),
                            noexcept_loc);
@@ -8303,15 +8379,13 @@ cp_parser_unary_expression (cp_parser *parser, cp_id_kind * pidk,
          /* Consume the '&&' token.  */
          cp_lexer_consume_token (parser->lexer);
          /* Look for the identifier.  */
-         location_t finish_loc
-           = get_finish (cp_lexer_peek_token (parser->lexer)->location);
          identifier = cp_parser_identifier (parser);
          /* Construct a location of the form:
               &&label
               ^~~~~~~
             with caret==start at the "&&", finish at the end of the label.  */
          location_t combined_loc
-           = make_location (start_loc, start_loc, finish_loc);
+           = make_location (start_loc, start_loc, parser->lexer);
          /* Create an expression representing the address.  */
          expression = finish_label_address_expr (identifier, combined_loc);
          if (cp_parser_non_integral_constant_expression (parser,
@@ -8472,12 +8546,12 @@ cp_parser_has_attribute_expression (cp_parser *parser)
   /* Types cannot be defined in a `sizeof' expression.  Save away the
      old message.  */
   const char *saved_message = parser->type_definition_forbidden_message;
-  /* And create the new one.  */
-  const int kwd = RID_BUILTIN_HAS_ATTRIBUTE;
-  char *tmp = concat ("types may not be defined in %<",
-                     IDENTIFIER_POINTER (ridpointers[kwd]),
-                     "%> expressions", NULL);
-  parser->type_definition_forbidden_message = tmp;
+  const char *saved_message_arg
+    = parser->type_definition_forbidden_message_arg;
+  parser->type_definition_forbidden_message
+    = G_("types may not be defined in %qs expressions");
+  parser->type_definition_forbidden_message_arg
+    = IDENTIFIER_POINTER (ridpointers[RID_BUILTIN_HAS_ATTRIBUTE]);
 
   /* The restrictions on constant-expressions do not apply inside
      sizeof expressions.  */
@@ -8506,9 +8580,9 @@ cp_parser_has_attribute_expression (cp_parser *parser)
   cp_parser_parse_definitely (parser);
 
   /* If the type-id production did not work out, then we must be
-     looking at the unary-expression production.  */
+     looking at an expression.  */
   if (!oper || oper == error_mark_node)
-    oper = cp_parser_unary_expression (parser);
+    oper = cp_parser_assignment_expression (parser);
 
   STRIP_ANY_LOCATION_WRAPPER (oper);
 
@@ -8516,10 +8590,9 @@ cp_parser_has_attribute_expression (cp_parser *parser)
   --cp_unevaluated_operand;
   --c_inhibit_evaluation_warnings;
 
-  /* Free the message we created.  */
-  free (tmp);
   /* And restore the old one.  */
   parser->type_definition_forbidden_message = saved_message;
+  parser->type_definition_forbidden_message_arg = saved_message_arg;
   parser->integral_constant_expression_p
     = saved_integral_constant_expression_p;
   parser->non_integral_constant_expression_p
@@ -8560,10 +8633,8 @@ cp_parser_has_attribute_expression (cp_parser *parser)
      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      with start == caret at the start of the built-in token,
      and with the endpoint at the final closing paren.  */
-  location_t finish_loc
-    = cp_lexer_previous_token (parser->lexer)->location;
   location_t compound_loc
-    = make_location (start_loc, start_loc, finish_loc);
+    = make_location (start_loc, start_loc, parser->lexer);
 
   cp_expr ret_expr (ret ? boolean_true_node : boolean_false_node);
   ret_expr.set_location (compound_loc);
@@ -8641,7 +8712,7 @@ cp_parser_new_expression (cp_parser* parser)
        {
          error_at (token->location,
                    "array bound forbidden after parenthesized type-id");
-         inform (token->location, 
+         inform (token->location,
                  "try removing the parentheses around the type-id");
          cp_parser_direct_new_declarator (parser);
        }
@@ -8685,9 +8756,8 @@ cp_parser_new_expression (cp_parser* parser)
                  ^~~~~~~~~~~~
          with caret == start at the start of the "new" token, and the end
          at the end of the final token we consumed.  */
-      cp_token *end_tok = cp_lexer_previous_token (parser->lexer);
-      location_t end_loc = get_finish (end_tok->location);
-      location_t combined_loc = make_location (start_loc, start_loc, end_loc);
+      location_t combined_loc = make_location (start_loc, start_loc,
+                                              parser->lexer);
 
       /* Create a representation of the new-expression.  */
       ret = build_new (&placement, type, nelts, &initializer, global_scope_p,
@@ -8815,7 +8885,7 @@ cp_parser_new_declarator_opt (cp_parser* parser)
 {
   enum tree_code code;
   tree type, std_attributes = NULL_TREE;
-  cp_cv_quals cv_quals;  
+  cp_cv_quals cv_quals;
 
   /* We don't know if there's a ptr-operator next, or not.  */
   cp_parser_parse_tentatively (parser);
@@ -9299,7 +9369,7 @@ cp_parser_cast_expression (cp_parser *parser, bool address_p, bool cast_p,
              return expr;
            }
        }
-      else 
+      else
         cp_parser_abort_tentative_parse (parser);
     }
 
@@ -9397,6 +9467,7 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p,
 {
   cp_parser_expression_stack stack;
   cp_parser_expression_stack_entry *sp = &stack[0];
+  cp_parser_expression_stack_entry *disable_warnings_sp = NULL;
   cp_parser_expression_stack_entry current;
   cp_expr rhs;
   cp_token *token;
@@ -9460,12 +9531,14 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p,
 
       /* For "false && x" or "true || x", x will never be executed;
         disable warnings while evaluating it.  */
-      if (current.tree_type == TRUTH_ANDIF_EXPR)
-       c_inhibit_evaluation_warnings +=
-         cp_fully_fold (current.lhs) == truthvalue_false_node;
-      else if (current.tree_type == TRUTH_ORIF_EXPR)
-       c_inhibit_evaluation_warnings +=
-         cp_fully_fold (current.lhs) == truthvalue_true_node;
+      if ((current.tree_type == TRUTH_ANDIF_EXPR
+          && cp_fully_fold (current.lhs) == truthvalue_false_node)
+         || (current.tree_type == TRUTH_ORIF_EXPR
+             && cp_fully_fold (current.lhs) == truthvalue_true_node))
+       {
+         disable_warnings_sp = sp;
+         ++c_inhibit_evaluation_warnings;
+       }
 
       /* Extract another operand.  It may be the RHS of this expression
         or the LHS of a new, higher priority expression.  */
@@ -9511,12 +9584,11 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p,
        }
 
       /* Undo the disabling of warnings done above.  */
-      if (current.tree_type == TRUTH_ANDIF_EXPR)
-       c_inhibit_evaluation_warnings -=
-         cp_fully_fold (current.lhs) == truthvalue_false_node;
-      else if (current.tree_type == TRUTH_ORIF_EXPR)
-       c_inhibit_evaluation_warnings -=
-         cp_fully_fold (current.lhs) == truthvalue_true_node;
+      if (sp == disable_warnings_sp)
+       {
+         disable_warnings_sp = NULL;
+         --c_inhibit_evaluation_warnings;
+       }
 
       if (warn_logical_not_paren
          && TREE_CODE_CLASS (current.tree_type) == tcc_comparison
@@ -9631,8 +9703,8 @@ cp_parser_question_colon_clause (cp_parser* parser, cp_expr logical_or_expr)
   if (cp_parser_allow_gnu_extensions_p (parser)
       && token->type == CPP_COLON)
     {
-      pedwarn (token->location, OPT_Wpedantic, 
-               "ISO C++ does not allow ?: with omitted middle operand");
+      pedwarn (token->location, OPT_Wpedantic,
+              "ISO C++ does not allow %<?:%> with omitted middle operand");
       /* Implicit true clause.  */
       expr = NULL_TREE;
       c_inhibit_evaluation_warnings +=
@@ -9856,12 +9928,13 @@ cp_parser_assignment_operator_opt (cp_parser* parser)
    CAST_P is true if this expression is the target of a cast.
    DECLTYPE_P is true if this expression is the immediate operand of decltype,
      except possibly parenthesized or on the RHS of a comma (N3276).
+   WARN_COMMA_P is true if a comma should be diagnosed.
 
    Returns a representation of the expression.  */
 
 static cp_expr
 cp_parser_expression (cp_parser* parser, cp_id_kind * pidk,
-                     bool cast_p, bool decltype_p)
+                     bool cast_p, bool decltype_p, bool warn_comma_p)
 {
   cp_expr expression = NULL_TREE;
   location_t loc = UNKNOWN_LOCATION;
@@ -9908,6 +9981,17 @@ cp_parser_expression (cp_parser* parser, cp_id_kind * pidk,
        break;
       /* Consume the `,'.  */
       loc = cp_lexer_peek_token (parser->lexer)->location;
+      if (warn_comma_p)
+       {
+         /* [depr.comma.subscript]: A comma expression appearing as
+            the expr-or-braced-init-list of a subscripting expression
+            is deprecated.  A parenthesized comma expression is not
+            deprecated.  */
+         warning_at (loc, OPT_Wcomma_subscript,
+                     "top-level comma expression in array subscript "
+                     "is deprecated");
+         warn_comma_p = false;
+       }
       cp_lexer_consume_token (parser->lexer);
       /* A comma operator cannot appear in a constant-expression.  */
       if (cp_parser_non_integral_constant_expression (parser, NIC_COMMA))
@@ -10054,7 +10138,7 @@ cp_parser_builtin_offsetof (cp_parser *parser)
   {
     const char *saved_message = parser->type_definition_forbidden_message;
     parser->type_definition_forbidden_message
-      = G_("types may not be defined within __builtin_offsetof");
+      = G_("types may not be defined within %<__builtin_offsetof%>");
     type = cp_parser_type_id (parser);
     parser->type_definition_forbidden_message = saved_message;
   }
@@ -10268,7 +10352,7 @@ cp_parser_trait_expr (cp_parser* parser, enum rid keyword)
   if (binary)
     {
       cp_parser_require (parser, CPP_COMMA, RT_COMMA);
+
       {
        type_id_in_expr_sentinel s (parser);
        type2 = cp_parser_type_id (parser);
@@ -10314,7 +10398,7 @@ cp_parser_trait_expr (cp_parser* parser, enum rid keyword)
     case CPTK_DIRECT_BASES:
       return cp_expr (finish_bases (type1, true), trait_loc);
     default:
-      return cp_expr (finish_trait_expr (kind, type1, type2), trait_loc);
+      return finish_trait_expr (trait_loc, kind, type1, type2);
     }
 }
 
@@ -10344,17 +10428,17 @@ cp_parser_lambda_expression (cp_parser* parser)
        {
          error_at (LAMBDA_EXPR_LOCATION (lambda_expr),
                    "lambda-expression in unevaluated context"
-                   " only available with -std=c++2a or -std=gnu++2a");
+                   " only available with %<-std=c++2a%> or %<-std=gnu++2a%>");
          token->error_reported = true;
        }
       ok = false;
     }
-  else if (parser->in_template_argument_list_p)
+  else if (parser->in_template_argument_list_p || processing_template_parmlist)
     {
       if (!token->error_reported)
        {
          error_at (token->location, "lambda-expression in template-argument"
-                   " only available with -std=c++2a or -std=gnu++2a");
+                   " only available with %<-std=c++2a%> or %<-std=gnu++2a%>");
          token->error_reported = true;
        }
       ok = false;
@@ -10430,7 +10514,7 @@ cp_parser_lambda_expression (cp_parser* parser)
     if (ok)
       maybe_add_lambda_conv_op (type);
 
-    type = finish_struct (type, /*attributes=*/NULL_TREE);
+    finish_struct (type, /*attributes=*/NULL_TREE);
 
     parser->num_template_parameter_lists = saved_num_template_parameter_lists;
     parser->in_statement = in_statement;
@@ -10452,10 +10536,9 @@ cp_parser_lambda_expression (cp_parser* parser)
   insert_pending_capture_proxies ();
 
   /* Update the lambda expression to a range.  */
-  cp_token *end_tok = cp_lexer_previous_token (parser->lexer);
   LAMBDA_EXPR_LOCATION (lambda_expr) = make_location (token->location,
                                                      token->location,
-                                                     end_tok->location);
+                                                     parser->lexer);
 
   if (ok)
     lambda_expr = build_lambda_object (lambda_expr);
@@ -10487,7 +10570,8 @@ cp_parser_lambda_introducer (cp_parser* parser, tree lambda_expr)
 
   /* Record default capture mode.  "[&" "[=" "[&," "[=,"  */
   if (cp_lexer_next_token_is (parser->lexer, CPP_AND)
-      && cp_lexer_peek_nth_token (parser->lexer, 2)->type != CPP_NAME)
+      && !cp_lexer_nth_token_is (parser->lexer, 2, CPP_NAME)
+      && !cp_lexer_nth_token_is_keyword (parser->lexer, 2, RID_THIS))
     LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr) = CPLD_REFERENCE;
   else if (cp_lexer_next_token_is (parser->lexer, CPP_EQ))
     LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr) = CPLD_COPY;
@@ -10501,6 +10585,8 @@ cp_parser_lambda_introducer (cp_parser* parser, tree lambda_expr)
        error ("non-local lambda expression cannot have a capture-default");
     }
 
+  hash_set<tree, true> ids;
+  tree first_capture_id = NULL_TREE;
   while (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_SQUARE))
     {
       cp_token* capture_token;
@@ -10536,11 +10622,14 @@ cp_parser_lambda_introducer (cp_parser* parser, tree lambda_expr)
            pedwarn (loc, 0, "explicit by-copy capture of %<this%> redundant "
                     "with by-copy capture default");
          cp_lexer_consume_token (parser->lexer);
-         add_capture (lambda_expr,
-                      /*id=*/this_identifier,
-                      /*initializer=*/finish_this_expr (),
-                      /*by_reference_p=*/true,
-                      explicit_init_p);
+         if (LAMBDA_EXPR_THIS_CAPTURE (lambda_expr))
+           pedwarn (input_location, 0,
+                    "already captured %qD in lambda expression",
+                    this_identifier);
+         else
+           add_capture (lambda_expr, /*id=*/this_identifier,
+                        /*initializer=*/finish_this_expr (),
+                        /*by_reference_p=*/true, explicit_init_p);
          continue;
        }
 
@@ -10551,24 +10640,39 @@ cp_parser_lambda_introducer (cp_parser* parser, tree lambda_expr)
          location_t loc = cp_lexer_peek_token (parser->lexer)->location;
          if (cxx_dialect < cxx17)
            pedwarn (loc, 0, "%<*this%> capture only available with "
-                            "-std=c++17 or -std=gnu++17");
+                            "%<-std=c++17%> or %<-std=gnu++17%>");
+         cp_lexer_consume_token (parser->lexer);
+         cp_lexer_consume_token (parser->lexer);
+         if (LAMBDA_EXPR_THIS_CAPTURE (lambda_expr))
+           pedwarn (input_location, 0,
+                    "already captured %qD in lambda expression",
+                    this_identifier);
+         else
+           add_capture (lambda_expr, /*id=*/this_identifier,
+                        /*initializer=*/finish_this_expr (),
+                        /*by_reference_p=*/false, explicit_init_p);
+         continue;
+       }
+
+      /* But reject `&this'.  */
+      if (cp_lexer_next_token_is (parser->lexer, CPP_AND)
+         && cp_lexer_nth_token_is_keyword (parser->lexer, 2, RID_THIS))
+       {
+         error_at (cp_lexer_peek_token (parser->lexer)->location,
+                   "%<this%> cannot be captured by reference");
          cp_lexer_consume_token (parser->lexer);
          cp_lexer_consume_token (parser->lexer);
-         add_capture (lambda_expr,
-                      /*id=*/this_identifier,
-                      /*initializer=*/finish_this_expr (),
-                      /*by_reference_p=*/false,
-                      explicit_init_p);
          continue;
        }
 
       bool init_pack_expansion = false;
+      location_t ellipsis_loc = UNKNOWN_LOCATION;
       if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))
        {
-         location_t loc = cp_lexer_peek_token (parser->lexer)->location;
+         ellipsis_loc = cp_lexer_peek_token (parser->lexer)->location;
          if (cxx_dialect < cxx2a)
-           pedwarn (loc, 0, "pack init-capture only available with "
-                            "-std=c++2a or -std=gnu++2a");
+           pedwarn (ellipsis_loc, 0, "pack init-capture only available with "
+                    "%<-std=c++2a%> or %<-std=gnu++2a%>");
          cp_lexer_consume_token (parser->lexer);
          init_pack_expansion = true;
        }
@@ -10607,7 +10711,7 @@ cp_parser_lambda_introducer (cp_parser* parser, tree lambda_expr)
          if (cxx_dialect < cxx14)
            pedwarn (input_location, 0,
                     "lambda capture initializers "
-                    "only available with -std=c++14 or -std=gnu++14");
+                    "only available with %<-std=c++14%> or %<-std=gnu++14%>");
          capture_init_expr = cp_parser_initializer (parser, &direct,
                                                     &non_constant, true);
          explicit_init_p = true;
@@ -10673,8 +10777,21 @@ cp_parser_lambda_introducer (cp_parser* parser, tree lambda_expr)
 
          if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))
            {
+             location_t loc = cp_lexer_peek_token (parser->lexer)->location;
              cp_lexer_consume_token (parser->lexer);
              capture_init_expr = make_pack_expansion (capture_init_expr);
+             if (init_pack_expansion)
+               {
+                 /* If what follows is an initializer, the second '...' is
+                    invalid.  But for cases like [...xs...], the first one
+                    is invalid.  */
+                 if (cp_lexer_next_token_is (parser->lexer, CPP_EQ)
+                     || cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN)
+                     || cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
+                   ellipsis_loc = loc;
+                 error_at (ellipsis_loc, "too many %<...%> in lambda capture");
+                 continue;
+               }
            }
        }
 
@@ -10693,11 +10810,28 @@ cp_parser_lambda_introducer (cp_parser* parser, tree lambda_expr)
                     "default", capture_id);
        }
 
-      add_capture (lambda_expr,
-                  capture_id,
-                  capture_init_expr,
-                  /*by_reference_p=*/capture_kind == BY_REFERENCE,
-                  explicit_init_p);
+      /* Check for duplicates.
+        Optimize for the zero or one explicit captures cases and only create
+        the hash_set after adding second capture.  */
+      bool found = false;
+      if (!ids.is_empty ())
+       found = ids.add (capture_id);
+      else if (first_capture_id == NULL_TREE)
+       first_capture_id = capture_id;
+      else if (capture_id == first_capture_id)
+       found = true;
+      else
+       {
+         ids.add (first_capture_id);
+         ids.add (capture_id);
+       }
+      if (found)
+       pedwarn (input_location, 0,
+                "already captured %qD in lambda expression", capture_id);
+      else
+       add_capture (lambda_expr, capture_id, capture_init_expr,
+                    /*by_reference_p=*/capture_kind == BY_REFERENCE,
+                    explicit_init_p);
 
       /* If there is any qualification still in effect, clear it
         now; we will be starting fresh with the next capture.  */
@@ -10730,7 +10864,8 @@ cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr)
      This means an empty parameter list, no attributes, and no exception
      specification.  */
   tree param_list = void_list_node;
-  tree attributes = NULL_TREE;
+  tree std_attrs = NULL_TREE;
+  tree gnu_attrs = NULL_TREE;
   tree exception_spec = NULL_TREE;
   tree template_param_list = NULL_TREE;
   tree tx_qual = NULL_TREE;
@@ -10745,11 +10880,11 @@ cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr)
       if (cxx_dialect < cxx14)
        pedwarn (parser->lexer->next_token->location, 0,
                 "lambda templates are only available with "
-                "-std=c++14 or -std=gnu++14");
+                "%<-std=c++14%> or %<-std=gnu++14%>");
       else if (cxx_dialect < cxx2a)
        pedwarn (parser->lexer->next_token->location, OPT_Wpedantic,
                 "lambda templates are only available with "
-                "-std=c++2a or -std=gnu++2a");
+                "%<-std=c++2a%> or %<-std=gnu++2a%>");
 
       cp_lexer_consume_token (parser->lexer);
 
@@ -10789,7 +10924,8 @@ cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr)
       /* In the decl-specifier-seq of the lambda-declarator, each
         decl-specifier shall either be mutable or constexpr.  */
       int declares_class_or_enum;
-      if (cp_lexer_next_token_is_decl_specifier_keyword (parser->lexer))
+      if (cp_lexer_next_token_is_decl_specifier_keyword (parser->lexer)
+         && !cp_next_tokens_can_be_gnu_attribute_p (parser))
        cp_parser_decl_specifier_seq (parser,
                                      CP_PARSER_FLAGS_ONLY_MUTABLE_OR_CONSTEXPR,
                                      &lambda_specs, &declares_class_or_enum);
@@ -10804,9 +10940,10 @@ cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr)
       tx_qual = cp_parser_tx_qualifier_opt (parser);
 
       /* Parse optional exception specification.  */
-      exception_spec = cp_parser_exception_specification_opt (parser);
+      exception_spec
+       = cp_parser_exception_specification_opt (parser, CP_PARSER_FLAGS_NONE);
 
-      attributes = cp_parser_std_attribute_spec_seq (parser);
+      std_attrs = cp_parser_std_attribute_spec_seq (parser);
 
       /* Parse optional trailing return type.  */
       if (cp_lexer_next_token_is (parser->lexer, CPP_DEREF))
@@ -10815,6 +10952,9 @@ cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr)
           return_type = cp_parser_trailing_type_id (parser);
         }
 
+      if (cp_next_tokens_can_be_gnu_attribute_p (parser))
+       gnu_attrs = cp_parser_gnu_attributes_opt (parser);
+
       /* The function parameters must be in scope all the way until after the
          trailing-return-type in case of decltype.  */
       pop_bindings_and_leave_scope ();
@@ -10844,7 +10984,8 @@ cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr)
            = lambda_specs.locations[ds_constexpr];
        else
          error_at (lambda_specs.locations[ds_constexpr], "%<constexpr%> "
-                   "lambda only available with -std=c++17 or -std=gnu++17");
+                   "lambda only available with %<-std=c++17%> or "
+                   "%<-std=gnu++17%>");
       }
 
     p = obstack_alloc (&declarator_obstack, 0);
@@ -10861,18 +11002,18 @@ cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr)
                                       exception_spec,
                                        return_type,
                                        /*requires_clause*/NULL_TREE);
-    declarator->std_attributes = attributes;
+    declarator->std_attributes = std_attrs;
 
     fco = grokmethod (&return_type_specs,
                      declarator,
-                     NULL_TREE);
+                     gnu_attrs);
     if (fco != error_mark_node)
       {
        DECL_INITIALIZED_IN_CLASS_P (fco) = 1;
        DECL_ARTIFICIAL (fco) = 1;
        /* Give the object parameter a different name.  */
        DECL_NAME (DECL_ARGUMENTS (fco)) = closure_identifier;
-       DECL_LAMBDA_FUNCTION (fco) = 1;
+       DECL_SET_LAMBDA_FUNCTION (fco, true);
       }
     if (template_param_list)
       {
@@ -10902,7 +11043,8 @@ static void
 cp_parser_lambda_body (cp_parser* parser, tree lambda_expr)
 {
   bool nested = (current_function_decl != NULL_TREE);
-  bool local_variables_forbidden_p = parser->local_variables_forbidden_p;
+  unsigned char local_variables_forbidden_p
+    = parser->local_variables_forbidden_p;
   bool in_function_body = parser->in_function_body;
 
   /* The body of a lambda-expression is not a subexpression of the enclosing
@@ -10919,7 +11061,7 @@ cp_parser_lambda_body (cp_parser* parser, tree lambda_expr)
   vec<tree> omp_privatization_save;
   save_omp_privatization_clauses (omp_privatization_save);
   /* Clear this in case we're in the middle of a default argument.  */
-  parser->local_variables_forbidden_p = false;
+  parser->local_variables_forbidden_p = 0;
   parser->in_function_body = true;
 
   {
@@ -11023,7 +11165,7 @@ cp_parser_statement (cp_parser* parser, tree in_statement_expr,
 {
   tree statement, std_attrs = NULL_TREE;
   cp_token *token;
-  location_t statement_location, attrs_location;
+  location_t statement_location, attrs_loc;
 
  restart:
   if (if_p != NULL)
@@ -11032,13 +11174,15 @@ cp_parser_statement (cp_parser* parser, tree in_statement_expr,
   statement = NULL_TREE;
 
   saved_token_sentinel saved_tokens (parser->lexer);
-  attrs_location = cp_lexer_peek_token (parser->lexer)->location;
+  attrs_loc = cp_lexer_peek_token (parser->lexer)->location;
   if (c_dialect_objc ())
     /* In obj-c++, seeing '[[' might be the either the beginning of
        c++11 attributes, or a nested objc-message-expression.  So
        let's parse the c++11 attributes tentatively.  */
     cp_parser_parse_tentatively (parser);
   std_attrs = cp_parser_std_attribute_spec_seq (parser);
+  if (std_attrs)
+    attrs_loc = make_location (attrs_loc, attrs_loc, parser->lexer);
   if (c_dialect_objc ())
     {
       if (!cp_parser_parse_definitely (parser))
@@ -11070,14 +11214,14 @@ cp_parser_statement (cp_parser* parser, tree in_statement_expr,
 
        case RID_IF:
        case RID_SWITCH:
-         std_attrs = process_stmt_hotness_attribute (std_attrs);
+         std_attrs = process_stmt_hotness_attribute (std_attrs, attrs_loc);
          statement = cp_parser_selection_statement (parser, if_p, chain);
          break;
 
        case RID_WHILE:
        case RID_DO:
        case RID_FOR:
-         std_attrs = process_stmt_hotness_attribute (std_attrs);
+         std_attrs = process_stmt_hotness_attribute (std_attrs, attrs_loc);
          statement = cp_parser_iteration_statement (parser, if_p, false, 0);
          break;
 
@@ -11085,7 +11229,7 @@ cp_parser_statement (cp_parser* parser, tree in_statement_expr,
        case RID_CONTINUE:
        case RID_RETURN:
        case RID_GOTO:
-         std_attrs = process_stmt_hotness_attribute (std_attrs);
+         std_attrs = process_stmt_hotness_attribute (std_attrs, attrs_loc);
          statement = cp_parser_jump_statement (parser);
          break;
 
@@ -11095,12 +11239,12 @@ cp_parser_statement (cp_parser* parser, tree in_statement_expr,
        case RID_AT_FINALLY:
        case RID_AT_SYNCHRONIZED:
        case RID_AT_THROW:
-         std_attrs = process_stmt_hotness_attribute (std_attrs);
+         std_attrs = process_stmt_hotness_attribute (std_attrs, attrs_loc);
          statement = cp_parser_objc_statement (parser);
          break;
 
        case RID_TRY:
-         std_attrs = process_stmt_hotness_attribute (std_attrs);
+         std_attrs = process_stmt_hotness_attribute (std_attrs, attrs_loc);
          statement = cp_parser_try_block (parser);
          break;
 
@@ -11115,17 +11259,17 @@ cp_parser_statement (cp_parser* parser, tree in_statement_expr,
            }
          cp_parser_declaration_statement (parser);
          return;
-         
+
        case RID_TRANSACTION_ATOMIC:
        case RID_TRANSACTION_RELAXED:
        case RID_SYNCHRONIZED:
        case RID_ATOMIC_NOEXCEPT:
        case RID_ATOMIC_CANCEL:
-         std_attrs = process_stmt_hotness_attribute (std_attrs);
+         std_attrs = process_stmt_hotness_attribute (std_attrs, attrs_loc);
          statement = cp_parser_transaction (parser, token);
          break;
        case RID_TRANSACTION_CANCEL:
-         std_attrs = process_stmt_hotness_attribute (std_attrs);
+         std_attrs = process_stmt_hotness_attribute (std_attrs, attrs_loc);
          statement = cp_parser_transaction_cancel (parser);
          break;
 
@@ -11202,7 +11346,7 @@ cp_parser_statement (cp_parser* parser, tree in_statement_expr,
       if (loc_after_labels != NULL)
        *loc_after_labels = statement_location;
 
-      std_attrs = process_stmt_hotness_attribute (std_attrs);
+      std_attrs = process_stmt_hotness_attribute (std_attrs, attrs_loc);
 
       /* Look for an expression-statement instead.  */
       statement = cp_parser_expression_statement (parser, in_statement_expr);
@@ -11232,7 +11376,7 @@ cp_parser_statement (cp_parser* parser, tree in_statement_expr,
 
   /* Allow "[[fallthrough]];", but warn otherwise.  */
   if (std_attrs != NULL_TREE)
-    warning_at (attrs_location,
+    warning_at (attrs_loc,
                OPT_Wattributes,
                "attributes at the beginning of statement are ignored");
 }
@@ -11537,12 +11681,12 @@ cp_parser_statement_seq_opt (cp_parser* parser, tree in_statement_expr)
          || token->type == CPP_PRAGMA_EOL
          || (token->type == CPP_KEYWORD && token->keyword == RID_AT_END))
        break;
-      
+
       /* If we are in a compound statement and find 'else' then
         something went wrong.  */
       else if (token->type == CPP_KEYWORD && token->keyword == RID_ELSE)
        {
-         if (parser->in_statement & IN_IF_STMT) 
+         if (parser->in_statement & IN_IF_STMT)
            break;
          else
            {
@@ -11661,7 +11805,7 @@ cp_parser_selection_statement (cp_parser* parser, bool *if_p,
            cp_token *tok = cp_lexer_consume_token (parser->lexer);
            if (cxx_dialect < cxx17 && !in_system_header_at (tok->location))
              pedwarn (tok->location, 0, "%<if constexpr%> only available "
-                      "with -std=c++17 or -std=gnu++17");
+                      "with %<-std=c++17%> or %<-std=gnu++17%>");
          }
 
        /* Look for the `('.  */
@@ -11688,7 +11832,7 @@ cp_parser_selection_statement (cp_parser* parser, bool *if_p,
            if (cxx_dialect < cxx17)
              pedwarn (cp_lexer_peek_token (parser->lexer)->location, 0,
                       "init-statement in selection statements only available "
-                      "with -std=c++17 or -std=gnu++17");
+                      "with %<-std=c++17%> or %<-std=gnu++17%>");
            cp_parser_init_statement (parser, &decl);
          }
 
@@ -11945,6 +12089,10 @@ cp_parser_condition (cp_parser* parser)
   /* Restore the saved message.  */
   parser->type_definition_forbidden_message = saved_message;
 
+  /* Gather the attributes that were provided with the
+     decl-specifiers.  */
+  tree prefix_attributes = type_specifiers.attributes;
+
   cp_parser_maybe_commit_to_declaration (parser,
                                         type_specifiers.any_specifiers_p);
 
@@ -11964,7 +12112,8 @@ cp_parser_condition (cp_parser* parser)
                                         /*ctor_dtor_or_conv_p=*/NULL,
                                         /*parenthesized_p=*/NULL,
                                         /*member_p=*/false,
-                                        /*friend_p=*/false);
+                                        /*friend_p=*/false,
+                                        /*static_p=*/false);
       /* Parse the attributes.  */
       attributes = cp_parser_attributes_opt (parser);
       /* Parse the asm-specification.  */
@@ -11979,7 +12128,7 @@ cp_parser_condition (cp_parser* parser)
       if (cp_lexer_next_token_is_not (parser->lexer, CPP_EQ)
          && cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_BRACE))
        cp_parser_simulate_error (parser);
-       
+
       /* If we did see an `=' or '{', then we are looking at a declaration
         for sure.  */
       if (cp_parser_parse_definitely (parser))
@@ -11994,7 +12143,7 @@ cp_parser_condition (cp_parser* parser)
          /* Create the declaration.  */
          decl = start_decl (declarator, &type_specifiers,
                             /*initialized_p=*/true,
-                            attributes, /*prefix_attributes=*/NULL_TREE,
+                            attributes, prefix_attributes,
                             &pushed_scope);
 
          /* Parse the initializer.  */
@@ -12436,8 +12585,7 @@ cp_parser_perform_range_for_lookup (tree range, tree *begin, tree *end)
       else
        {
          /* Use global functions with ADL.  */
-         vec<tree, va_gc> *vec;
-         vec = make_tree_vector ();
+         releasing_vec vec;
 
          vec_safe_push (vec, range);
 
@@ -12449,8 +12597,6 @@ cp_parser_perform_range_for_lookup (tree range, tree *begin, tree *end)
                                              tf_warning_or_error);
          *end = finish_call_expr (member_end, &vec, false, true,
                                   tf_warning_or_error);
-
-         release_tree_vector (vec);
        }
 
       /* Last common checks.  */
@@ -12498,19 +12644,17 @@ static tree
 cp_parser_range_for_member_function (tree range, tree identifier)
 {
   tree member, res;
-  vec<tree, va_gc> *vec;
 
   member = finish_class_member_access_expr (range, identifier,
                                            false, tf_warning_or_error);
   if (member == error_mark_node)
     return error_mark_node;
 
-  vec = make_tree_vector ();
+  releasing_vec vec;
   res = finish_call_expr (member, &vec,
                          /*disallow_virtual=*/false,
                          /*koenig_p=*/false,
                          tf_warning_or_error);
-  release_tree_vector (vec);
   return res;
 }
 
@@ -12674,7 +12818,7 @@ cp_parser_init_statement (cp_parser *parser, tree *decl)
            {
              pedwarn (cp_lexer_peek_token (parser->lexer)->location, 0,
                       "range-based %<for%> loops with initializer only "
-                      "available with -std=c++2a or -std=gnu++2a");
+                      "available with %<-std=c++2a%> or %<-std=gnu++2a%>");
              *decl = error_mark_node;
            }
        }
@@ -12698,7 +12842,7 @@ cp_parser_init_statement (cp_parser *parser, tree *decl)
          if (cxx_dialect < cxx11)
            pedwarn (cp_lexer_peek_token (parser->lexer)->location, 0,
                     "range-based %<for%> loops only available with "
-                    "-std=c++11 or -std=gnu++11");
+                    "%<-std=c++11%> or %<-std=gnu++11%>");
        }
       else
        /* The ';' is not consumed yet because we told
@@ -12749,7 +12893,7 @@ cp_parser_jump_statement (cp_parser* parser)
   switch (keyword)
     {
     case RID_BREAK:
-      in_statement = parser->in_statement & ~IN_IF_STMT;      
+      in_statement = parser->in_statement & ~IN_IF_STMT;
       switch (in_statement)
        {
        case 0:
@@ -12810,7 +12954,7 @@ cp_parser_jump_statement (cp_parser* parser)
             expression.  */
          expr = NULL_TREE;
        /* Build the return-statement.  */
-       if (current_function_auto_return_pattern && in_discarded_stmt)
+       if (FNDECL_USED_AUTO (current_function_decl) && in_discarded_stmt)
          /* Don't deduce from a discarded return statement.  */;
        else
          statement = finish_return_stmt (expr);
@@ -13640,7 +13784,7 @@ cp_parser_decomposition_declaration (cp_parser *parser,
 
   if (cxx_dialect < cxx17)
     pedwarn (loc, 0, "structured bindings only available with "
-                    "-std=c++17 or -std=gnu++17");
+                    "%<-std=c++17%> or %<-std=gnu++17%>");
 
   tree pushed_scope;
   cp_declarator *declarator = make_declarator (cdk_decomp);
@@ -13716,9 +13860,12 @@ cp_parser_decomposition_declaration (cp_parser *parser,
 
       if (decl != error_mark_node)
        {
+         int flags = (decl_spec_seq_has_spec_p (decl_specifiers, ds_constinit)
+                      ? LOOKUP_CONSTINIT : 0);
          cp_maybe_mangle_decomp (decl, prev, v.length ());
          cp_finish_decl (decl, initializer, non_constant_p, NULL_TREE,
-                         is_direct_init ? LOOKUP_NORMAL : LOOKUP_IMPLICIT);
+                         (is_direct_init ? LOOKUP_NORMAL : LOOKUP_IMPLICIT)
+                         | flags);
          cp_finish_decomp (decl, prev, v.length ());
        }
     }
@@ -13870,7 +14017,8 @@ cp_parser_decl_specifier_seq (cp_parser* parser,
        {
          /* decl-specifier:
               friend
-               constexpr */
+              constexpr
+              constinit */
        case RID_FRIEND:
          if (!at_class_scope_p ())
            {
@@ -13892,9 +14040,23 @@ cp_parser_decl_specifier_seq (cp_parser* parser,
           cp_lexer_consume_token (parser->lexer);
           break;
 
+       case RID_CONSTINIT:
+         ds = ds_constinit;
+         cp_lexer_consume_token (parser->lexer);
+         break;
+
         case RID_CONCEPT:
           ds = ds_concept;
           cp_lexer_consume_token (parser->lexer);
+         /* In C++20 a concept definition is just 'concept name = expr;'
+            Support that syntax by pretending we've seen 'bool'.  */
+         if (cp_lexer_next_token_is (parser->lexer, CPP_NAME)
+             && cp_lexer_nth_token_is (parser->lexer, 2, CPP_EQ))
+           {
+             cp_parser_set_decl_spec_type (decl_specs, boolean_type_node,
+                                           token, /*type_definition*/false);
+             decl_specs->any_type_specifiers_p = true;
+           }
           break;
 
          /* function-specifier:
@@ -13933,7 +14095,7 @@ cp_parser_decl_specifier_seq (cp_parser* parser,
             GNU Extension:
               thread  */
        case RID_AUTO:
-          if (cxx_dialect == cxx98) 
+          if (cxx_dialect == cxx98)
             {
              /* Consume the token.  */
              cp_lexer_consume_token (parser->lexer);
@@ -13979,7 +14141,7 @@ cp_parser_decl_specifier_seq (cp_parser* parser,
       if (found_decl_spec
          && (flags & CP_PARSER_FLAGS_ONLY_TYPE_OR_CONSTEXPR)
          && token->keyword != RID_CONSTEXPR)
-       error ("decl-specifier invalid in condition");
+       error ("%<decl-specifier%> invalid in condition");
 
       if (found_decl_spec
          && (flags & CP_PARSER_FLAGS_ONLY_MUTABLE_OR_CONSTEXPR)
@@ -13997,7 +14159,8 @@ cp_parser_decl_specifier_seq (cp_parser* parser,
        = (!found_decl_spec
           && constructor_possible_p
           && (cp_parser_constructor_declarator_p
-              (parser, decl_spec_seq_has_spec_p (decl_specs, ds_friend))));
+              (parser, flags, decl_spec_seq_has_spec_p (decl_specs,
+                                                        ds_friend))));
 
       /* If we don't have a DECL_SPEC yet, then we must be looking at
         a type-specifier.  */
@@ -14177,8 +14340,8 @@ cp_parser_function_specifier_opt (cp_parser* parser,
 
            if (cxx_dialect < cxx2a)
              pedwarn (token->location, 0,
-                      "%<explicit(bool)%> only available with -std=c++2a "
-                      "or -std=gnu++2a");
+                      "%<explicit(bool)%> only available with %<-std=c++2a%> "
+                      "or %<-std=gnu++2a%>");
 
            /* Parse the constant-expression.  */
            expr = cp_parser_constant_expression (parser);
@@ -14303,12 +14466,12 @@ cp_parser_linkage_specification (cp_parser* parser)
 /* Parse a static_assert-declaration.
 
    static_assert-declaration:
-     static_assert ( constant-expression , string-literal ) ; 
+     static_assert ( constant-expression , string-literal ) ;
      static_assert ( constant-expression ) ; (C++17)
 
    If MEMBER_P, this static_assert is a class member.  */
 
-static void 
+static void
 cp_parser_static_assert(cp_parser *parser, bool member_p)
 {
   cp_expr condition;
@@ -14321,7 +14484,7 @@ cp_parser_static_assert(cp_parser *parser, bool member_p)
   token_loc = cp_lexer_peek_token (parser->lexer)->location;
 
   /* Look for the `static_assert' keyword.  */
-  if (!cp_parser_require_keyword (parser, RID_STATIC_ASSERT, 
+  if (!cp_parser_require_keyword (parser, RID_STATIC_ASSERT,
                                   RT_STATIC_ASSERT))
     return;
 
@@ -14336,7 +14499,7 @@ cp_parser_static_assert(cp_parser *parser, bool member_p)
 
   /* Parse the constant-expression.  Allow a non-constant expression
      here in order to give better diagnostics in finish_static_assert.  */
-  condition = 
+  condition =
     cp_parser_constant_expression (parser,
                                    /*allow_non_constant_p=*/true,
                                    /*non_constant_p=*/&dummy);
@@ -14345,8 +14508,8 @@ cp_parser_static_assert(cp_parser *parser, bool member_p)
     {
       if (cxx_dialect < cxx17)
        pedwarn (input_location, OPT_Wpedantic,
-                "static_assert without a message "
-                "only available with -std=c++17 or -std=gnu++17");
+                "%<static_assert%> without a message "
+                "only available with %<-std=c++17%> or %<-std=gnu++17%>");
       /* Eat the ')'  */
       cp_lexer_consume_token (parser->lexer);
       message = build_string (1, "");
@@ -14359,14 +14522,14 @@ cp_parser_static_assert(cp_parser *parser, bool member_p)
       cp_parser_require (parser, CPP_COMMA, RT_COMMA);
 
       /* Parse the string-literal message.  */
-      message = cp_parser_string_literal (parser, 
+      message = cp_parser_string_literal (parser,
                                          /*translate=*/false,
                                          /*wide_ok=*/true);
 
       /* A `)' completes the static assertion.  */
       if (!parens.require_close (parser))
-       cp_parser_skip_to_closing_parenthesis (parser, 
-                                               /*recovering=*/true, 
+       cp_parser_skip_to_closing_parenthesis (parser,
+                                               /*recovering=*/true,
                                                /*or_comma=*/false,
                                               /*consume_paren=*/true);
     }
@@ -14381,7 +14544,7 @@ cp_parser_static_assert(cp_parser *parser, bool member_p)
   if (assert_loc == UNKNOWN_LOCATION)
     assert_loc = token_loc;
 
-  /* Complete the static assertion, which may mean either processing 
+  /* Complete the static assertion, which may mean either processing
      the static assert now or saving it for template instantiation.  */
   finish_static_assert (condition, message, assert_loc, member_p);
 }
@@ -14455,7 +14618,7 @@ cp_parser_decltype_expr (cp_parser *parser,
             id_expression_or_member_access_p = true;
         }
 
-      if (expr 
+      if (expr
           && expr != error_mark_node
           && cp_lexer_peek_token (parser->lexer)->type == CPP_CLOSE_PAREN)
         /* We have an id-expression.  */
@@ -14475,7 +14638,7 @@ cp_parser_decltype_expr (cp_parser *parser,
                                            /*cast_p=*/false, /*decltype*/true,
                                            /*member_access_only_p=*/true, NULL);
 
-      if (expr 
+      if (expr
           && expr != error_mark_node
           && cp_lexer_peek_token (parser->lexer)->type == CPP_CLOSE_PAREN)
         /* We have an id-expression.  */
@@ -14534,7 +14697,7 @@ cp_parser_decltype (cp_parser *parser)
   push_deferring_access_checks (dk_deferred);
 
   tree expr = NULL_TREE;
-  
+
   if (cxx_dialect >= cxx14
       && cp_lexer_next_token_is_keyword (parser->lexer, RID_AUTO))
     /* decltype (auto) */
@@ -14619,7 +14782,7 @@ cp_parser_decltype (cp_parser *parser)
   cp_lexer_purge_tokens_after (parser->lexer, start_token);
 
   pop_to_parent_deferring_access_checks ();
-  
+
   return expr;
 }
 
@@ -14703,8 +14866,9 @@ cp_parser_conversion_type_id (cp_parser* parser)
   parser->type_definition_forbidden_message
     = G_("types may not be defined in a conversion-type-id");
 
-  /* Parse the type-specifiers.  */
-  cp_parser_type_specifier_seq (parser, CP_PARSER_FLAGS_NONE,
+  /* Parse the type-specifiers.  DR 2413 clarifies that `typename' is
+     optional in conversion-type-id.  */
+  cp_parser_type_specifier_seq (parser, CP_PARSER_FLAGS_TYPENAME_OPTIONAL,
                                /*is_declaration=*/false,
                                /*is_trailing_return=*/false,
                                &type_specifiers);
@@ -14991,7 +15155,7 @@ cp_parser_mem_initializer_id (cp_parser* parser)
   /* `typename' is not allowed in this context ([temp.res]).  */
   if (cp_lexer_next_token_is_keyword (parser->lexer, RID_TYPENAME))
     {
-      error_at (token->location, 
+      error_at (token->location,
                "keyword %<typename%> not allowed in this context (a qualified "
                "member initializer is implicitly a type)");
       cp_lexer_consume_token (parser->lexer);
@@ -15410,10 +15574,8 @@ cp_parser_operator (cp_parser* parser, location_t start_loc)
             ^~~~~~~~~~~~~~~~~~~~~
           with caret == start at the start token, finish at the end of the
           suffix identifier.  */
-       location_t finish_loc
-         = get_finish (cp_lexer_previous_token (parser->lexer)->location);
        location_t combined_loc
-         = make_location (start_loc, start_loc, finish_loc);
+         = make_location (start_loc, start_loc, parser->lexer);
        return cp_expr (id, combined_loc);
       }
 
@@ -15521,7 +15683,7 @@ cp_parser_template_parameter_list (cp_parser* parser)
 
       /* Parse the template-parameter.  */
       parm_loc = cp_lexer_peek_token (parser->lexer)->location;
-      parameter = cp_parser_template_parameter (parser, 
+      parameter = cp_parser_template_parameter (parser,
                                                 &is_non_type,
                                                 &is_parameter_pack);
       /* Add it to the list.  */
@@ -16335,10 +16497,8 @@ cp_parser_template_id (cp_parser *parser,
      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      with caret == start at the start of the template-name,
      ranging until the closing '>'.  */
-  location_t finish_loc
-    = get_finish (cp_lexer_previous_token (parser->lexer)->location);
   location_t combined_loc
-    = make_location (token->location, token->location, finish_loc);
+    = make_location (token->location, token->location, parser->lexer);
 
   /* Check for concepts autos where they don't belong.  We could
      identify types in some cases of idnetifier TEMPL, looking ahead
@@ -16382,10 +16542,7 @@ cp_parser_template_id (cp_parser *parser,
     {
       /* If it's not a class-template or a template-template, it should be
         a function-template.  */
-      gcc_assert ((DECL_FUNCTION_TEMPLATE_P (templ)
-                  || TREE_CODE (templ) == OVERLOAD
-                  || TREE_CODE (templ) == FUNCTION_DECL
-                  || BASELINK_P (templ)));
+      gcc_assert (OVL_P (templ) || BASELINK_P (templ));
 
       template_id = lookup_template_function (templ, arguments);
       if (TREE_CODE (template_id) == TEMPLATE_ID_EXPR)
@@ -16801,7 +16958,7 @@ cp_parser_template_argument (cp_parser* parser)
      Here 'X()' is a valid type-id of a function type, but the user just
      wanted to write the expression "X() >> 5". Thus, we remember that we
      found a valid type-id, but we still try to parse the argument as an
-     expression to see what happens. 
+     expression to see what happens.
 
      In C++0x, the '>>' will be considered two separate '>'
      tokens.  */
@@ -16994,6 +17151,14 @@ cp_parser_template_argument (cp_parser* parser)
     argument = cp_parser_constant_expression (parser);
   else
     {
+      /* In C++20, we can encounter a braced-init-list.  */
+      if (cxx_dialect >= cxx2a
+         && cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
+       {
+         bool expr_non_constant_p;
+         return cp_parser_braced_list (parser, &expr_non_constant_p);
+       }
+
       /* With C++17 generalized non-type template arguments we need to handle
         lvalue constant expressions, too.  */
       argument = cp_parser_assignment_expression (parser);
@@ -17097,7 +17262,8 @@ cp_parser_explicit_instantiation (cp_parser* parser)
                                /*ctor_dtor_or_conv_p=*/NULL,
                                /*parenthesized_p=*/NULL,
                                /*member_p=*/false,
-                               /*friend_p=*/false);
+                               /*friend_p=*/false,
+                               /*static_p=*/false);
       if (declares_class_or_enum & 2)
        cp_parser_check_for_definition_in_return_type (declarator,
                                                       decl_specifiers.type,
@@ -17418,7 +17584,7 @@ cp_parser_type_specifier (cp_parser* parser,
 
    simple-type-specifier:
      auto
-     decltype ( expression )   
+     decltype ( expression )
      char16_t
      char32_t
      __underlying_type ( type-id )
@@ -17463,6 +17629,9 @@ cp_parser_simple_type_specifier (cp_parser* parser,
        decl_specs->explicit_char_p = true;
       type = char_type_node;
       break;
+    case RID_CHAR8:
+      type = char8_type_node;
+      break;
     case RID_CHAR16:
       type = char16_type_node;
       break;
@@ -17495,6 +17664,12 @@ cp_parser_simple_type_specifier (cp_parser* parser,
        {
          decl_specs->explicit_intN_p = true;
          decl_specs->int_n_idx = idx;
+         /* Check if the alternate "__intN__" form has been used instead of
+            "__intN".  */
+         if (strncmp (IDENTIFIER_POINTER (token->u.value)
+                       + (IDENTIFIER_LENGTH (token->u.value) - 2),
+                       "__", 2) == 0)
+           decl_specs->int_n_alt = true;
        }
       type = int_n_trees [idx].signed_type;
       break;
@@ -17576,17 +17751,17 @@ cp_parser_simple_type_specifier (cp_parser* parser,
                error_at (token->location,
                         "use of %<auto%> in lambda parameter declaration "
                         "only available with "
-                        "-std=c++14 or -std=gnu++14");
+                        "%<-std=c++14%> or %<-std=gnu++14%>");
            }
          else if (cxx_dialect < cxx14)
            error_at (token->location,
                     "use of %<auto%> in parameter declaration "
                     "only available with "
-                    "-std=c++14 or -std=gnu++14");
+                    "%<-std=c++14%> or %<-std=gnu++14%>");
          else if (!flag_concepts)
            pedwarn (token->location, 0,
                     "use of %<auto%> in parameter declaration "
-                    "only available with -fconcepts");
+                    "only available with %<-fconcepts%>");
        }
       else
        type = make_auto ();
@@ -17699,7 +17874,7 @@ cp_parser_simple_type_specifier (cp_parser* parser,
 
       /* Don't gobble tokens or issue error messages if this is an
         optional type-specifier.  */
-      if ((flags & CP_PARSER_FLAGS_OPTIONAL) || cxx_dialect >= cxx17)
+      if (flags & CP_PARSER_FLAGS_OPTIONAL)
        cp_parser_parse_tentatively (parser);
 
       token = cp_lexer_peek_token (parser->lexer);
@@ -17739,37 +17914,26 @@ cp_parser_simple_type_specifier (cp_parser* parser,
              else
                {
                  cp_parser_error (parser, "expected template-id for type");
-                 type = NULL_TREE;
+                 type = error_mark_node;
                }
            }
        }
-      /* Otherwise, look for a type-name.  */
-      else
-       type = cp_parser_type_name (parser, (qualified_p && typename_p));
 
-      /* Keep track of all name-lookups performed in class scopes.  */
-      if (type
-         && !global_p
-         && !qualified_p
-         && TREE_CODE (type) == TYPE_DECL
-         && identifier_p (DECL_NAME (type)))
-       maybe_note_name_used_in_class (DECL_NAME (type), type);
-      /* If it didn't work out, we don't have a TYPE.  */
-      if (((flags & CP_PARSER_FLAGS_OPTIONAL) || cxx_dialect >= cxx17)
-         && !cp_parser_parse_definitely (parser))
-       type = NULL_TREE;
-      if (!type && cxx_dialect >= cxx17)
+      /* Otherwise, look for a type-name.  */
+      if (!type)
        {
-         if (flags & CP_PARSER_FLAGS_OPTIONAL)
+         if (cxx_dialect >= cxx17)
            cp_parser_parse_tentatively (parser);
 
-         cp_parser_global_scope_opt (parser,
-                                     /*current_scope_valid_p=*/false);
-         cp_parser_nested_name_specifier_opt (parser,
-                                              /*typename_keyword_p=*/false,
-                                              /*check_dependency_p=*/true,
-                                              /*type_p=*/false,
-                                              /*is_declaration=*/false);
+         type = cp_parser_type_name (parser, (qualified_p && typename_p));
+
+         if (cxx_dialect >= cxx17 && !cp_parser_parse_definitely (parser))
+           type = NULL_TREE;
+       }
+
+      if (!type && cxx_dialect >= cxx17)
+       {
+         /* Try class template argument deduction.  */
          tree name = cp_parser_identifier (parser);
          if (name && TREE_CODE (name) == IDENTIFIER_NODE
              && parser->scope != error_mark_node)
@@ -17795,11 +17959,21 @@ cp_parser_simple_type_specifier (cp_parser* parser,
            }
          else
            type = error_mark_node;
-
-         if ((flags & CP_PARSER_FLAGS_OPTIONAL)
-             && !cp_parser_parse_definitely (parser))
-           type = NULL_TREE;
        }
+
+      /* If it didn't work out, we don't have a TYPE.  */
+      if ((flags & CP_PARSER_FLAGS_OPTIONAL)
+         && !cp_parser_parse_definitely (parser))
+       type = NULL_TREE;
+
+      /* Keep track of all name-lookups performed in class scopes.  */
+      if (type
+         && !global_p
+         && !qualified_p
+         && TREE_CODE (type) == TYPE_DECL
+         && identifier_p (DECL_NAME (type)))
+       maybe_note_name_used_in_class (DECL_NAME (type), type);
+
       if (type && decl_specs)
        cp_parser_set_decl_spec_type (decl_specs, type,
                                      token,
@@ -17903,12 +18077,12 @@ cp_parser_type_name (cp_parser* parser, bool typename_keyword_p)
                                         /*is_declaration=*/false);
       /* Note that this must be an instantiation of an alias template
         because [temp.names]/6 says:
-        
+
             A template-id that names an alias template specialization
             is a type-name.
 
         Whereas [temp.names]/7 says:
-        
+
             A simple-template-id that names a class template
             specialization is a class-name.
 
@@ -18059,7 +18233,7 @@ cp_parser_nonclass_name (cp_parser* parser)
   type_decl = cp_parser_lookup_name_simple (parser, identifier, token->location);
 
   type_decl = strip_using_decl (type_decl);
-  
+
   /* If we found an overload set, then it may refer to a concept-name. */
   if (tree decl = cp_parser_maybe_concept_name (parser, type_decl))
     type_decl = decl;
@@ -18097,7 +18271,7 @@ cp_parser_nonclass_name (cp_parser* parser)
   else if (type_decl != error_mark_node
           && !parser->scope)
     maybe_note_name_used_in_class (identifier, type_decl);
-  
+
   return type_decl;
 }
 
@@ -18262,7 +18436,7 @@ cp_parser_elaborated_type_specifier (cp_parser* parser,
       /* If the `typename' keyword is in effect and DECL is not a type
         decl, then type is non existent.   */
       else if (tag_type == typename_type && TREE_CODE (decl) != TYPE_DECL)
-        ; 
+        ;
       else if (TREE_CODE (decl) == TYPE_DECL)
        {
          type = check_elaborated_type_specifier (tag_type, decl,
@@ -18277,7 +18451,7 @@ cp_parser_elaborated_type_specifier (cp_parser* parser,
            check_unqualified_spec_or_inst (type, token->location);
        }
       else if (decl == error_mark_node)
-       type = error_mark_node; 
+       type = error_mark_node;
     }
 
   if (!type)
@@ -18525,7 +18699,7 @@ cp_parser_elaborated_type_specifier (cp_parser* parser,
      enum-key identifier enum-base [opt] ;
 
    GNU Extensions:
-     enum-key attributes[opt] identifier [opt] enum-base [opt] 
+     enum-key attributes[opt] identifier [opt] enum-base [opt]
        { enumerator-list [opt] }attributes[opt]
      enum-key attributes[opt] identifier [opt] enum-base [opt]
        { enumerator-list, }attributes[opt] [C++0x]
@@ -19104,7 +19278,7 @@ cp_parser_namespace_definition (cp_parser* parser)
   for (;;)
     {
       identifier = NULL_TREE;
-      
+
       bool nested_inline_p = cp_lexer_next_token_is_keyword (parser->lexer,
                                                             RID_INLINE);
       if (nested_inline_p && nested_definition_count != 0)
@@ -19112,7 +19286,7 @@ cp_parser_namespace_definition (cp_parser* parser)
          if (cxx_dialect < cxx2a)
            pedwarn (cp_lexer_peek_token (parser->lexer)->location,
                     OPT_Wpedantic, "nested inline namespace definitions only "
-                    "available with -std=c++2a or -std=gnu++2a");
+                    "available with %<-std=c++2a%> or %<-std=gnu++2a%>");
          cp_lexer_consume_token (parser->lexer);
        }
 
@@ -19138,11 +19312,11 @@ cp_parser_namespace_definition (cp_parser* parser)
          is_inline |= nested_inline_p;
          break;
        }
-  
+
       if (!nested_definition_count && cxx_dialect < cxx17)
         pedwarn (input_location, OPT_Wpedantic,
-                 "nested namespace definitions only available with "
-                 "-std=c++17 or -std=gnu++17");
+                "nested namespace definitions only available with "
+                "%<-std=c++17%> or %<-std=gnu++17%>");
 
       /* Nested namespace names can create new namespaces (unlike
         other qualified-ids).  */
@@ -19157,7 +19331,7 @@ cp_parser_namespace_definition (cp_parser* parser)
 
   if (nested_definition_count && !identifier)
     cp_parser_error (parser, "namespace name required");
-  
+
   if (nested_definition_count && attribs)
     error_at (token->location,
              "a nested namespace definition cannot have attributes");
@@ -19223,7 +19397,7 @@ cp_parser_namespace_alias_definition (cp_parser* parser)
     return;
   /* Look for the `=' token.  */
   if (!cp_parser_uncommitted_to_tentative_parse_p (parser)
-      && cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE)) 
+      && cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
     {
       error_at (token->location, "%<namespace%> definition is not allowed here");
       /* Skip the definition.  */
@@ -19236,6 +19410,7 @@ cp_parser_namespace_alias_definition (cp_parser* parser)
   /* Look for the qualified-namespace-specifier.  */
   namespace_specifier
     = cp_parser_qualified_namespace_specifier (parser);
+  cp_warn_deprecated_use_scopes (namespace_specifier);
   /* Look for the `;' token.  */
   cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
 
@@ -19273,15 +19448,15 @@ cp_parser_qualified_namespace_specifier (cp_parser* parser)
 
    using-declaration:
      using typename [opt] :: [opt] nested-name-specifier unqualified-id ;
-     using :: unqualified-id ;  
+     using :: unqualified-id ;
 
    access-declaration:
-     qualified-id ;  
+     qualified-id ;
 
    */
 
 static bool
-cp_parser_using_declaration (cp_parser* parser, 
+cp_parser_using_declaration (cp_parser* parser,
                             bool access_declaration_p)
 {
   cp_token *token;
@@ -19302,7 +19477,7 @@ cp_parser_using_declaration (cp_parser* parser,
     {
       /* Look for the `using' keyword.  */
       cp_parser_require_keyword (parser, RID_USING, RT_USING);
-      
+
  again:
       /* Peek at the next token.  */
       token = cp_lexer_peek_token (parser->lexer);
@@ -19346,9 +19521,12 @@ cp_parser_using_declaration (cp_parser* parser,
                                                  /*is_declaration=*/true);
   if (!qscope)
     qscope = global_namespace;
-  else if (UNSCOPED_ENUM_P (qscope))
+  else if (UNSCOPED_ENUM_P (qscope)
+          && !TYPE_FUNCTION_SCOPE_P (qscope))
     qscope = CP_TYPE_CONTEXT (qscope);
 
+  cp_warn_deprecated_use_scopes (qscope);
+
   if (access_declaration_p && cp_parser_error_occurred (parser))
     /* Something has already gone wrong; there's no need to parse
        further.  Since an error has occurred, the return value of
@@ -19377,7 +19555,7 @@ cp_parser_using_declaration (cp_parser* parser,
          && !in_system_header_at (ell->location))
        pedwarn (ell->location, 0,
                 "pack expansion in using-declaration only available "
-                "with -std=c++17 or -std=gnu++17");
+                "with %<-std=c++17%> or %<-std=gnu++17%>");
       qscope = make_pack_expansion (qscope);
     }
 
@@ -19412,24 +19590,7 @@ cp_parser_using_declaration (cp_parser* parser,
            finish_member_declaration (decl);
        }
       else
-       {
-         decl = cp_parser_lookup_name_simple (parser,
-                                              identifier,
-                                              token->location);
-         if (decl == error_mark_node)
-           cp_parser_name_lookup_error (parser, identifier,
-                                        decl, NLE_NULL,
-                                        token->location);
-         else if (check_for_bare_parameter_packs (decl))
-           {
-             cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
-             return false;
-           }
-         else if (!at_namespace_scope_p ())
-           finish_local_using_decl (decl, qscope, identifier);
-         else
-           finish_namespace_using_decl (decl, qscope, identifier);
-       }
+       finish_nonmember_using_decl (qscope, identifier);
     }
 
   if (!access_declaration_p
@@ -19439,7 +19600,7 @@ cp_parser_using_declaration (cp_parser* parser,
       if (cxx_dialect < cxx17)
        pedwarn (comma->location, 0,
                 "comma-separated list in using-declaration only available "
-                "with -std=c++17 or -std=gnu++17");
+                "with %<-std=c++17%> or %<-std=gnu++17%>");
       goto again;
     }
 
@@ -19573,7 +19734,7 @@ cp_parser_alias_declaration (cp_parser* parser)
   if (decl == error_mark_node)
     return decl;
 
-  // Attach constraints to the alias declaration.
+  /* Attach constraints to the alias declaration.  */
   if (flag_concepts && current_template_parms)
     {
       tree reqs = TEMPLATE_PARMS_CONSTRAINTS (current_template_parms);
@@ -19626,14 +19787,12 @@ cp_parser_using_directive (cp_parser* parser)
                                       /*is_declaration=*/true);
   /* Get the namespace being used.  */
   namespace_decl = cp_parser_namespace_name (parser);
+  cp_warn_deprecated_use_scopes (namespace_decl);
   /* And any specified attributes.  */
   attribs = cp_parser_attributes_opt (parser);
 
   /* Update the symbol table.  */
-  if (namespace_bindings_p ())
-    finish_namespace_using_directive (namespace_decl, attribs);
-  else
-    finish_local_using_directive (namespace_decl, attribs);
+  finish_using_directive (namespace_decl, attribs);
 
   /* Look for the final `;'.  */
   cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
@@ -19680,65 +19839,102 @@ cp_parser_asm_definition (cp_parser* parser)
   tree clobbers = NULL_TREE;
   tree labels = NULL_TREE;
   tree asm_stmt;
-  bool volatile_p = false;
   bool extended_p = false;
   bool invalid_inputs_p = false;
   bool invalid_outputs_p = false;
-  bool inline_p = false;
-  bool goto_p = false;
   required_token missing = RT_NONE;
+  location_t asm_loc = cp_lexer_peek_token (parser->lexer)->location;
 
   /* Look for the `asm' keyword.  */
   cp_parser_require_keyword (parser, RID_ASM, RT_ASM);
 
+  /* In C++2a, unevaluated inline assembly is permitted in constexpr
+     functions.  */
   if (parser->in_function_body
-      && DECL_DECLARED_CONSTEXPR_P (current_function_decl))
-    {
-      error ("%<asm%> in %<constexpr%> function");
-      cp_function_chain->invalid_constexpr = true;
-    }
+      && DECL_DECLARED_CONSTEXPR_P (current_function_decl)
+      && (cxx_dialect < cxx2a))
+    pedwarn (asm_loc, 0, "%<asm%> in %<constexpr%> function only available "
+            "with %<-std=c++2a%> or %<-std=gnu++2a%>");
+
+  /* Handle the asm-qualifier-list.  */
+  location_t volatile_loc = UNKNOWN_LOCATION;
+  location_t inline_loc = UNKNOWN_LOCATION;
+  location_t goto_loc = UNKNOWN_LOCATION;
+  location_t first_loc = UNKNOWN_LOCATION;
 
-  /* See if the next token is `volatile'.  */
   if (cp_parser_allow_gnu_extensions_p (parser))
-    for (bool done = false; !done ; )
-      switch (cp_lexer_peek_token (parser->lexer)->keyword)
-       {
-       case RID_VOLATILE:
-         if (!volatile_p)
-           {
-             /* Remember that we saw the `volatile' keyword.  */
-             volatile_p = true;
-             /* Consume the token.  */
-             cp_lexer_consume_token (parser->lexer);
-           }
-         else
-           done = true;
-         break;
-       case RID_INLINE:
-         if (!inline_p && parser->in_function_body)
-           {
-             /* Remember that we saw the `inline' keyword.  */
-             inline_p = true;
-             /* Consume the token.  */
-             cp_lexer_consume_token (parser->lexer);
-           }
-         else
-           done = true;
-         break;
-       case RID_GOTO:
-         if (!goto_p && parser->in_function_body)
-           {
-             /* Remember that we saw the `goto' keyword.  */
-             goto_p = true;
-             /* Consume the token.  */
-             cp_lexer_consume_token (parser->lexer);
-           }
-         else
-           done = true;
-         break;
-       default:
-         done = true;
-       }
+    for (;;)
+      {
+       cp_token *token = cp_lexer_peek_token (parser->lexer);
+       location_t loc = token->location;
+       switch (cp_lexer_peek_token (parser->lexer)->keyword)
+         {
+         case RID_VOLATILE:
+           if (volatile_loc)
+             {
+               error_at (loc, "duplicate %<asm%> qualifier %qT",
+                         token->u.value);
+               inform (volatile_loc, "first seen here");
+             }
+           else
+             {
+               if (!parser->in_function_body)
+                 warning_at (loc, 0, "%<asm%> qualifier %qT ignored "
+                             "outside of function body", token->u.value);
+               volatile_loc = loc;
+             }
+           cp_lexer_consume_token (parser->lexer);
+           continue;
+
+         case RID_INLINE:
+           if (inline_loc)
+             {
+               error_at (loc, "duplicate %<asm%> qualifier %qT",
+                         token->u.value);
+               inform (inline_loc, "first seen here");
+             }
+           else
+             inline_loc = loc;
+           if (!first_loc)
+             first_loc = loc;
+           cp_lexer_consume_token (parser->lexer);
+           continue;
+
+         case RID_GOTO:
+           if (goto_loc)
+             {
+               error_at (loc, "duplicate %<asm%> qualifier %qT",
+                         token->u.value);
+               inform (goto_loc, "first seen here");
+             }
+           else
+             goto_loc = loc;
+           if (!first_loc)
+             first_loc = loc;
+           cp_lexer_consume_token (parser->lexer);
+           continue;
+
+         case RID_CONST:
+         case RID_RESTRICT:
+           error_at (loc, "%qT is not an %<asm%> qualifier", token->u.value);
+           cp_lexer_consume_token (parser->lexer);
+           continue;
+
+         default:
+           break;
+         }
+       break;
+      }
+
+  bool volatile_p = (volatile_loc != UNKNOWN_LOCATION);
+  bool inline_p = (inline_loc != UNKNOWN_LOCATION);
+  bool goto_p = (goto_loc != UNKNOWN_LOCATION);
+
+  if (!parser->in_function_body && (inline_p || goto_p))
+    {
+      error_at (first_loc, "%<asm%> qualifier outside of function body");
+      inline_p = goto_p = false;
+    }
 
   /* Look for the opening `('.  */
   if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
@@ -19831,8 +20027,7 @@ cp_parser_asm_definition (cp_parser* parser)
                                             CPP_CLOSE_PAREN))
            clobbers = cp_parser_asm_clobber_list (parser);
        }
-      else if (goto_p
-              && cp_lexer_next_token_is (parser->lexer, CPP_SCOPE))
+      else if (goto_p && cp_lexer_next_token_is (parser->lexer, CPP_SCOPE))
        /* The labels are coming next.  */
        labels_p = true;
 
@@ -19865,7 +20060,7 @@ cp_parser_asm_definition (cp_parser* parser)
       /* Create the ASM_EXPR.  */
       if (parser->in_function_body)
        {
-         asm_stmt = finish_asm_stmt (volatile_p, string, outputs,
+         asm_stmt = finish_asm_stmt (asm_loc, volatile_p, string, outputs,
                                      inputs, clobbers, labels, inline_p);
          /* If the extended syntax was not used, mark the ASM_EXPR.  */
          if (!extended_p)
@@ -20027,7 +20222,7 @@ cp_parser_init_declarator (cp_parser* parser,
     = cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED,
                            flags, &ctor_dtor_or_conv_p,
                            /*parenthesized_p=*/NULL,
-                           member_p, friend_p);
+                           member_p, friend_p, /*static_p=*/false);
   /* Gather up the deferred checks.  */
   stop_deferring_access_checks ();
 
@@ -20119,7 +20314,7 @@ cp_parser_init_declarator (cp_parser* parser,
             on a function-definition.  */
          if (asm_specification)
            error_at (asm_spec_start_token->location,
-                     "an asm-specification is not allowed "
+                     "an %<asm%> specification is not allowed "
                      "on a function-definition");
          if (attributes)
            error_at (attributes_start_token->location,
@@ -20367,6 +20562,8 @@ cp_parser_init_declarator (cp_parser* parser,
      declarations.  */
   if (!member_p && decl && decl != error_mark_node && !range_for_decl_p)
     {
+      int cf = (decl_spec_seq_has_spec_p (decl_specifiers, ds_constinit)
+               ? LOOKUP_CONSTINIT : 0);
       cp_finish_decl (decl,
                      initializer, !is_non_constant_init,
                      asm_specification,
@@ -20375,14 +20572,14 @@ cp_parser_init_declarator (cp_parser* parser,
                         `explicit' constructor is OK.  Otherwise, an
                         `explicit' constructor cannot be used.  */
                      ((is_direct_init || !is_initialized)
-                      ? LOOKUP_NORMAL : LOOKUP_IMPLICIT));
+                      ? LOOKUP_NORMAL : LOOKUP_IMPLICIT) | cf);
     }
   else if ((cxx_dialect != cxx98) && friend_p
           && decl && TREE_CODE (decl) == FUNCTION_DECL)
     /* Core issue #226 (C++0x only): A default template-argument
        shall not be specified in a friend class template
        declaration. */
-    check_default_tmpl_args (decl, current_template_parms, /*is_primary=*/true, 
+    check_default_tmpl_args (decl, current_template_parms, /*is_primary=*/true,
                              /*is_partial=*/false, /*is_friend_decl=*/1);
 
   if (!friend_p && pushed_scope)
@@ -20445,7 +20642,9 @@ cp_parser_init_declarator (cp_parser* parser,
 
    MEMBER_P is true iff this declarator is a member-declarator.
 
-   FRIEND_P is true iff this declarator is a friend.  */
+   FRIEND_P is true iff this declarator is a friend.
+
+   STATIC_P is true iff the keyword static was seen.  */
 
 static cp_declarator *
 cp_parser_declarator (cp_parser* parser,
@@ -20453,7 +20652,7 @@ cp_parser_declarator (cp_parser* parser,
                      cp_parser_flags flags,
                      int* ctor_dtor_or_conv_p,
                      bool* parenthesized_p,
-                     bool member_p, bool friend_p)
+                     bool member_p, bool friend_p, bool static_p)
 {
   cp_declarator *declarator;
   enum tree_code code;
@@ -20495,7 +20694,7 @@ cp_parser_declarator (cp_parser* parser,
                                         /*ctor_dtor_or_conv_p=*/NULL,
                                         /*parenthesized_p=*/NULL,
                                         /*member_p=*/false,
-                                        friend_p);
+                                        friend_p, /*static_p=*/false);
 
       /* If we are parsing an abstract-declarator, we must handle the
         case where the dependent declarator is absent.  */
@@ -20514,7 +20713,7 @@ cp_parser_declarator (cp_parser* parser,
                                                   CPP_OPEN_PAREN);
       declarator = cp_parser_direct_declarator (parser, dcl_kind,
                                                flags, ctor_dtor_or_conv_p,
-                                               member_p, friend_p);
+                                               member_p, friend_p, static_p);
     }
 
   if (gnu_attributes && declarator && declarator != cp_error_declarator)
@@ -20550,7 +20749,7 @@ cp_parser_declarator (cp_parser* parser,
    of ambiguity we prefer an abstract declarator, as per
    [dcl.ambig.res].
    The parser flags FLAGS is used to control type-specifier parsing.
-   CTOR_DTOR_OR_CONV_P, MEMBER_P, and FRIEND_P are
+   CTOR_DTOR_OR_CONV_P, MEMBER_P, FRIEND_P, and STATIC_P are
    as for cp_parser_declarator.  */
 
 static cp_declarator *
@@ -20558,7 +20757,7 @@ cp_parser_direct_declarator (cp_parser* parser,
                             cp_parser_declarator_kind dcl_kind,
                             cp_parser_flags flags,
                             int* ctor_dtor_or_conv_p,
-                            bool member_p, bool friend_p)
+                            bool member_p, bool friend_p, bool static_p)
 {
   cp_token *token;
   cp_declarator *declarator = NULL;
@@ -20661,6 +20860,11 @@ cp_parser_direct_declarator (cp_parser* parser,
                  tree attrs;
                  bool memfn = (member_p || (pushed_scope
                                             && CLASS_TYPE_P (pushed_scope)));
+                 unsigned char local_variables_forbidden_p
+                   = parser->local_variables_forbidden_p;
+                 /* 'this' is not allowed in static member functions.  */
+                 if (static_p || friend_p)
+                   parser->local_variables_forbidden_p |= THIS_FORBIDDEN;
 
                  is_declarator = true;
 
@@ -20676,7 +20880,7 @@ cp_parser_direct_declarator (cp_parser* parser,
                  tree tx_qual = cp_parser_tx_qualifier_opt (parser);
                  /* And the exception-specification.  */
                  exception_specification
-                   = cp_parser_exception_specification_opt (parser);
+                   = cp_parser_exception_specification_opt (parser, flags);
 
                  attrs = cp_parser_std_attribute_spec_seq (parser);
 
@@ -20708,6 +20912,10 @@ cp_parser_direct_declarator (cp_parser* parser,
                     return type, so are not those of the declared
                     function.  */
                  parser->default_arg_ok_p = false;
+
+                 /* Restore the state of local_variables_forbidden_p.  */
+                 parser->local_variables_forbidden_p
+                   = local_variables_forbidden_p;
                }
 
              /* Remove the function parms from scope.  */
@@ -20738,7 +20946,8 @@ cp_parser_direct_declarator (cp_parser* parser,
                = cp_parser_declarator (parser, dcl_kind, flags,
                                        ctor_dtor_or_conv_p,
                                        /*parenthesized_p=*/NULL,
-                                       member_p, friend_p);
+                                       member_p, friend_p,
+                                       /*static_p=*/false);
              parser->in_type_id_in_expr_p = saved_in_type_id_in_expr_p;
              first = false;
              /* Expect a `)'.  */
@@ -21021,6 +21230,44 @@ cp_parser_direct_declarator (cp_parser* parser,
 
            if (pack_expansion_p)
              maybe_warn_variadic_templates ();
+
+           /* We're looking for this case in [temp.res]:
+              A qualified-id is assumed to name a type if [...]
+              - it is a decl-specifier of the decl-specifier-seq of a
+                parameter-declaration in a declarator of a function or
+                function template declaration, ... */
+           if (cxx_dialect >= cxx2a
+               && (flags & CP_PARSER_FLAGS_TYPENAME_OPTIONAL)
+               && declarator->kind == cdk_id
+               && !at_class_scope_p ()
+               && cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
+             {
+               /* ...whose declarator-id is qualified.  If it isn't, never
+                  assume the parameters to refer to types.  */
+               if (qualifying_scope == NULL_TREE)
+                 flags &= ~CP_PARSER_FLAGS_TYPENAME_OPTIONAL;
+               else
+                 {
+                   /* Now we have something like
+                      template <typename T> int C::x(S::p);
+                      which can be a function template declaration or a
+                      variable template definition.  If name lookup for
+                      the declarator-id C::x finds one or more function
+                      templates, assume S::p to name a type.  Otherwise,
+                      don't.  */
+                   tree decl
+                     = cp_parser_lookup_name_simple (parser, unqualified_name,
+                                                     token->location);
+                   if (!is_overloaded_fn (decl)
+                       /* Allow
+                          template<typename T>
+                          A<T>::A(T::type) { }  */
+                       && !(MAYBE_CLASS_TYPE_P (qualifying_scope)
+                            && constructor_name_p (unqualified_name,
+                                                   qualifying_scope)))
+                     flags &= ~CP_PARSER_FLAGS_TYPENAME_OPTIONAL;
+                 }
+             }
          }
 
        handle_declarator:;
@@ -21632,7 +21879,8 @@ cp_parser_type_id_1 (cp_parser *parser, cp_parser_flags flags,
                            CP_PARSER_FLAGS_NONE, NULL,
                            /*parenthesized_p=*/NULL,
                            /*member_p=*/false,
-                           /*friend_p=*/false);
+                           /*friend_p=*/false,
+                           /*static_p=*/false);
   /* Check to see if there really was a declarator.  */
   if (!cp_parser_parse_definitely (parser))
     abstract_declarator = NULL;
@@ -21671,7 +21919,7 @@ cp_parser_type_id_1 (cp_parser *parser, cp_parser_flags flags,
            return error_mark_node;
          }
       }
-  
+
   return groktypename (&type_specifier_seq, abstract_declarator,
                       is_template_arg);
 }
@@ -22217,7 +22465,8 @@ cp_parser_parameter_declaration (cp_parser *parser,
                                         /*ctor_dtor_or_conv_p=*/NULL,
                                         parenthesized_p,
                                         /*member_p=*/false,
-                                        /*friend_p=*/false);
+                                        /*friend_p=*/false,
+                                        /*static_p=*/false);
       parser->default_arg_ok_p = saved_default_arg_ok_p;
       /* After the declarator, allow more attributes.  */
       decl_specifiers.attributes
@@ -22275,7 +22524,7 @@ cp_parser_parameter_declaration (cp_parser *parser,
          /* Consume the `...'. */
          cp_lexer_consume_token (parser->lexer);
          maybe_warn_variadic_templates ();
-         
+
          /* Build a pack expansion type */
          if (template_parm_p)
            template_parameter_pack_p = true;
@@ -22302,12 +22551,14 @@ cp_parser_parameter_declaration (cp_parser *parser,
          && !LAMBDA_TYPE_P (current_class_type))
        default_argument = cp_parser_cache_defarg (parser, /*nsdmi=*/false);
 
-      // A constrained-type-specifier may declare a type template-parameter.
+      /* A constrained-type-specifier may declare a type
+        template-parameter.  */
       else if (declares_constrained_type_template_parameter (type))
         default_argument
           = cp_parser_default_type_template_argument (parser);
 
-      // A constrained-type-specifier may declare a template-template-parameter.
+      /* A constrained-type-specifier may declare a
+        template-template-parameter.  */
       else if (declares_constrained_template_template_parameter (type))
         default_argument
           = cp_parser_default_template_template_argument (parser);
@@ -22329,11 +22580,11 @@ cp_parser_parameter_declaration (cp_parser *parser,
               || (decl_specifiers.type
                   && PACK_EXPANSION_P (decl_specifiers.type)))
        {
-         /* Find the name of the parameter pack.  */     
+         /* Find the name of the parameter pack.  */
          cp_declarator *id_declarator = declarator;
          while (id_declarator && id_declarator->kind != cdk_id)
            id_declarator = id_declarator->declarator;
-         
+
          if (id_declarator && id_declarator->kind == cdk_id)
            error_at (declarator_token_start->location,
                      template_parm_p
@@ -22398,7 +22649,7 @@ cp_parser_default_argument (cp_parser *parser, bool template_parm_p)
 {
   tree default_argument = NULL_TREE;
   bool saved_greater_than_is_operator_p;
-  bool saved_local_variables_forbidden_p;
+  unsigned char saved_local_variables_forbidden_p;
   bool non_constant_p, is_direct_init;
 
   /* Make sure that PARSER->GREATER_THAN_IS_OPERATOR_P is
@@ -22408,7 +22659,7 @@ cp_parser_default_argument (cp_parser *parser, bool template_parm_p)
   /* Local variable names (and the `this' keyword) may not
      appear in a default argument.  */
   saved_local_variables_forbidden_p = parser->local_variables_forbidden_p;
-  parser->local_variables_forbidden_p = true;
+  parser->local_variables_forbidden_p = LOCAL_VARS_AND_THIS_FORBIDDEN;
   /* Parse the assignment-expression.  */
   if (template_parm_p)
     push_deferring_access_checks (dk_no_deferred);
@@ -22462,11 +22713,25 @@ cp_parser_ctor_initializer_opt_and_function_body (cp_parser *parser,
                                                  bool in_function_try_block)
 {
   tree body, list;
-  const bool check_body_p =
-     DECL_CONSTRUCTOR_P (current_function_decl)
-     && DECL_DECLARED_CONSTEXPR_P (current_function_decl);
+  const bool check_body_p
+     = (DECL_CONSTRUCTOR_P (current_function_decl)
+       && DECL_DECLARED_CONSTEXPR_P (current_function_decl));
   tree last = NULL;
 
+  if (in_function_try_block
+      && DECL_DECLARED_CONSTEXPR_P (current_function_decl)
+      && cxx_dialect < cxx2a)
+    {
+      if (DECL_CONSTRUCTOR_P (current_function_decl))
+       pedwarn (input_location, 0,
+                "function-try-block body of %<constexpr%> constructor only "
+                "available with %<-std=c++2a%> or %<-std=gnu++2a%>");
+      else
+       pedwarn (input_location, 0,
+                "function-try-block body of %<constexpr%> function only "
+                "available with %<-std=c++2a%> or %<-std=gnu++2a%>");
+    }
+
   /* Begin the function body.  */
   body = begin_function_body ();
   /* Parse the optional ctor-initializer.  */
@@ -22610,7 +22875,7 @@ cp_parser_initializer_clause (cp_parser* parser, bool* non_constant_p)
    production is used).  The TREE_TYPE for the CONSTRUCTOR will be
    NULL_TREE.  There is no way to detect whether or not the optional
    trailing `,' was provided.  NON_CONSTANT_P is as for
-   cp_parser_initializer.  */     
+   cp_parser_initializer.  */
 
 static cp_expr
 cp_parser_braced_list (cp_parser* parser, bool* non_constant_p)
@@ -22626,9 +22891,11 @@ cp_parser_braced_list (cp_parser* parser, bool* non_constant_p)
   /* If it's not a `}', then there is a non-trivial initializer.  */
   if (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_BRACE))
     {
+      bool designated;
       /* Parse the initializer list.  */
       CONSTRUCTOR_ELTS (initializer)
-       = cp_parser_initializer_list (parser, non_constant_p);
+       = cp_parser_initializer_list (parser, non_constant_p, &designated);
+      CONSTRUCTOR_IS_DESIGNATED_INIT (initializer) = designated;
       /* A trailing `,' token is allowed.  */
       if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
        cp_lexer_consume_token (parser->lexer);
@@ -22709,7 +22976,7 @@ cp_parser_array_designator_p (cp_parser *parser)
   bool array_designator_p
     = (cp_parser_skip_to_closing_square_bracket (parser)
        && cp_lexer_next_token_is (parser->lexer, CPP_EQ));
-  
+
   /* Roll back the tokens we skipped.  */
   cp_lexer_rollback_tokens (parser->lexer);
 
@@ -22748,10 +23015,12 @@ cp_parser_array_designator_p (cp_parser *parser)
    Returns a vec of constructor_elt.  The VALUE of each elt is an expression
    for the initializer.  If the INDEX of the elt is non-NULL, it is the
    IDENTIFIER_NODE naming the field to initialize.  NON_CONSTANT_P is
-   as for cp_parser_initializer.  */
+   as for cp_parser_initializer.  Set *DESIGNATED to a boolean whether there
+   are any designators.  */
 
 static vec<constructor_elt, va_gc> *
-cp_parser_initializer_list (cp_parser* parser, bool* non_constant_p)
+cp_parser_initializer_list (cp_parser* parser, bool* non_constant_p,
+                           bool *designated)
 {
   vec<constructor_elt, va_gc> *v = NULL;
   bool first_p = true;
@@ -22781,7 +23050,7 @@ cp_parser_initializer_list (cp_parser* parser, bool* non_constant_p)
          if (cxx_dialect < cxx2a)
            pedwarn (loc, OPT_Wpedantic,
                     "C++ designated initializers only available with "
-                    "-std=c++2a or -std=gnu++2a");
+                    "%<-std=c++2a%> or %<-std=gnu++2a%>");
          /* Consume the `.'.  */
          cp_lexer_consume_token (parser->lexer);
          /* Consume the identifier.  */
@@ -22914,7 +23183,7 @@ cp_parser_initializer_list (cp_parser* parser, bool* non_constant_p)
          {
            if (IDENTIFIER_MARKED (designator))
              {
-               error_at (cp_expr_loc_or_loc (val, input_location),
+               error_at (cp_expr_loc_or_input_loc (val),
                          "%<.%s%> designator used multiple times in "
                          "the same initializer list",
                          IDENTIFIER_POINTER (designator));
@@ -22928,6 +23197,7 @@ cp_parser_initializer_list (cp_parser* parser, bool* non_constant_p)
          IDENTIFIER_MARKED (designator) = 0;
     }
 
+  *designated = first_designator != NULL_TREE;
   return v;
 }
 
@@ -23056,7 +23326,9 @@ cp_parser_class_name (cp_parser *parser,
   decl = cp_parser_maybe_treat_template_as_class (decl, class_head_p);
 
   /* If this is a typename, create a TYPENAME_TYPE.  */
-  if (typename_p && decl != error_mark_node)
+  if (typename_p
+      && decl != error_mark_node
+      && !is_overloaded_fn (decl))
     {
       decl = make_typename_type (scope, decl, typename_type,
                                 /*complain=*/tf_error);
@@ -23092,7 +23364,7 @@ cp_parser_class_name (cp_parser *parser,
           /* In Objective-C 2.0, a classname followed by '.' starts a
              dot-syntax expression, and it's not a type-name.  */
           || (c_dialect_objc ()
-              && cp_lexer_peek_token (parser->lexer)->type == CPP_DOT 
+              && cp_lexer_peek_token (parser->lexer)->type == CPP_DOT
               && objc_is_class_name (decl)))
     decl = error_mark_node;
 
@@ -23104,6 +23376,34 @@ cp_parser_class_name (cp_parser *parser,
   return decl;
 }
 
+/* Make sure that any member-function parameters are in scope.
+   For instance, a function's noexcept-specifier can use the function's
+   parameters:
+
+   struct S {
+     void fn (int p) noexcept(noexcept(p));
+   };
+
+   so we need to make sure name lookup can find them.  This is used
+   when we delay parsing of the noexcept-specifier.  */
+
+static void
+inject_parm_decls (tree decl)
+{
+  begin_scope (sk_function_parms, decl);
+  tree args = DECL_ARGUMENTS (decl);
+
+  do_push_parm_decls (decl, args, /*nonparms=*/NULL);
+}
+
+/* Undo the effects of inject_parm_decls.  */
+
+static void
+pop_injected_parms (void)
+{
+  pop_bindings_and_leave_scope ();
+}
+
 /* Parse a class-specifier.
 
    class-specifier:
@@ -23152,7 +23452,7 @@ cp_parser_class_specifier_1 (cp_parser* parser)
   cp_ensure_no_oacc_routine (parser);
 
   /* Issue an error message if type-definitions are forbidden here.  */
-  cp_parser_check_type_definition (parser);
+  bool type_definition_ok_p = cp_parser_check_type_definition (parser);
   /* Remember that we are defining one more class.  */
   ++parser->num_classes_being_defined;
   /* Inside the class, surrounding template-parameter-lists do not
@@ -23347,7 +23647,7 @@ cp_parser_class_specifier_1 (cp_parser* parser)
       cp_default_arg_entry *e;
       tree save_ccp, save_ccr;
 
-      if (any_erroneous_template_args_p (type))
+      if (!type_definition_ok_p || any_erroneous_template_args_p (type))
        {
          /* Skip default arguments, NSDMIs, etc, in order to improve
             error recovery (c++/71169, c++/71832).  */
@@ -23414,6 +23714,60 @@ cp_parser_class_specifier_1 (cp_parser* parser)
       vec_safe_truncate (unparsed_classes, 0);
       after_nsdmi_defaulted_late_checks (type);
 
+      /* If there are noexcept-specifiers that have not yet been processed,
+        take care of them now.  */
+      class_type = NULL_TREE;
+      pushed_scope = NULL_TREE;
+      FOR_EACH_VEC_SAFE_ELT (unparsed_noexcepts, ix, decl)
+       {
+         tree ctx = DECL_CONTEXT (decl);
+         if (class_type != ctx)
+           {
+             if (pushed_scope)
+               pop_scope (pushed_scope);
+             class_type = ctx;
+             pushed_scope = push_scope (class_type);
+           }
+
+         tree spec = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (decl));
+         spec = TREE_PURPOSE (spec);
+
+         /* Make sure that any template parameters are in scope.  */
+         maybe_begin_member_template_processing (decl);
+
+         /* Make sure that any member-function parameters are in scope.  */
+         inject_parm_decls (decl);
+
+         /* 'this' is not allowed in static member functions.  */
+         unsigned char local_variables_forbidden_p
+           = parser->local_variables_forbidden_p;
+         if (DECL_THIS_STATIC (decl))
+           parser->local_variables_forbidden_p |= THIS_FORBIDDEN;
+
+         /* Now we can parse the noexcept-specifier.  */
+         spec = cp_parser_late_noexcept_specifier (parser, spec);
+
+         if (spec != error_mark_node)
+           TREE_TYPE (decl) = build_exception_variant (TREE_TYPE (decl), spec);
+
+         /* Restore the state of local_variables_forbidden_p.  */
+         parser->local_variables_forbidden_p = local_variables_forbidden_p;
+
+         /* The finish_struct call above performed various override checking,
+            but it skipped unparsed noexcept-specifier operands.  Now that we
+            have resolved them, check again.  */
+         noexcept_override_late_checks (type, decl);
+
+         /* Remove any member-function parameters from the symbol table.  */
+         pop_injected_parms ();
+
+         /* Remove any template parameters from the symbol table.  */
+         maybe_end_member_template_processing ();
+       }
+      vec_safe_truncate (unparsed_noexcepts, 0);
+      if (pushed_scope)
+       pop_scope (pushed_scope);
+
       /* Now parse the body of the functions.  */
       if (flag_openmp)
        {
@@ -23872,8 +24226,11 @@ cp_parser_class_head (cp_parser* parser,
   cp_parser_check_class_key (class_key, type);
 
   /* If this type was already complete, and we see another definition,
-     that's an error.  */
-  if (type != error_mark_node && COMPLETE_TYPE_P (type))
+     that's an error.  Likewise if the type is already being defined:
+     this can happen, eg, when it's defined from within an expression 
+     (c++/84605).  */
+  if (type != error_mark_node
+      && (COMPLETE_TYPE_P (type) || TYPE_BEING_DEFINED (type)))
     {
       error_at (type_start_token->location, "redefinition of %q#T",
                type);
@@ -23990,9 +24347,9 @@ cp_parser_type_parameter_key (cp_parser* parser)
       if (pedantic && tag_type == typename_type && cxx_dialect < cxx17)
        /* typename is not allowed in a template template parameter
           by the standard until C++17.  */
-       pedwarn (token->location, OPT_Wpedantic, 
+       pedwarn (token->location, OPT_Wpedantic,
                 "ISO C++ forbids typename key in template template parameter;"
-                " use -std=c++17 or -std=gnu++17");
+                " use %<-std=c++17%> or %<-std=gnu++17%>");
     }
   else
     cp_parser_error (parser, "expected %<class%> or %<typename%>");
@@ -24079,7 +24436,7 @@ cp_parser_member_specification_opt (cp_parser* parser)
    member-declarator:
      declarator attributes [opt] pure-specifier [opt]
      declarator attributes [opt] constant-initializer [opt]
-     identifier [opt] attributes [opt] : constant-expression  
+     identifier [opt] attributes [opt] : constant-expression
 
    C++0x Extensions:
 
@@ -24378,8 +24735,8 @@ cp_parser_member_declaration (cp_parser* parser)
                      && identifier != NULL_TREE)
                    pedwarn (loc, 0,
                             "default member initializers for bit-fields "
-                            "only available with -std=c++2a or "
-                            "-std=gnu++2a");
+                            "only available with %<-std=c++2a%> or "
+                            "%<-std=gnu++2a%>");
 
                  initializer = cp_parser_save_nsdmi (parser);
                  if (identifier == NULL_TREE)
@@ -24390,7 +24747,7 @@ cp_parser_member_declaration (cp_parser* parser)
                    }
                }
              else
-               { 
+               {
                  /* Look for attributes that apply to the bitfield after
                     the `:' token and width.  This is where GCC used to
                     parse attributes in the past, pedwarn if there is
@@ -24427,15 +24784,20 @@ cp_parser_member_declaration (cp_parser* parser)
              cp_declarator *declarator;
              tree asm_specification;
              int ctor_dtor_or_conv_p;
+             bool static_p = (decl_specifiers.storage_class == sc_static);
+             cp_parser_flags flags = CP_PARSER_FLAGS_TYPENAME_OPTIONAL;
+             if (!friend_p
+                 && !decl_spec_seq_has_spec_p (&decl_specifiers, ds_typedef))
+               flags |= CP_PARSER_FLAGS_DELAY_NOEXCEPT;
 
              /* Parse the declarator.  */
              declarator
                = cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED,
-                                       CP_PARSER_FLAGS_TYPENAME_OPTIONAL,
+                                       flags,
                                        &ctor_dtor_or_conv_p,
                                        /*parenthesized_p=*/NULL,
                                        /*member_p=*/true,
-                                       friend_p);
+                                       friend_p, static_p);
 
              /* If something went wrong parsing the declarator, make sure
                 that we at least consume some tokens.  */
@@ -24965,6 +25327,89 @@ cp_parser_base_specifier (cp_parser* parser)
 
 /* Exception handling [gram.exception] */
 
+/* Save the tokens that make up the noexcept-specifier for a member-function.
+   Returns a DEFERRED_PARSE.  */
+
+static tree
+cp_parser_save_noexcept (cp_parser *parser)
+{
+  cp_token *first = parser->lexer->next_token;
+  /* We want everything up to, including, the final ')'.  */
+  cp_parser_cache_group (parser, CPP_CLOSE_PAREN, /*depth=*/0);
+  cp_token *last = parser->lexer->next_token;
+
+  /* As with default arguments and NSDMIs, make use of DEFERRED_PARSE
+     to carry the information we will need.  */
+  tree expr = make_node (DEFERRED_PARSE);
+  /* Save away the noexcept-specifier; we will process it when the
+     class is complete.  */
+  DEFPARSE_TOKENS (expr) = cp_token_cache_new (first, last);
+  expr = build_tree_list (expr, NULL_TREE);
+  return expr;
+}
+
+/* Used for late processing of noexcept-specifiers of member-functions.
+   DEFAULT_ARG is the unparsed operand of a noexcept-specifier which
+   we saved for later; parse it now.  */
+
+static tree
+cp_parser_late_noexcept_specifier (cp_parser *parser, tree default_arg)
+{
+  /* Make sure we've gotten something that hasn't been parsed yet.  */
+  gcc_assert (TREE_CODE (default_arg) == DEFERRED_PARSE);
+
+  push_unparsed_function_queues (parser);
+
+  /* Push the saved tokens for the noexcept-specifier onto the parser's
+     lexer stack.  */
+  cp_token_cache *tokens = DEFPARSE_TOKENS (default_arg);
+  cp_parser_push_lexer_for_tokens (parser, tokens);
+
+  /* Parse the cached noexcept-specifier.  */
+  tree parsed_arg
+    = cp_parser_noexcept_specification_opt (parser,
+                                           CP_PARSER_FLAGS_NONE,
+                                           /*require_constexpr=*/true,
+                                           /*consumed_expr=*/NULL,
+                                           /*return_cond=*/false);
+
+  /* Revert to the main lexer.  */
+  cp_parser_pop_lexer (parser);
+
+  /* Restore the queue.  */
+  pop_unparsed_function_queues (parser);
+
+  /* And we're done.  */
+  return parsed_arg;
+}
+
+/* Perform late checking of overriding function with respect to their
+   noexcept-specifiers.  TYPE is the class and FNDECL is the function
+   that potentially overrides some virtual function with the same
+   signature.  */
+
+static void
+noexcept_override_late_checks (tree type, tree fndecl)
+{
+  tree binfo = TYPE_BINFO (type);
+  tree base_binfo;
+
+  if (DECL_STATIC_FUNCTION_P (fndecl))
+    return;
+
+  for (int i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i)
+    {
+      tree basetype = BINFO_TYPE (base_binfo);
+
+      if (!TYPE_POLYMORPHIC_P (basetype))
+       continue;
+
+      tree fn = look_for_overrides_here (basetype, fndecl);
+      if (fn)
+       maybe_check_overriding_exception_spec (fndecl, fn);
+    }
+}
+
 /* Parse an (optional) noexcept-specification.
 
    noexcept-specification:
@@ -24975,10 +25420,12 @@ cp_parser_base_specifier (cp_parser* parser)
    expression if parentheses follow noexcept, or return BOOLEAN_TRUE_NODE if
    there are no parentheses.  CONSUMED_EXPR will be set accordingly.
    Otherwise, returns a noexcept specification unless RETURN_COND is true,
-   in which case a boolean condition is returned instead.  */
+   in which case a boolean condition is returned instead.  The parser flags
+   FLAGS is used to control parsing.  */
 
 static tree
 cp_parser_noexcept_specification_opt (cp_parser* parser,
+                                     cp_parser_flags flags,
                                      bool require_constexpr,
                                      bool* consumed_expr,
                                      bool return_cond)
@@ -24993,6 +25440,29 @@ cp_parser_noexcept_specification_opt (cp_parser* parser,
   if (cp_parser_is_keyword (token, RID_NOEXCEPT))
     {
       tree expr;
+
+      /* [class.mem]/6 says that a noexcept-specifer (within the
+        member-specification of the class) is a complete-class context of
+        a class.  So, if the noexcept-specifier has the optional expression,
+        just save the tokens, and reparse this after we're done with the
+        class.  */
+      const bool literal_p
+       = ((cp_lexer_nth_token_is (parser->lexer, 3, CPP_NUMBER)
+           || cp_lexer_nth_token_is (parser->lexer, 3, CPP_KEYWORD))
+          && cp_lexer_nth_token_is (parser->lexer, 4, CPP_CLOSE_PAREN));
+
+      if (cp_lexer_nth_token_is (parser->lexer, 2, CPP_OPEN_PAREN)
+         /* No need to delay parsing for a number literal or true/false.  */
+         && !literal_p
+         && at_class_scope_p ()
+         /* We don't delay parsing for friend member functions,
+            alias-declarations, and typedefs, even though the standard seems
+            to require it.  */
+         && (flags & CP_PARSER_FLAGS_DELAY_NOEXCEPT)
+         && TYPE_BEING_DEFINED (current_class_type)
+         && !LAMBDA_TYPE_P (current_class_type))
+       return cp_parser_save_noexcept (parser);
+
       cp_lexer_consume_token (parser->lexer);
 
       if (cp_lexer_peek_token (parser->lexer)->type == CPP_OPEN_PAREN)
@@ -25013,7 +25483,17 @@ cp_parser_noexcept_specification_opt (cp_parser* parser,
              parser->type_definition_forbidden_message
              = G_("types may not be defined in an exception-specification");
 
-             expr = cp_parser_constant_expression (parser);
+             bool non_constant_p;
+             expr
+               = cp_parser_constant_expression (parser,
+                                                /*allow_non_constant=*/true,
+                                                &non_constant_p);
+             if (non_constant_p
+                 && !require_potential_rvalue_constant_expression (expr))
+               {
+                 expr = NULL_TREE;
+                 return_cond = true;
+               }
 
              /* Restore the saved message.  */
              parser->type_definition_forbidden_message = saved_message;
@@ -25053,10 +25533,11 @@ cp_parser_noexcept_specification_opt (cp_parser* parser,
      throw ( type-id-list [opt] )
 
    Returns a TREE_LIST representing the exception-specification.  The
-   TREE_VALUE of each node is a type.  */
+   TREE_VALUE of each node is a type.  The parser flags FLAGS is used to
+   control parsing.  */
 
 static tree
-cp_parser_exception_specification_opt (cp_parser* parser)
+cp_parser_exception_specification_opt (cp_parser* parser, cp_parser_flags flags)
 {
   cp_token *token;
   tree type_id_list;
@@ -25066,8 +25547,11 @@ cp_parser_exception_specification_opt (cp_parser* parser)
   token = cp_lexer_peek_token (parser->lexer);
 
   /* Is it a noexcept-specification?  */
-  type_id_list = cp_parser_noexcept_specification_opt (parser, true, NULL,
-                                                      false);
+  type_id_list
+    = cp_parser_noexcept_specification_opt (parser, flags,
+                                           /*require_constexpr=*/true,
+                                           /*consumed_expr=*/NULL,
+                                           /*return_cond=*/false);
   if (type_id_list != NULL_TREE)
     return type_id_list;
 
@@ -25188,8 +25672,11 @@ cp_parser_try_block (cp_parser* parser)
 
   cp_parser_require_keyword (parser, RID_TRY, RT_TRY);
   if (parser->in_function_body
-      && DECL_DECLARED_CONSTEXPR_P (current_function_decl))
-    error ("%<try%> in %<constexpr%> function");
+      && DECL_DECLARED_CONSTEXPR_P (current_function_decl)
+      && cxx_dialect < cxx2a)
+    pedwarn (input_location, 0,
+            "%<try%> in %<constexpr%> function only "
+            "available with %<-std=c++2a%> or %<-std=gnu++2a%>");
 
   try_block = begin_try_block ();
   cp_parser_compound_statement (parser, NULL, BCS_TRY_BLOCK, false);
@@ -25316,7 +25803,8 @@ cp_parser_exception_declaration (cp_parser* parser)
                                       /*ctor_dtor_or_conv_p=*/NULL,
                                       /*parenthesized_p=*/NULL,
                                       /*member_p=*/false,
-                                      /*friend_p=*/false);
+                                      /*friend_p=*/false,
+                                      /*static_p=*/false);
 
   /* Restore the saved message.  */
   parser->type_definition_forbidden_message = saved_message;
@@ -25450,8 +25938,8 @@ cp_parser_asm_operand_list (cp_parser* parser)
       /* Look for the `)'.  */
       parens.require_close (parser);
 
-      if (name == error_mark_node 
-         || string_literal == error_mark_node 
+      if (name == error_mark_node
+         || string_literal == error_mark_node
          || expression == error_mark_node)
         invalid_operands = true;
 
@@ -25655,9 +26143,11 @@ cp_parser_gnu_attributes_opt (cp_parser* parser)
       cp_lexer_consume_token (parser->lexer);
       /* Look for the two `(' tokens.  */
       matching_parens outer_parens;
-      outer_parens.require_open (parser);
+      if (!outer_parens.require_open (parser))
+       ok = false;
       matching_parens inner_parens;
-      inner_parens.require_open (parser);
+      if (!inner_parens.require_open (parser))
+       ok = false;
 
       /* Peek at the next token.  */
       token = cp_lexer_peek_token (parser->lexer);
@@ -25732,7 +26222,7 @@ cp_parser_gnu_attribute_list (cp_parser* parser, bool exactly_one /* = false */)
 
          /* Save away the identifier that indicates which attribute
             this is.  */
-         identifier = (token->type == CPP_KEYWORD) 
+         identifier = (token->type == CPP_KEYWORD)
            /* For keywords, use the canonical spelling, not the
               parsed identifier.  */
            ? ridpointers[(int) token->keyword]
@@ -25749,9 +26239,9 @@ cp_parser_gnu_attribute_list (cp_parser* parser, bool exactly_one /* = false */)
              vec<tree, va_gc> *vec;
              int attr_flag = (attribute_takes_identifier_p (identifier)
                               ? id_attr : normal_attr);
-             vec = cp_parser_parenthesized_expression_list 
-                   (parser, attr_flag, /*cast_p=*/false, 
-                   /*allow_expansion_p=*/false, 
+             vec = cp_parser_parenthesized_expression_list
+                   (parser, attr_flag, /*cast_p=*/false,
+                   /*allow_expansion_p=*/false,
                    /*non_constant_p=*/NULL);
              if (vec == NULL)
                arguments = error_mark_node;
@@ -25895,11 +26385,11 @@ cp_parser_std_attribute (cp_parser *parser, tree attr_ns)
       attr_id = canonicalize_attr_name (attr_id);
       attribute = build_tree_list (build_tree_list (NULL_TREE, attr_id),
                                   NULL_TREE);
-      /* C++11 noreturn attribute is equivalent to GNU's.  */
-      if (is_attribute_p ("noreturn", attr_id))
-       TREE_PURPOSE (TREE_PURPOSE (attribute)) = gnu_identifier;
+      /* We used to treat C++11 noreturn attribute as equivalent to GNU's,
+        but no longer: we have to be able to tell [[noreturn]] and
+        __attribute__((noreturn)) apart.  */
       /* C++14 deprecated attribute is equivalent to GNU's.  */
-      else if (is_attribute_p ("deprecated", attr_id))
+      if (is_attribute_p ("deprecated", attr_id))
        TREE_PURPOSE (TREE_PURPOSE (attribute)) = gnu_identifier;
       /* C++17 fallthrough attribute is equivalent to GNU's.  */
       else if (is_attribute_p ("fallthrough", attr_id))
@@ -25923,6 +26413,20 @@ cp_parser_std_attribute (cp_parser *parser, tree attr_ns)
     vec<tree, va_gc> *vec;
     int attr_flag = normal_attr;
 
+    /* Maybe we don't expect to see any arguments for this attribute.  */
+    const attribute_spec *as
+      = lookup_attribute_spec (TREE_PURPOSE (attribute));
+    if (as && as->max_length == 0)
+      {
+       error_at (token->location, "%qE attribute does not take any arguments",
+                 attr_id);
+       cp_parser_skip_to_closing_parenthesis (parser,
+                                              /*recovering=*/true,
+                                              /*or_comma=*/false,
+                                              /*consume_paren=*/true);
+       return error_mark_node;
+      }
+
     if (attr_ns == gnu_identifier
        && attribute_takes_identifier_p (attr_id))
       /* A GNU attribute that takes an identifier in parameter.  */
@@ -26065,7 +26569,7 @@ cp_parser_std_attribute_spec (cp_parser *parser)
                  && !in_system_header_at (input_location))
                pedwarn (input_location, 0,
                         "attribute using prefix only available "
-                        "with -std=c++17 or -std=gnu++17");
+                        "with %<-std=c++17%> or %<-std=gnu++17%>");
 
              cp_lexer_consume_token (parser->lexer);
              cp_lexer_consume_token (parser->lexer);
@@ -26131,6 +26635,12 @@ cp_parser_std_attribute_spec (cp_parser *parser)
       if (alignas_expr == error_mark_node)
        return error_mark_node;
 
+      /* Missing ')' means the code cannot possibly be valid; go ahead
+        and commit to make sure we issue a hard error.  */
+      if (cp_parser_uncommitted_to_tentative_parse_p (parser)
+         && cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_PAREN))
+       cp_parser_commit_to_tentative_parse (parser);
+
       if (!parens.require_close (parser))
        return error_mark_node;
 
@@ -26388,7 +26898,7 @@ cp_parser_requires_clause_opt (cp_parser *parser)
          && tok->u.value == ridpointers[RID_REQUIRES])
        {
          error_at (cp_lexer_peek_token (parser->lexer)->location,
-                   "%<requires%> only available with -fconcepts");
+                   "%<requires%> only available with %<-fconcepts%>");
          /* Parse and discard the requires-clause.  */
          cp_lexer_consume_token (parser->lexer);
          cp_parser_requires_clause (parser);
@@ -27084,7 +27594,7 @@ cp_parser_check_declarator_template_parameters (cp_parser* parser,
            template_id_p = true;
          }
 
-       return cp_parser_check_template_parameters 
+       return cp_parser_check_template_parameters
          (parser, num_templates, template_id_p, declarator_location,
           declarator);
       }
@@ -27136,14 +27646,14 @@ cp_parser_check_template_parameters (cp_parser* parser,
     {
       if (declarator && !current_function_decl)
        error_at (location, "specializing member %<%T::%E%> "
-                 "requires %<template<>%> syntax", 
+                 "requires %<template<>%> syntax",
                  declarator->u.id.qualifying_scope,
                  declarator->u.id.unqualified_name);
       else if (declarator)
        error_at (location, "invalid declaration of %<%T::%E%>",
                  declarator->u.id.qualifying_scope,
                  declarator->u.id.unqualified_name);
-      else 
+      else
        error_at (location, "too few template-parameter-lists");
       return false;
     }
@@ -27194,10 +27704,12 @@ cp_parser_global_scope_opt (cp_parser* parser, bool current_scope_valid_p)
 
 /* Returns TRUE if the upcoming token sequence is the start of a
    constructor declarator or C++17 deduction guide.  If FRIEND_P is true, the
-   declarator is preceded by the `friend' specifier.  */
+   declarator is preceded by the `friend' specifier.  The parser flags FLAGS
+   is used to control type-specifier parsing.  */
 
 static bool
-cp_parser_constructor_declarator_p (cp_parser *parser, bool friend_p)
+cp_parser_constructor_declarator_p (cp_parser *parser, cp_parser_flags flags,
+                                   bool friend_p)
 {
   bool constructor_p;
   bool outside_class_specifier_p;
@@ -27344,7 +27856,9 @@ cp_parser_constructor_declarator_p (cp_parser *parser, bool friend_p)
          /* A parameter declaration begins with a decl-specifier,
             which is either the "attribute" keyword, a storage class
             specifier, or (usually) a type-specifier.  */
-         && !cp_lexer_next_token_is_decl_specifier_keyword (parser->lexer))
+         && !cp_lexer_next_token_is_decl_specifier_keyword (parser->lexer)
+         /* A parameter declaration can also begin with [[attribute]].  */
+         && !cp_next_tokens_can_be_std_attribute_p (parser))
        {
          tree type;
          tree pushed_scope = NULL_TREE;
@@ -27376,9 +27890,20 @@ cp_parser_constructor_declarator_p (cp_parser *parser, bool friend_p)
            = parser->num_template_parameter_lists;
          parser->num_template_parameter_lists = 0;
 
-         /* Look for the type-specifier.  */
+         /* Look for the type-specifier.  It's not optional, but its typename
+            might be.  Unless this is a friend declaration; we don't want to
+            treat
+
+              friend S (T::fn)(int);
+
+            as a constructor, but with P0634, we might assume a type when
+            looking for the type-specifier.  It is actually a function named
+            `T::fn' that takes one parameter (of type `int') and returns a
+            value of type `S'.  Constructors can be friends, but they must
+            use a qualified name.  */
          cp_parser_type_specifier (parser,
-                                   CP_PARSER_FLAGS_NONE,
+                                   (friend_p ? CP_PARSER_FLAGS_NONE
+                                    : (flags & ~CP_PARSER_FLAGS_OPTIONAL)),
                                    /*decl_specs=*/NULL,
                                    /*is_declarator=*/true,
                                    /*declares_class_or_enum=*/NULL,
@@ -27648,7 +28173,10 @@ cp_parser_template_declaration_after_parameters (cp_parser* parser,
            {
              tree parm_list = TREE_VEC_ELT (parameter_list, 0);
              tree parm = INNERMOST_TEMPLATE_PARMS (parm_list);
-             if (CLASS_TYPE_P (TREE_TYPE (parm)))
+             if (TREE_CODE (parm) != PARM_DECL)
+               ok = false;
+             else if (MAYBE_CLASS_TYPE_P (TREE_TYPE (parm))
+                      && !TEMPLATE_PARM_PARAMETER_PACK (DECL_INITIAL (parm)))
                /* OK, C++20 string literal operator template.  We don't need
                   to warn in lower dialects here because we will have already
                   warned about the template parameter.  */;
@@ -27662,7 +28190,7 @@ cp_parser_template_declaration_after_parameters (cp_parser* parser,
              tree type = INNERMOST_TEMPLATE_PARMS (parm_type);
              tree parm_list = TREE_VEC_ELT (parameter_list, 1);
              tree parm = INNERMOST_TEMPLATE_PARMS (parm_list);
-             if (parm == error_mark_node
+             if (TREE_CODE (parm) != PARM_DECL
                  || TREE_TYPE (parm) != TREE_TYPE (type)
                  || !TEMPLATE_PARM_PARAMETER_PACK (DECL_INITIAL (parm)))
                ok = false;
@@ -27678,14 +28206,16 @@ cp_parser_template_declaration_after_parameters (cp_parser* parser,
       if (!ok)
        {
          if (cxx_dialect > cxx17)
-           error ("literal operator template %qD has invalid parameter list;"
-                  "  Expected non-type template parameter pack <char...> "
-                  "  or single non-type parameter of class type",
-                  decl);
+           error_at (DECL_SOURCE_LOCATION (decl), "literal operator "
+                     "template %qD has invalid parameter list; expected "
+                     "non-type template parameter pack %<<char...>%> or "
+                     "single non-type parameter of class type",
+                     decl);
          else
-           error ("literal operator template %qD has invalid parameter list."
-                  "  Expected non-type template parameter pack <char...>",
-                  decl);
+           error_at (DECL_SOURCE_LOCATION (decl), "literal operator "
+                     "template %qD has invalid parameter list; expected "
+                     "non-type template parameter pack %<<char...>%>",
+                     decl);
        }
     }
 
@@ -27947,9 +28477,9 @@ cp_parser_single_declaration (cp_parser* parser,
       if (cp_parser_declares_only_class_p (parser)
          || (declares_class_or_enum & 2))
        {
-         // If this is a declaration, but not a definition, associate
-         // any constraints with the type declaration. Constraints
-         // are associated with definitions in cp_parser_class_specifier.
+         /* If this is a declaration, but not a definition, associate
+            any constraints with the type declaration. Constraints
+            are associated with definitions in cp_parser_class_specifier.  */
          if (declares_class_or_enum == 1)
            associate_classtype_constraints (decl_specifiers.type);
 
@@ -28098,10 +28628,8 @@ cp_parser_functional_cast (cp_parser* parser, tree type)
            ^~~~~~~~~~~~~~~
         with caret == start at the start of the type name,
         finishing at the closing brace.  */
-      location_t finish_loc
-       = get_finish (cp_lexer_previous_token (parser->lexer)->location);
       location_t combined_loc = make_location (start_loc, start_loc,
-                                              finish_loc);
+                                              parser->lexer);
       cast.set_location (combined_loc);
       return cast;
    }
@@ -28136,9 +28664,7 @@ cp_parser_functional_cast (cp_parser* parser, tree type)
        ^~~~~~~~
      with caret == start at the start of the type name,
      finishing at the closing paren.  */
-  location_t finish_loc
-    = get_finish (cp_lexer_previous_token (parser->lexer)->location);
-  location_t combined_loc = make_location (start_loc, start_loc, finish_loc);
+  location_t combined_loc = make_location (start_loc, start_loc, parser->lexer);
   cast.set_location (combined_loc);
   return cast;
 }
@@ -28174,7 +28700,7 @@ cp_parser_save_member_function_body (cp_parser* parser,
       return error_mark_node;
     }
 
-  /* Remember it, if there default args to post process.  */
+  /* Remember it, if there are default args to post process.  */
   cp_parser_save_default_args (parser, fn);
 
   /* Save away the tokens that make up the body of the
@@ -28255,7 +28781,7 @@ cp_parser_save_member_function_body (cp_parser* parser,
 }
 
 /* Save the tokens that make up the in-class initializer for a non-static
-   data member.  Returns a DEFAULT_ARG.  */
+   data member.  Returns a DEFERRED_PARSE.  */
 
 static tree
 cp_parser_save_nsdmi (cp_parser* parser)
@@ -28467,6 +28993,11 @@ cp_parser_save_default_args (cp_parser* parser, tree decl)
        vec_safe_push (unparsed_funs_with_default_args, entry);
        break;
       }
+
+  /* Remember if there is a noexcept-specifier to post process.  */
+  tree spec = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (decl));
+  if (UNPARSED_NOEXCEPT_SPEC_P (spec))
+    vec_safe_push (unparsed_noexcepts, decl);
 }
 
 /* DEFAULT_ARG contains the saved tokens for the initializer of DECL,
@@ -28487,7 +29018,7 @@ cp_parser_late_parse_one_default_arg (cp_parser *parser, tree decl,
 
   /* Push the saved tokens for the default argument onto the parser's
      lexer stack.  */
-  tokens = DEFARG_TOKENS (default_arg);
+  tokens = DEFPARSE_TOKENS (default_arg);
   cp_parser_push_lexer_for_tokens (parser, tokens);
 
   start_lambda_scope (decl);
@@ -28554,14 +29085,14 @@ cp_parser_late_parsing_nsdmi (cp_parser *parser, tree field)
 }
 
 /* FN is a FUNCTION_DECL which may contains a parameter with an
-   unparsed DEFAULT_ARG.  Parse the default args now.  This function
+   unparsed DEFERRED_PARSE.  Parse the default args now.  This function
    assumes that the current scope is the scope in which the default
    argument should be processed.  */
 
 static void
 cp_parser_late_parsing_default_args (cp_parser *parser, tree fn)
 {
-  bool saved_local_variables_forbidden_p;
+  unsigned char saved_local_variables_forbidden_p;
   tree parm, parmdecl;
 
   /* While we're parsing the default args, we might (due to the
@@ -28573,7 +29104,7 @@ cp_parser_late_parsing_default_args (cp_parser *parser, tree fn)
   /* Local variable names (and the `this' keyword) may not appear
      in a default argument.  */
   saved_local_variables_forbidden_p = parser->local_variables_forbidden_p;
-  parser->local_variables_forbidden_p = true;
+  parser->local_variables_forbidden_p = LOCAL_VARS_AND_THIS_FORBIDDEN;
 
   push_defarg_context (fn);
 
@@ -28592,7 +29123,7 @@ cp_parser_late_parsing_default_args (cp_parser *parser, tree fn)
       if (!default_arg)
        continue;
 
-      if (TREE_CODE (default_arg) != DEFAULT_ARG)
+      if (TREE_CODE (default_arg) != DEFERRED_PARSE)
        /* This can happen for a friend declaration for a function
           already declared with default arguments.  */
        continue;
@@ -28604,7 +29135,7 @@ cp_parser_late_parsing_default_args (cp_parser *parser, tree fn)
       TREE_PURPOSE (parm) = parsed_arg;
 
       /* Update any instantiations we've already created.  */
-      for (insts = DEFARG_INSTANTIATIONS (default_arg), ix = 0;
+      for (insts = DEFPARSE_INSTANTIATIONS (default_arg), ix = 0;
           vec_safe_iterate (insts, ix, &copy); ix++)
        TREE_PURPOSE (copy) = parsed_arg;
     }
@@ -28677,7 +29208,7 @@ cp_parser_sizeof_operand (cp_parser* parser, enum rid keyword)
 {
   tree expr = NULL_TREE;
   const char *saved_message;
-  char *tmp;
+  const char *saved_message_arg;
   bool saved_integral_constant_expression_p;
   bool saved_non_integral_constant_expression_p;
 
@@ -28690,11 +29221,11 @@ cp_parser_sizeof_operand (cp_parser* parser, enum rid keyword)
   /* Types cannot be defined in a `sizeof' expression.  Save away the
      old message.  */
   saved_message = parser->type_definition_forbidden_message;
-  /* And create the new one.  */
-  tmp = concat ("types may not be defined in %<",
-               IDENTIFIER_POINTER (ridpointers[keyword]),
-               "%> expressions", NULL);
-  parser->type_definition_forbidden_message = tmp;
+  saved_message_arg = parser->type_definition_forbidden_message_arg;
+  parser->type_definition_forbidden_message
+    = G_("types may not be defined in %qs expressions");
+  parser->type_definition_forbidden_message_arg
+    = IDENTIFIER_POINTER (ridpointers[keyword]);
 
   /* The restrictions on constant-expressions do not apply inside
      sizeof expressions.  */
@@ -28713,6 +29244,8 @@ cp_parser_sizeof_operand (cp_parser* parser, enum rid keyword)
     {
       tree type = NULL_TREE;
 
+      tentative_firewall firewall (parser);
+
       /* We can't be sure yet whether we're looking at a type-id or an
         expression.  */
       cp_parser_parse_tentatively (parser);
@@ -28740,21 +29273,24 @@ cp_parser_sizeof_operand (cp_parser* parser, enum rid keyword)
       /* If all went well, then we're done.  */
       if (cp_parser_parse_definitely (parser))
        expr = type;
-    }
+      else
+       {
+         /* Commit to the tentative_firewall so we get syntax errors.  */
+         cp_parser_commit_to_tentative_parse (parser);
 
-  /* If the type-id production did not work out, then we must be
-     looking at the unary-expression production.  */
-  if (!expr)
+         expr = cp_parser_unary_expression (parser);
+       }
+    }
+  else
     expr = cp_parser_unary_expression (parser);
 
   /* Go back to evaluating expressions.  */
   --cp_unevaluated_operand;
   --c_inhibit_evaluation_warnings;
 
-  /* Free the message we created.  */
-  free (tmp);
   /* And restore the old one.  */
   parser->type_definition_forbidden_message = saved_message;
+  parser->type_definition_forbidden_message_arg = saved_message_arg;
   parser->integral_constant_expression_p
     = saved_integral_constant_expression_p;
   parser->non_integral_constant_expression_p
@@ -28828,8 +29364,8 @@ cp_parser_set_storage_class (cp_parser *parser,
   decl_specs->storage_class = storage_class;
   set_and_check_decl_spec_loc (decl_specs, ds_storage_class, token);
 
-  /* A storage class specifier cannot be applied alongside a typedef 
-     specifier. If there is a typedef specifier present then set 
+  /* A storage class specifier cannot be applied alongside a typedef
+     specifier. If there is a typedef specifier present then set
      conflicting_specifiers_p which will trigger an error later
      on in grokdeclarator. */
   if (decl_spec_seq_has_spec_p (decl_specs, ds_typedef))
@@ -28847,14 +29383,15 @@ cp_parser_set_decl_spec_type (cp_decl_specifier_seq *decl_specs,
 {
   decl_specs->any_specifiers_p = true;
 
-  /* If the user tries to redeclare bool, char16_t, char32_t, or wchar_t
-     (with, for example, in "typedef int wchar_t;") we remember that
+  /* If the user tries to redeclare bool, char8_t, char16_t, char32_t, or
+     wchar_t (with, for example, in "typedef int wchar_t;") we remember that
      this is what happened.  In system headers, we ignore these
      declarations so that G++ can work with system headers that are not
      C++-safe.  */
   if (decl_spec_seq_has_spec_p (decl_specs, ds_typedef)
       && !type_definition_p
       && (type_spec == boolean_type_node
+         || type_spec == char8_type_node
          || type_spec == char16_type_node
          || type_spec == char32_type_node
          || type_spec == wchar_type_node)
@@ -28935,7 +29472,7 @@ set_and_check_decl_spec_loc (cp_decl_specifier_seq *decl_specs,
            {
              decl_specs->locations[ds_long_long] = location;
              pedwarn_cxx98 (location,
-                            OPT_Wlong_long, 
+                            OPT_Wlong_long,
                             "ISO C++ 1998 does not support %<long long%>");
            }
        }
@@ -28972,7 +29509,8 @@ set_and_check_decl_spec_loc (cp_decl_specifier_seq *decl_specs,
            "typedef",
            "using",
             "constexpr",
-           "__complex"
+           "__complex",
+           "constinit"
          };
          gcc_rich_location richloc (location);
          richloc.add_fixit_remove ();
@@ -29363,7 +29901,7 @@ cp_parser_next_token_ends_template_argument_p (cp_parser *parser)
   cp_token *token;
 
   token = cp_lexer_peek_token (parser->lexer);
-  return (token->type == CPP_COMMA 
+  return (token->type == CPP_COMMA
           || token->type == CPP_GREATER
           || token->type == CPP_ELLIPSIS
          || ((cxx_dialect != cxx98) && token->type == CPP_RSHIFT));
@@ -29652,7 +30190,8 @@ cp_parser_cache_defarg (cp_parser *parser, bool nsdmi)
                                            &ctor_dtor_or_conv_p,
                                            /*parenthesized_p=*/NULL,
                                            /*member_p=*/true,
-                                           /*friend_p=*/false);
+                                           /*friend_p=*/false,
+                                           /*static_p=*/false);
                      peek = cp_lexer_peek_token (parser->lexer);
                      if (cp_parser_error_occurred (parser))
                        break;
@@ -29764,22 +30303,22 @@ cp_parser_cache_defarg (cp_parser *parser, bool nsdmi)
       token = cp_lexer_consume_token (parser->lexer);
     }
 
-  /* Create a DEFAULT_ARG to represent the unparsed default
+  /* Create a DEFERRED_PARSE to represent the unparsed default
      argument.  */
-  default_argument = make_node (DEFAULT_ARG);
-  DEFARG_TOKENS (default_argument)
+  default_argument = make_node (DEFERRED_PARSE);
+  DEFPARSE_TOKENS (default_argument)
     = cp_token_cache_new (first_token, token);
-  DEFARG_INSTANTIATIONS (default_argument) = NULL;
+  DEFPARSE_INSTANTIATIONS (default_argument) = NULL;
 
   return default_argument;
 }
 
-/* A location to use for diagnostics about an unparsed DEFAULT_ARG.  */
+/* A location to use for diagnostics about an unparsed DEFERRED_PARSE.  */
 
 location_t
-defarg_location (tree default_argument)
+defparse_location (tree default_argument)
 {
-  cp_token_cache *tokens = DEFARG_TOKENS (default_argument);
+  cp_token_cache *tokens = DEFPARSE_TOKENS (default_argument);
   location_t start = tokens->first->location;
   location_t end = tokens->last->location;
   return make_location (start, start, end);
@@ -30047,7 +30586,7 @@ cp_parser_objc_message_receiver (cp_parser* parser)
 
   if (cp_parser_parse_definitely (parser))
     return objc_get_class_reference (rcv);
-  
+
   cp_parser_error (parser, "objective-c++ message receiver expected");
   return error_mark_node;
 }
@@ -30148,7 +30687,7 @@ cp_parser_objc_encode_expression (cp_parser* parser)
 
   if (!type)
     {
-      error_at (token->location, 
+      error_at (token->location,
                "%<@encode%> must specify a type as an argument");
       return error_mark_node;
     }
@@ -30171,9 +30710,7 @@ cp_parser_objc_encode_expression (cp_parser* parser)
        @encode(int)
        ^~~~~~~~~~~~
      with caret==start at the @ token, finishing at the close paren.  */
-  location_t combined_loc
-    = make_location (start_loc, start_loc,
-                     cp_lexer_previous_token (parser->lexer)->location);
+  location_t combined_loc = make_location (start_loc, start_loc, parser->lexer);
 
   return cp_expr (objc_build_encode_expr (type), combined_loc);
 }
@@ -30217,9 +30754,7 @@ cp_parser_objc_protocol_expression (cp_parser* parser)
        @protocol(prot)
        ^~~~~~~~~~~~~~~
      with caret==start at the @ token, finishing at the close paren.  */
-  location_t combined_loc
-    = make_location (start_loc, start_loc,
-                     cp_lexer_previous_token (parser->lexer)->location);
+  location_t combined_loc = make_location (start_loc, start_loc, parser->lexer);
   tree result = objc_build_protocol_expr (proto);
   protected_set_expr_location (result, combined_loc);
   return result;
@@ -30304,9 +30839,7 @@ cp_parser_objc_selector_expression (cp_parser* parser)
        @selector(func)
        ^~~~~~~~~~~~~~~
      with caret==start at the @ token, finishing at the close paren.  */
-  location_t combined_loc
-    = make_location (loc, loc,
-                     cp_lexer_previous_token (parser->lexer)->location);
+  location_t combined_loc = make_location (loc, loc, parser->lexer);
   tree result = objc_build_selector_expr (combined_loc, sel_seq);
   /* TODO: objc_build_selector_expr doesn't always honor the location.  */
   protected_set_expr_location (result, combined_loc);
@@ -30330,7 +30863,7 @@ cp_parser_objc_identifier_list (cp_parser* parser)
 
   identifier = cp_parser_identifier (parser);
   if (identifier == error_mark_node)
-    return error_mark_node;      
+    return error_mark_node;
 
   list = build_tree_list (NULL_TREE, identifier);
   sep = cp_lexer_peek_token (parser->lexer);
@@ -30346,7 +30879,7 @@ cp_parser_objc_identifier_list (cp_parser* parser)
                                             identifier));
       sep = cp_lexer_peek_token (parser->lexer);
     }
-  
+
   return list;
 }
 
@@ -30385,11 +30918,11 @@ cp_parser_objc_class_declaration (cp_parser* parser)
   while (true)
     {
       tree id;
-      
+
       id = cp_parser_identifier (parser);
       if (id == error_mark_node)
        break;
-      
+
       objc_declare_class (id);
 
       if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
@@ -30513,7 +31046,7 @@ cp_parser_objc_typename (cp_parser* parser)
       if (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_PAREN))
        {
          cp_type = cp_parser_type_id (parser);
-         
+
          /* If the type could not be parsed, an error has already
             been produced.  For error recovery, behave as if it had
             not been specified, which will use the default type
@@ -30645,7 +31178,7 @@ cp_parser_objc_method_keyword_params (cp_parser* parser, tree* attributes)
       if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON)
          || cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
        return params;
-      cp_parser_error (parser, 
+      cp_parser_error (parser,
                       "method attributes must be specified at the end");
       return error_mark_node;
     }
@@ -30661,7 +31194,7 @@ cp_parser_objc_method_keyword_params (cp_parser* parser, tree* attributes)
 /* Parse the non-keyword Objective-C params.  */
 
 static tree
-cp_parser_objc_method_tail_params_opt (cp_parser* parser, bool *ellipsisp, 
+cp_parser_objc_method_tail_params_opt (cp_parser* parser, bool *ellipsisp,
                                       tree* attributes)
 {
   tree params = make_node (TREE_LIST);
@@ -30706,12 +31239,12 @@ cp_parser_objc_method_tail_params_opt (cp_parser* parser, bool *ellipsisp,
              || cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
            return params;
        }
-      else        
-       /* We have an error, but parse the attributes, so that we can 
+      else
+       /* We have an error, but parse the attributes, so that we can
           carry on.  */
        *attributes = cp_parser_attributes_opt (parser);
 
-      cp_parser_error (parser, 
+      cp_parser_error (parser,
                       "method attributes must be specified at the end");
       return error_mark_node;
     }
@@ -30788,11 +31321,11 @@ cp_parser_objc_method_signature (cp_parser* parser, tree* attributes)
 static bool
 cp_parser_objc_method_maybe_bad_prefix_attributes (cp_parser* parser)
 {
-  tree tattr;  
+  tree tattr;
   cp_lexer_save_tokens (parser->lexer);
   tattr = cp_parser_attributes_opt (parser);
   gcc_assert (tattr) ;
-  
+
   /* If the attributes are followed by a method introducer, this is not allowed.
      Dump the attributes and flag the situation.  */
   if (cp_lexer_next_token_is (parser->lexer, CPP_PLUS)
@@ -30802,7 +31335,7 @@ cp_parser_objc_method_maybe_bad_prefix_attributes (cp_parser* parser)
   /* Otherwise, the attributes introduce some interstitial code, possibly so
      rewind to allow that check.  */
   cp_lexer_rollback_tokens (parser->lexer);
-  return false;  
+  return false;
 }
 
 /* Parse an Objective-C method prototype list.  */
@@ -30834,10 +31367,10 @@ cp_parser_objc_method_prototype_list (cp_parser* parser)
        }
       else if (token->keyword == RID_AT_PROPERTY)
        cp_parser_objc_at_property_declaration (parser);
-      else if (token->keyword == RID_ATTRIBUTE 
+      else if (token->keyword == RID_ATTRIBUTE
               && cp_parser_objc_method_maybe_bad_prefix_attributes(parser))
-       warning_at (cp_lexer_peek_token (parser->lexer)->location, 
-                   OPT_Wattributes, 
+       warning_at (cp_lexer_peek_token (parser->lexer)->location,
+                   OPT_Wattributes,
                    "prefix attributes are ignored for methods");
       else
        /* Allow for interspersed non-ObjC++ code.  */
@@ -30890,7 +31423,7 @@ cp_parser_objc_method_definition_list (cp_parser* parser)
            cp_lexer_consume_token (parser->lexer);
 
          ptk = cp_lexer_peek_token (parser->lexer);
-         if (!(ptk->type == CPP_PLUS || ptk->type == CPP_MINUS 
+         if (!(ptk->type == CPP_PLUS || ptk->type == CPP_MINUS
                || ptk->type == CPP_EOF || ptk->keyword == RID_AT_END))
            {
              perform_deferred_access_checks (tf_warning_or_error);
@@ -30909,7 +31442,7 @@ cp_parser_objc_method_definition_list (cp_parser* parser)
        cp_parser_objc_at_synthesize_declaration (parser);
       else if (token->keyword == RID_AT_DYNAMIC)
        cp_parser_objc_at_dynamic_declaration (parser);
-      else if (token->keyword == RID_ATTRIBUTE 
+      else if (token->keyword == RID_ATTRIBUTE
               && cp_parser_objc_method_maybe_bad_prefix_attributes(parser))
        warning_at (token->location, OPT_Wattributes,
                    "prefix attributes are ignored for methods");
@@ -30941,7 +31474,7 @@ cp_parser_objc_class_ivars (cp_parser* parser)
   cp_lexer_consume_token (parser->lexer);  /* Eat '{'.  */
   token = cp_lexer_peek_token (parser->lexer);
 
-  while (token->type != CPP_CLOSE_BRACE 
+  while (token->type != CPP_CLOSE_BRACE
        && token->keyword != RID_AT_END && token->type != CPP_EOF)
     {
       cp_decl_specifier_seq declspecs;
@@ -30961,7 +31494,7 @@ cp_parser_objc_class_ivars (cp_parser* parser)
       /* auto, register, static, extern, mutable.  */
       if (declspecs.storage_class != sc_none)
        {
-         cp_parser_error (parser, "invalid type for instance variable");         
+         cp_parser_error (parser, "invalid type for instance variable");
          declspecs.storage_class = sc_none;
        }
 
@@ -30971,7 +31504,7 @@ cp_parser_objc_class_ivars (cp_parser* parser)
          cp_parser_error (parser, "invalid type for instance variable");
          declspecs.locations[ds_thread] = 0;
        }
-      
+
       /* typedef.  */
       if (decl_spec_seq_has_spec_p (&declspecs, ds_typedef))
        {
@@ -31019,7 +31552,8 @@ cp_parser_objc_class_ivars (cp_parser* parser)
                                        &ctor_dtor_or_conv_p,
                                        /*parenthesized_p=*/NULL,
                                        /*member_p=*/false,
-                                       /*friend_p=*/false);
+                                       /*friend_p=*/false,
+                                       /*static_p=*/false);
            }
 
          /* Look for attributes that apply to the ivar.  */
@@ -31070,10 +31604,10 @@ cp_parser_objc_class_ivars (cp_parser* parser)
     cp_parser_error (parser, "expected %<}%>");
 
   /* Do not consume the RID_AT_END, so it will be read again as terminating
-     the @interface of @implementation.  */ 
+     the @interface of @implementation.  */
   if (token->keyword != RID_AT_END && token->type != CPP_EOF)
     cp_lexer_consume_token (parser->lexer);  /* Eat '}'.  */
-    
+
   /* For historical reasons, we accept an optional semicolon.  */
   if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
     cp_lexer_consume_token (parser->lexer);
@@ -31105,13 +31639,13 @@ cp_parser_objc_protocol_declaration (cp_parser* parser, tree attributes)
       while (true)
        {
          tree id;
-         
+
          id = cp_parser_identifier (parser);
          if (id == error_mark_node)
            break;
-         
+
          objc_declare_protocol (id, attributes);
-         
+
          if(cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
            cp_lexer_consume_token (parser->lexer);
          else
@@ -31133,7 +31667,7 @@ cp_parser_objc_protocol_declaration (cp_parser* parser, tree attributes)
 /* Parse an Objective-C superclass or category.  */
 
 static void
-cp_parser_objc_superclass_or_category (cp_parser *parser, 
+cp_parser_objc_superclass_or_category (cp_parser *parser,
                                       bool iface_p,
                                       tree *super,
                                       tree *categ, bool *is_class_extension)
@@ -31328,7 +31862,7 @@ cp_parser_objc_declaration (cp_parser* parser, tree attributes)
    Returns NULL_TREE.
 
    PS: This function is identical to c_parser_objc_try_catch_finally_statement
-   for C.  Keep them in sync.  */   
+   for C.  Keep them in sync.  */
 
 static tree
 cp_parser_objc_try_catch_finally_statement (cp_parser *parser)
@@ -31393,7 +31927,7 @@ cp_parser_objc_try_catch_finally_statement (cp_parser *parser)
             going.  */
          if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_PAREN))
            cp_lexer_consume_token (parser->lexer);
-         
+
          /* If these is no immediate closing parenthesis, the user
             probably doesn't know that parenthesis are required at
             all (ie, they typed "@catch NSException *e").  So, just
@@ -31495,9 +32029,9 @@ cp_parser_objc_statement (cp_parser * parser)
   return error_mark_node;
 }
 
-/* If we are compiling ObjC++ and we see an __attribute__ we neeed to 
+/* If we are compiling ObjC++ and we see an __attribute__ we neeed to
    look ahead to see if an objc keyword follows the attributes.  This
-   is to detect the use of prefix attributes on ObjC @interface and 
+   is to detect the use of prefix attributes on ObjC @interface and
    @protocol.  */
 
 static bool
@@ -31512,7 +32046,7 @@ cp_parser_objc_valid_prefix_attributes (cp_parser* parser, tree *attrib)
       return true;
     }
   cp_lexer_rollback_tokens (parser->lexer);
-  return false;  
+  return false;
 }
 
 /* This routine is a minimal replacement for
@@ -31549,14 +32083,14 @@ cp_parser_objc_struct_declaration (cp_parser *parser)
       cp_parser_error (parser, "invalid type for property");
       declspecs.storage_class = sc_none;
     }
-  
+
   /* thread_local.  */
   if (decl_spec_seq_has_spec_p (&declspecs, ds_thread))
     {
       cp_parser_error (parser, "invalid type for property");
       declspecs.locations[ds_thread] = 0;
     }
-  
+
   /* typedef.  */
   if (decl_spec_seq_has_spec_p (&declspecs, ds_typedef))
     {
@@ -31577,7 +32111,7 @@ cp_parser_objc_struct_declaration (cp_parser *parser)
       /* Parse the declarator.  */
       declarator = cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED,
                                         CP_PARSER_FLAGS_NONE,
-                                        NULL, NULL, false, false);
+                                        NULL, NULL, false, false, false);
 
       /* Look for attributes that apply to the ivar.  */
       attributes = cp_parser_attributes_opt (parser);
@@ -31593,7 +32127,7 @@ cp_parser_objc_struct_declaration (cp_parser *parser)
 
       if (decl == error_mark_node || decl == NULL_TREE)
        return error_mark_node;
-      
+
       /* Reset PREFIX_ATTRIBUTES.  */
       if (attributes != error_mark_node)
        {
@@ -31648,7 +32182,7 @@ cp_parser_objc_struct_declaration (cp_parser *parser)
 
    PS: This function is identical to
    c_parser_objc_at_property_declaration for C.  Keep them in sync.  */
-static void 
+static void
 cp_parser_objc_at_property_declaration (cp_parser *parser)
 {
   /* The following variables hold the attributes of the properties as
@@ -31799,7 +32333,7 @@ cp_parser_objc_at_property_declaration (cp_parser *parser)
       /* Comma-separated properties are chained together in
         reverse order; add them one by one.  */
       properties = nreverse (properties);
-      
+
       for (; properties; properties = TREE_CHAIN (properties))
        objc_add_property_declaration (loc, copy_node (properties),
                                       property_readonly, property_readwrite,
@@ -31807,7 +32341,7 @@ cp_parser_objc_at_property_declaration (cp_parser *parser)
                                       property_copy, property_nonatomic,
                                       property_getter_ident, property_setter_ident);
     }
-  
+
   cp_parser_consume_semicolon_at_end_of_statement (parser);
 }
 
@@ -31831,7 +32365,7 @@ cp_parser_objc_at_property_declaration (cp_parser *parser)
   PS: This function is identical to c_parser_objc_at_synthesize_declaration
   for C.  Keep them in sync.
 */
-static void 
+static void
 cp_parser_objc_at_synthesize_declaration (cp_parser *parser)
 {
   tree list = NULL_TREE;
@@ -31882,7 +32416,7 @@ cp_parser_objc_at_synthesize_declaration (cp_parser *parser)
   PS: This function is identical to c_parser_objc_at_dynamic_declaration
   for C.  Keep them in sync.
 */
-static void 
+static void
 cp_parser_objc_at_dynamic_declaration (cp_parser *parser)
 {
   tree list = NULL_TREE;
@@ -31947,6 +32481,10 @@ cp_parser_omp_clause_name (cp_parser *parser)
          else if (!strcmp ("async", p))
            result = PRAGMA_OACC_CLAUSE_ASYNC;
          break;
+       case 'b':
+         if (!strcmp ("bind", p))
+           result = PRAGMA_OMP_CLAUSE_BIND;
+         break;
        case 'c':
          if (!strcmp ("collapse", p))
            result = PRAGMA_OMP_CLAUSE_COLLAPSE;
@@ -31972,6 +32510,8 @@ cp_parser_omp_clause_name (cp_parser *parser)
            result = PRAGMA_OACC_CLAUSE_DEVICEPTR;
          else if (!strcmp ("device_resident", p))
            result = PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT;
+         else if (!strcmp ("device_type", p))
+           result = PRAGMA_OMP_CLAUSE_DEVICE_TYPE;
          else if (!strcmp ("dist_schedule", p))
            result = PRAGMA_OMP_CLAUSE_DIST_SCHEDULE;
          break;
@@ -32046,6 +32586,8 @@ cp_parser_omp_clause_name (cp_parser *parser)
        case 'o':
          if (!strcmp ("ordered", p))
            result = PRAGMA_OMP_CLAUSE_ORDERED;
+         else if (!strcmp ("order", p))
+           result = PRAGMA_OMP_CLAUSE_ORDER;
          break;
        case 'p':
          if (!strcmp ("parallel", p))
@@ -32112,6 +32654,8 @@ cp_parser_omp_clause_name (cp_parser *parser)
            result = PRAGMA_OMP_CLAUSE_UNTIED;
          else if (!strcmp ("use_device", p))
            result = PRAGMA_OACC_CLAUSE_USE_DEVICE;
+         else if (!strcmp ("use_device_addr", p))
+           result = PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR;
          else if (!strcmp ("use_device_ptr", p))
            result = PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR;
          break;
@@ -32142,14 +32686,8 @@ static void
 check_no_duplicate_clause (tree clauses, enum omp_clause_code code,
                           const char *name, location_t location)
 {
-  tree c;
-
-  for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
-    if (OMP_CLAUSE_CODE (c) == code)
-      {
-       error_at (location, "too many %qs clauses", name);
-       break;
-      }
+  if (omp_find_clause (clauses, code))
+    error_at (location, "too many %qs clauses", name);
 }
 
 /* OpenMP 2.5:
@@ -32469,13 +33007,14 @@ cp_parser_oacc_data_clause_deviceptr (cp_parser *parser, tree list)
    seq */
 
 static tree
-cp_parser_oacc_simple_clause (cp_parser * /* parser  */,
-                             enum omp_clause_code code,
-                             tree list, location_t location)
+cp_parser_oacc_simple_clause (location_t loc, enum omp_clause_code code,
+                             tree list)
 {
-  check_no_duplicate_clause (list, code, omp_clause_code_name[code], location);
-  tree c = build_omp_clause (location, code);
+  check_no_duplicate_clause (list, code, omp_clause_code_name[code], loc);
+
+  tree c = build_omp_clause (loc, code);
   OMP_CLAUSE_CHAIN (c) = list;
+
   return c;
 }
 
@@ -32531,13 +33070,13 @@ cp_parser_oacc_single_int_clause (cp_parser *parser, omp_clause_code code,
 */
 
 static tree
-cp_parser_oacc_shape_clause (cp_parser *parser, omp_clause_code kind,
+cp_parser_oacc_shape_clause (cp_parser *parser, location_t loc,
+                            omp_clause_code kind,
                             const char *str, tree list)
 {
   const char *id = "num";
   cp_lexer *lexer = parser->lexer;
   tree ops[2] = { NULL_TREE, NULL_TREE }, c;
-  location_t loc = cp_lexer_peek_token (lexer)->location;
 
   if (kind == OMP_CLAUSE_VECTOR)
     id = "length";
@@ -32664,7 +33203,7 @@ cp_parser_oacc_clause_tile (cp_parser *parser, location_t clause_loc, tree list)
     {
       if (tile && !cp_parser_require (parser, CPP_COMMA, RT_COMMA))
        return list;
-      
+
       if (cp_lexer_next_token_is (parser->lexer, CPP_MULT)
          && (cp_lexer_nth_token_is (parser->lexer, 2, CPP_COMMA)
              || cp_lexer_nth_token_is (parser->lexer, 2, CPP_CLOSE_PAREN)))
@@ -32741,17 +33280,23 @@ cp_parser_oacc_wait_list (cp_parser *parser, location_t clause_loc, tree list)
 }
 
 /* OpenACC:
-   wait ( int-expr-list ) */
+   wait [( int-expr-list )] */
 
 static tree
 cp_parser_oacc_clause_wait (cp_parser *parser, tree list)
 {
   location_t location = cp_lexer_peek_token (parser->lexer)->location;
 
-  if (cp_lexer_peek_token (parser->lexer)->type != CPP_OPEN_PAREN)
-    return list;
+  if (cp_lexer_peek_token (parser->lexer)->type == CPP_OPEN_PAREN)
+    list = cp_parser_oacc_wait_list (parser, location, list);
+  else
+    {
+      tree c = build_omp_clause (location, OMP_CLAUSE_WAIT);
 
-  list = cp_parser_oacc_wait_list (parser, location, list);
+      OMP_CLAUSE_DECL (c) = build_int_cst (integer_type_node, GOMP_ASYNC_NOVAL);
+      OMP_CLAUSE_CHAIN (c) = list;
+      list = c;
+    }
 
   return list;
 }
@@ -33032,8 +33577,8 @@ cp_parser_omp_clause_if (cp_parser *parser, tree list, location_t location,
              case OMP_TARGET_DATA: p = "target data"; break;
              case OMP_TARGET: p = "target"; break;
              case OMP_TARGET_UPDATE: p = "target update"; break;
-             case OMP_TARGET_ENTER_DATA: p = "enter data"; break;
-             case OMP_TARGET_EXIT_DATA: p = "exit data"; break;
+             case OMP_TARGET_ENTER_DATA: p = "target enter data"; break;
+             case OMP_TARGET_EXIT_DATA: p = "target exit data"; break;
              default: gcc_unreachable ();
              }
            error_at (location, "too many %<if%> clauses with %qs modifier",
@@ -33430,6 +33975,100 @@ cp_parser_omp_clause_defaultmap (cp_parser *parser, tree list,
   return list;
 }
 
+/* OpenMP 5.0:
+   order ( concurrent ) */
+
+static tree
+cp_parser_omp_clause_order (cp_parser *parser, tree list, location_t location)
+{
+  tree c, id;
+  const char *p;
+
+  matching_parens parens;
+  if (!parens.require_open (parser))
+    return list;
+
+  if (!cp_lexer_next_token_is (parser->lexer, CPP_NAME))
+    {
+      cp_parser_error (parser, "expected %<concurrent%>");
+      goto out_err;
+    }
+  else
+    {
+      id = cp_lexer_peek_token (parser->lexer)->u.value;
+      p = IDENTIFIER_POINTER (id);
+    }
+  if (strcmp (p, "concurrent") != 0)
+    {
+      cp_parser_error (parser, "expected %<concurrent%>");
+      goto out_err;
+    }
+  cp_lexer_consume_token (parser->lexer);
+  if (!parens.require_close (parser))
+    goto out_err;
+
+  /* check_no_duplicate_clause (list, OMP_CLAUSE_ORDER, "order", location); */
+  c = build_omp_clause (location, OMP_CLAUSE_ORDER);
+  OMP_CLAUSE_CHAIN (c) = list;
+  return c;
+
+ out_err:
+  cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
+                                        /*or_comma=*/false,
+                                        /*consume_paren=*/true);
+  return list;
+}
+
+/* OpenMP 5.0:
+   bind ( teams | parallel | thread ) */
+
+static tree
+cp_parser_omp_clause_bind (cp_parser *parser, tree list,
+                          location_t location)
+{
+  tree c;
+  const char *p;
+  enum omp_clause_bind_kind kind = OMP_CLAUSE_BIND_THREAD;
+
+  matching_parens parens;
+  if (!parens.require_open (parser))
+    return list;
+
+  if (!cp_lexer_next_token_is (parser->lexer, CPP_NAME))
+    {
+    invalid:
+      cp_parser_error (parser,
+                      "expected %<teams%>, %<parallel%> or %<thread%>");
+      goto out_err;
+    }
+  else
+    {
+      tree id = cp_lexer_peek_token (parser->lexer)->u.value;
+      p = IDENTIFIER_POINTER (id);
+    }
+  if (strcmp (p, "teams") == 0)
+    kind = OMP_CLAUSE_BIND_TEAMS;
+  else if (strcmp (p, "parallel") == 0)
+    kind = OMP_CLAUSE_BIND_PARALLEL;
+  else if (strcmp (p, "thread") != 0)
+    goto invalid;
+  cp_lexer_consume_token (parser->lexer);
+  if (!parens.require_close (parser))
+    goto out_err;
+
+  /* check_no_duplicate_clause (list, OMP_CLAUSE_BIND, "bind", location); */
+  c = build_omp_clause (location, OMP_CLAUSE_BIND);
+  OMP_CLAUSE_BIND_KIND (c) = kind;
+  OMP_CLAUSE_CHAIN (c) = list;
+  return c;
+
+ out_err:
+  cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
+                                        /*or_comma=*/false,
+                                        /*consume_paren=*/true);
+  return list;
+}
+
 /* OpenMP 2.5:
    ordered
 
@@ -33529,11 +34168,7 @@ cp_parser_omp_clause_reduction (cp_parser *parser, enum omp_clause_code kind,
          if (strcmp (p, "task") == 0)
            task = true;
          else if (strcmp (p, "inscan") == 0)
-           {
-             inscan = true;
-             sorry ("%<inscan%> modifier on %<reduction%> clause "
-                    "not supported yet");
-           }
+           inscan = true;
          if (task || inscan)
            {
              cp_lexer_consume_token (parser->lexer);
@@ -33987,7 +34622,7 @@ cp_parser_omp_clause_lastprivate (cp_parser *parser, tree list)
    linear ( modifier ( variable-list ) : expression ) */
 
 static tree
-cp_parser_omp_clause_linear (cp_parser *parser, tree list, 
+cp_parser_omp_clause_linear (cp_parser *parser, tree list,
                             bool declare_simd)
 {
   tree nlist, c, step = integer_one_node;
@@ -34619,8 +35254,10 @@ cp_parser_omp_clause_dist_schedule (cp_parser *parser, tree list,
   else if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_COMMA_CLOSE_PAREN))
     goto resync_fail;
 
-  check_no_duplicate_clause (list, OMP_CLAUSE_DIST_SCHEDULE, "dist_schedule",
-                            location);
+  /* check_no_duplicate_clause (list, OMP_CLAUSE_DIST_SCHEDULE,
+                               "dist_schedule", location); */
+  if (omp_find_clause (list, OMP_CLAUSE_DIST_SCHEDULE))
+    warning_at (location, 0, "too many %qs clauses", "dist_schedule");
   OMP_CLAUSE_CHAIN (c) = list;
   return c;
 
@@ -34686,6 +35323,56 @@ cp_parser_omp_clause_proc_bind (cp_parser *parser, tree list,
   return list;
 }
 
+/* OpenMP 5.0:
+   device_type ( host | nohost | any )  */
+
+static tree
+cp_parser_omp_clause_device_type (cp_parser *parser, tree list,
+                                 location_t location)
+{
+  tree c;
+  enum omp_clause_device_type_kind kind;
+
+  if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
+    return list;
+
+  if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
+    {
+      tree id = cp_lexer_peek_token (parser->lexer)->u.value;
+      const char *p = IDENTIFIER_POINTER (id);
+
+      if (strcmp ("host", p) == 0)
+       kind = OMP_CLAUSE_DEVICE_TYPE_HOST;
+      else if (strcmp ("nohost", p) == 0)
+       kind = OMP_CLAUSE_DEVICE_TYPE_NOHOST;
+      else if (strcmp ("any", p) == 0)
+       kind = OMP_CLAUSE_DEVICE_TYPE_ANY;
+      else
+       goto invalid_kind;
+    }
+  else
+    goto invalid_kind;
+
+  cp_lexer_consume_token (parser->lexer);
+  if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_COMMA_CLOSE_PAREN))
+    goto resync_fail;
+
+  c = build_omp_clause (location, OMP_CLAUSE_DEVICE_TYPE);
+  /* check_no_duplicate_clause (list, OMP_CLAUSE_DEVICE_TYPE, "device_type",
+                               location);  */
+  OMP_CLAUSE_DEVICE_TYPE_KIND (c) = kind;
+  OMP_CLAUSE_CHAIN (c) = list;
+  return c;
+
+ invalid_kind:
+  cp_parser_error (parser, "invalid depend kind");
+ resync_fail:
+  cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
+                                        /*or_comma=*/false,
+                                        /*consume_paren=*/true);
+  return list;
+}
+
 /* OpenACC:
    async [( int-expr )] */
 
@@ -34752,8 +35439,8 @@ cp_parser_oacc_all_clauses (cp_parser *parser, omp_clause_mask mask,
          c_name = "async";
          break;
        case PRAGMA_OACC_CLAUSE_AUTO:
-         clauses = cp_parser_oacc_simple_clause (parser, OMP_CLAUSE_AUTO,
-                                                clauses, here);
+         clauses = cp_parser_oacc_simple_clause (here, OMP_CLAUSE_AUTO,
+                                                 clauses);
          c_name = "auto";
          break;
        case PRAGMA_OACC_CLAUSE_COLLAPSE:
@@ -34797,8 +35484,8 @@ cp_parser_oacc_all_clauses (cp_parser *parser, omp_clause_mask mask,
          c_name = "device_resident";
          break;
        case PRAGMA_OACC_CLAUSE_FINALIZE:
-         clauses = cp_parser_oacc_simple_clause (parser, OMP_CLAUSE_FINALIZE,
-                                                 clauses, here);
+         clauses = cp_parser_oacc_simple_clause (here, OMP_CLAUSE_FINALIZE,
+                                                 clauses);
          c_name = "finalize";
          break;
        case PRAGMA_OACC_CLAUSE_FIRSTPRIVATE:
@@ -34808,7 +35495,7 @@ cp_parser_oacc_all_clauses (cp_parser *parser, omp_clause_mask mask,
          break;
        case PRAGMA_OACC_CLAUSE_GANG:
          c_name = "gang";
-         clauses = cp_parser_oacc_shape_clause (parser, OMP_CLAUSE_GANG,
+         clauses = cp_parser_oacc_shape_clause (parser, here, OMP_CLAUSE_GANG,
                                                 c_name, clauses);
          break;
        case PRAGMA_OACC_CLAUSE_HOST:
@@ -34820,15 +35507,13 @@ cp_parser_oacc_all_clauses (cp_parser *parser, omp_clause_mask mask,
          c_name = "if";
          break;
        case PRAGMA_OACC_CLAUSE_IF_PRESENT:
-         clauses = cp_parser_oacc_simple_clause (parser,
-                                                 OMP_CLAUSE_IF_PRESENT,
-                                                 clauses, here);
+         clauses = cp_parser_oacc_simple_clause (here, OMP_CLAUSE_IF_PRESENT,
+                                                 clauses);
          c_name = "if_present";
          break;
        case PRAGMA_OACC_CLAUSE_INDEPENDENT:
-         clauses = cp_parser_oacc_simple_clause (parser,
-                                                 OMP_CLAUSE_INDEPENDENT,
-                                                 clauses, here);
+         clauses = cp_parser_oacc_simple_clause (here, OMP_CLAUSE_INDEPENDENT,
+                                                 clauses);
          c_name = "independent";
          break;
        case PRAGMA_OACC_CLAUSE_LINK:
@@ -34863,8 +35548,8 @@ cp_parser_oacc_all_clauses (cp_parser *parser, omp_clause_mask mask,
          c_name = "reduction";
          break;
        case PRAGMA_OACC_CLAUSE_SEQ:
-         clauses = cp_parser_oacc_simple_clause (parser, OMP_CLAUSE_SEQ,
-                                                clauses, here);
+         clauses = cp_parser_oacc_simple_clause (here, OMP_CLAUSE_SEQ,
+                                                 clauses);
          c_name = "seq";
          break;
        case PRAGMA_OACC_CLAUSE_TILE:
@@ -34878,7 +35563,8 @@ cp_parser_oacc_all_clauses (cp_parser *parser, omp_clause_mask mask,
          break;
        case PRAGMA_OACC_CLAUSE_VECTOR:
          c_name = "vector";
-         clauses = cp_parser_oacc_shape_clause (parser, OMP_CLAUSE_VECTOR,
+         clauses = cp_parser_oacc_shape_clause (parser, here,
+                                                OMP_CLAUSE_VECTOR,
                                                 c_name, clauses);
          break;
        case PRAGMA_OACC_CLAUSE_VECTOR_LENGTH:
@@ -34893,7 +35579,8 @@ cp_parser_oacc_all_clauses (cp_parser *parser, omp_clause_mask mask,
          break;
        case PRAGMA_OACC_CLAUSE_WORKER:
          c_name = "worker";
-         clauses = cp_parser_oacc_shape_clause (parser, OMP_CLAUSE_WORKER,
+         clauses = cp_parser_oacc_shape_clause (parser, here,
+                                                OMP_CLAUSE_WORKER,
                                                 c_name, clauses);
          break;
        default:
@@ -34951,6 +35638,11 @@ cp_parser_omp_all_clauses (cp_parser *parser, omp_clause_mask mask,
 
       switch (c_kind)
        {
+       case PRAGMA_OMP_CLAUSE_BIND:
+         clauses = cp_parser_omp_clause_bind (parser, clauses,
+                                              token->location);
+         c_name = "bind";
+         break;
        case PRAGMA_OMP_CLAUSE_COLLAPSE:
          clauses = cp_parser_omp_clause_collapse (parser, clauses,
                                                   token->location);
@@ -34999,6 +35691,11 @@ cp_parser_omp_all_clauses (cp_parser *parser, omp_clause_mask mask,
                                            clauses);
          c_name = "use_device_ptr";
          break;
+       case PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR:
+         clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_USE_DEVICE_ADDR,
+                                           clauses);
+         c_name = "use_device_addr";
+         break;
        case PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR:
          clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_IS_DEVICE_PTR,
                                            clauses);
@@ -35025,7 +35722,8 @@ cp_parser_omp_all_clauses (cp_parser *parser, omp_clause_mask mask,
          c_name = "mergeable";
          break;
        case PRAGMA_OMP_CLAUSE_NOWAIT:
-         clauses = cp_parser_omp_clause_nowait (parser, clauses, token->location);
+         clauses = cp_parser_omp_clause_nowait (parser, clauses,
+                                                token->location);
          c_name = "nowait";
          break;
        case PRAGMA_OMP_CLAUSE_NUM_TASKS:
@@ -35038,6 +35736,11 @@ cp_parser_omp_all_clauses (cp_parser *parser, omp_clause_mask mask,
                                                      token->location);
          c_name = "num_threads";
          break;
+       case PRAGMA_OMP_CLAUSE_ORDER:
+         clauses = cp_parser_omp_clause_order (parser, clauses,
+                                               token->location);
+         c_name = "order";
+         break;
        case PRAGMA_OMP_CLAUSE_ORDERED:
          clauses = cp_parser_omp_clause_ordered (parser, clauses,
                                                  token->location);
@@ -35198,6 +35901,11 @@ cp_parser_omp_all_clauses (cp_parser *parser, omp_clause_mask mask,
                                                    token->location);
          c_name = "proc_bind";
          break;
+       case PRAGMA_OMP_CLAUSE_DEVICE_TYPE:
+         clauses = cp_parser_omp_clause_device_type (parser, clauses,
+                                                     token->location);
+         c_name = "device_type";
+         break;
        case PRAGMA_OMP_CLAUSE_SAFELEN:
          clauses = cp_parser_omp_clause_safelen (parser, clauses,
                                                  token->location);
@@ -36056,7 +36764,7 @@ cp_parser_omp_for_cond (cp_parser *parser, tree decl, enum tree_code code)
          || CLASS_TYPE_P (TREE_TYPE (decl))))
     return cond;
 
-  return build_x_binary_op (cp_expr_loc_or_loc (cond, input_location),
+  return build_x_binary_op (cp_expr_loc_or_input_loc (cond),
                            TREE_CODE (cond),
                            TREE_OPERAND (cond, 0), ERROR_MARK,
                            TREE_OPERAND (cond, 1), ERROR_MARK,
@@ -36168,7 +36876,7 @@ cp_parser_omp_for_incr (cp_parser *parser, tree decl)
 static tree
 cp_parser_omp_for_loop_init (cp_parser *parser,
                             tree &this_pre_body,
-                            vec<tree, va_gc> *&for_block,
+                            releasing_vec &for_block,
                             tree &init,
                             tree &orig_init,
                             tree &decl,
@@ -36210,14 +36918,15 @@ cp_parser_omp_for_loop_init (cp_parser *parser,
                                         /*ctor_dtor_or_conv_p=*/NULL,
                                         /*parenthesized_p=*/NULL,
                                         /*member_p=*/false,
-                                        /*friend_p=*/false);
+                                        /*friend_p=*/false,
+                                        /*static_p=*/false);
       attributes = cp_parser_attributes_opt (parser);
       asm_specification = cp_parser_asm_specification_opt (parser);
 
-      if (declarator == cp_error_declarator) 
+      if (declarator == cp_error_declarator)
        cp_parser_skip_to_end_of_statement (parser);
 
-      else 
+      else
        {
          tree pushed_scope, auto_node;
 
@@ -36229,7 +36938,7 @@ cp_parser_omp_for_loop_init (cp_parser *parser,
          auto_node = type_uses_auto (TREE_TYPE (decl));
          if (cp_lexer_next_token_is_not (parser->lexer, CPP_EQ))
            {
-             if (cp_lexer_next_token_is (parser->lexer, 
+             if (cp_lexer_next_token_is (parser->lexer,
                                          CPP_OPEN_PAREN))
                error ("parenthesized initialization is not allowed in "
                       "OpenMP %<for%> loop");
@@ -36260,7 +36969,7 @@ cp_parser_omp_for_loop_init (cp_parser *parser,
                      && !type_dependent_expression_p (decl))
                    goto non_class;
                }
-                     
+
              cp_finish_decl (decl, init, !is_non_constant_init,
                              asm_specification,
                              LOOKUP_ONLYCONVERTING);
@@ -36320,7 +37029,7 @@ cp_parser_omp_for_loop_init (cp_parser *parser,
            pop_scope (pushed_scope);
        }
     }
-  else 
+  else
     {
       cp_id_kind idk;
       /* If parsing a type specifier sequence failed, then
@@ -36575,6 +37284,63 @@ cp_finish_omp_range_for (tree orig, tree begin)
     cp_finish_decomp (decl, decomp_first_name, decomp_cnt);
 }
 
+/* OpenMP 5.0:
+
+   scan-loop-body:
+     { structured-block scan-directive structured-block }  */
+
+static void
+cp_parser_omp_scan_loop_body (cp_parser *parser)
+{
+  tree substmt, clauses = NULL_TREE;
+
+  matching_braces braces;
+  if (!braces.require_open (parser))
+    return;
+
+  substmt = cp_parser_omp_structured_block (parser, NULL);
+  substmt = build2 (OMP_SCAN, void_type_node, substmt, NULL_TREE);
+  add_stmt (substmt);
+
+  cp_token *tok = cp_lexer_peek_token (parser->lexer);
+  if (cp_parser_pragma_kind (tok) == PRAGMA_OMP_SCAN)
+    {
+      enum omp_clause_code clause = OMP_CLAUSE_ERROR;
+
+      cp_lexer_consume_token (parser->lexer);
+
+      if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
+       {
+         tree id = cp_lexer_peek_token (parser->lexer)->u.value;
+         const char *p = IDENTIFIER_POINTER (id);
+         if (strcmp (p, "inclusive") == 0)
+           clause = OMP_CLAUSE_INCLUSIVE;
+         else if (strcmp (p, "exclusive") == 0)
+           clause = OMP_CLAUSE_EXCLUSIVE;
+       }
+      if (clause != OMP_CLAUSE_ERROR)
+       {
+         cp_lexer_consume_token (parser->lexer);
+         clauses = cp_parser_omp_var_list (parser, clause, NULL_TREE);
+       }
+      else
+       cp_parser_error (parser, "expected %<inclusive%> or "
+                                "%<exclusive%> clause");
+
+      cp_parser_require_pragma_eol (parser, tok);
+    }
+  else
+    error ("expected %<#pragma omp scan%>");
+
+  clauses = finish_omp_clauses (clauses, C_ORT_OMP);
+  substmt = cp_parser_omp_structured_block (parser, NULL);
+  substmt = build2_loc (tok->location, OMP_SCAN, void_type_node, substmt,
+                       clauses);
+  add_stmt (substmt);
+
+  braces.require_close (parser);
+}
+
 /* Parse the restricted form of the for statement allowed by OpenMP.  */
 
 static tree
@@ -36588,9 +37354,10 @@ cp_parser_omp_for_loop (cp_parser *parser, enum tree_code code, tree clauses,
   location_t loc_first;
   bool collapse_err = false;
   int i, collapse = 1, ordered = 0, count, nbraces = 0;
-  vec<tree, va_gc> *for_block = make_tree_vector ();
+  releasing_vec for_block;
   auto_vec<tree, 4> orig_inits;
   bool tiling = false;
+  bool inscan = false;
 
   for (cl = clauses; cl; cl = OMP_CLAUSE_CHAIN (cl))
     if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_COLLAPSE)
@@ -36606,6 +37373,10 @@ cp_parser_omp_for_loop (cp_parser *parser, enum tree_code code, tree clauses,
        ordered_cl = cl;
        ordered = tree_to_shwi (OMP_CLAUSE_ORDERED_EXPR (cl));
       }
+    else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_REDUCTION
+            && OMP_CLAUSE_REDUCTION_INSCAN (cl)
+            && (code == OMP_SIMD || code == OMP_FOR))
+      inscan = true;
 
   if (ordered && ordered < collapse)
     {
@@ -36751,7 +37522,8 @@ cp_parser_omp_for_loop (cp_parser *parser, enum tree_code code, tree clauses,
        real_decl = decl;
       if (cclauses != NULL
          && cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL] != NULL
-         && real_decl != NULL_TREE)
+         && real_decl != NULL_TREE
+         && code != OMP_LOOP)
        {
          tree *c;
          for (c = &cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL]; *c ; )
@@ -36811,12 +37583,12 @@ cp_parser_omp_for_loop (cp_parser *parser, enum tree_code code, tree clauses,
            }
          if (c == NULL)
            {
-             if (code != OMP_SIMD)
+             if ((code == OMP_SIMD && collapse != 1) || code == OMP_LOOP)
+               c = build_omp_clause (loc, OMP_CLAUSE_LASTPRIVATE);
+             else if (code != OMP_SIMD)
                c = build_omp_clause (loc, OMP_CLAUSE_PRIVATE);
-             else if (collapse == 1)
-               c = build_omp_clause (loc, OMP_CLAUSE_LINEAR);
              else
-               c = build_omp_clause (loc, OMP_CLAUSE_LASTPRIVATE);
+               c = build_omp_clause (loc, OMP_CLAUSE_LINEAR);
              OMP_CLAUSE_DECL (c) = add_private_clause;
              c = finish_omp_clauses (c, C_ORT_OMP);
              if (c)
@@ -36934,7 +37706,10 @@ cp_parser_omp_for_loop (cp_parser *parser, enum tree_code code, tree clauses,
     }
   else
     body = push_stmt_list ();
-  cp_parser_statement (parser, NULL_TREE, false, if_p);
+  if (inscan)
+    cp_parser_omp_scan_loop_body (parser);
+  else
+    cp_parser_statement (parser, NULL_TREE, false, if_p);
   if (orig_declv)
     body = finish_omp_structured_block (body);
   else
@@ -36977,7 +37752,6 @@ cp_parser_omp_for_loop (cp_parser *parser, enum tree_code code, tree clauses,
       else
        add_stmt (t);
     }
-  release_tree_vector (for_block);
 
   return ret;
 }
@@ -36996,6 +37770,50 @@ cp_omp_split_clauses (location_t loc, enum tree_code code,
       cclauses[i] = finish_omp_clauses (cclauses[i], C_ORT_OMP);
 }
 
+/* OpenMP 5.0:
+   #pragma omp loop loop-clause[optseq] new-line
+     for-loop  */
+
+#define OMP_LOOP_CLAUSE_MASK                                   \
+       ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE)      \
+       | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE)  \
+       | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION)    \
+       | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE)     \
+       | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_BIND)         \
+       | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
+
+static tree
+cp_parser_omp_loop (cp_parser *parser, cp_token *pragma_tok,
+                   char *p_name, omp_clause_mask mask, tree *cclauses,
+                   bool *if_p)
+{
+  tree clauses, sb, ret;
+  unsigned int save;
+  location_t loc = cp_lexer_peek_token (parser->lexer)->location;
+
+  strcat (p_name, " loop");
+  mask |= OMP_LOOP_CLAUSE_MASK;
+
+  clauses = cp_parser_omp_all_clauses (parser, mask, p_name, pragma_tok,
+                                      cclauses == NULL);
+  if (cclauses)
+    {
+      cp_omp_split_clauses (loc, OMP_LOOP, mask, clauses, cclauses);
+      clauses = cclauses[C_OMP_CLAUSE_SPLIT_LOOP];
+    }
+
+  keep_next_level (true);
+  sb = begin_omp_structured_block ();
+  save = cp_parser_begin_omp_structured_block (parser);
+
+  ret = cp_parser_omp_for_loop (parser, OMP_LOOP, clauses, cclauses, if_p);
+
+  cp_parser_end_omp_structured_block (parser, save);
+  add_stmt (finish_omp_for_block (finish_omp_structured_block (sb), ret));
+
+  return ret;
+}
+
 /* OpenMP 4.0:
    #pragma omp simd simd-clause[optseq] new-line
      for-loop  */
@@ -37010,7 +37828,8 @@ cp_omp_split_clauses (location_t loc, enum tree_code code,
        | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION)    \
        | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE)     \
        | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF)           \
-       | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NONTEMPORAL))
+       | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NONTEMPORAL)  \
+       | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
 
 static tree
 cp_parser_omp_simd (cp_parser *parser, cp_token *pragma_tok,
@@ -37070,7 +37889,8 @@ cp_parser_omp_simd (cp_parser *parser, cp_token *pragma_tok,
        | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED)      \
        | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE)     \
        | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT)       \
-       | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE))
+       | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE)     \
+       | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
 
 static tree
 cp_parser_omp_for (cp_parser *parser, cp_token *pragma_tok,
@@ -37454,11 +38274,11 @@ cp_parser_omp_parallel (cp_parser *parser, cp_token *pragma_tok,
       cp_parser_skip_to_pragma_eol (parser, pragma_tok);
       return NULL_TREE;
     }
-  else if (cclauses == NULL && cp_lexer_next_token_is (parser->lexer, CPP_NAME))
+  else if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
     {
       tree id = cp_lexer_peek_token (parser->lexer)->u.value;
       const char *p = IDENTIFIER_POINTER (id);
-      if (strcmp (p, "master") == 0)
+      if (cclauses == NULL && strcmp (p, "master") == 0)
        {
          tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
          cclauses = cclauses_buf;
@@ -37476,12 +38296,34 @@ cp_parser_omp_parallel (cp_parser *parser, cp_token *pragma_tok,
            return ret;
          return stmt;
        }
+      else if (strcmp (p, "loop") == 0)
+       {
+         tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
+         if (cclauses == NULL)
+           cclauses = cclauses_buf;
+
+         cp_lexer_consume_token (parser->lexer);
+         if (!flag_openmp)  /* flag_openmp_simd  */
+           return cp_parser_omp_loop (parser, pragma_tok, p_name, mask,
+                                      cclauses, if_p);
+         block = begin_omp_parallel ();
+         save = cp_parser_begin_omp_structured_block (parser);
+         tree ret = cp_parser_omp_loop (parser, pragma_tok, p_name, mask,
+                                        cclauses, if_p);
+         cp_parser_end_omp_structured_block (parser, save);
+         stmt = finish_omp_parallel (cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
+                                     block);
+         if (ret == NULL_TREE)
+           return ret;
+         OMP_PARALLEL_COMBINED (stmt) = 1;
+         return stmt;
+       }
       else if (!flag_openmp)  /* flag_openmp_simd  */
        {
          cp_parser_skip_to_pragma_eol (parser, pragma_tok);
          return NULL_TREE;
        }
-      else if (strcmp (p, "sections") == 0)
+      else if (cclauses == NULL && strcmp (p, "sections") == 0)
        {
          tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
          cclauses = cclauses_buf;
@@ -37876,6 +38718,34 @@ cp_parser_omp_teams (cp_parser *parser, cp_token *pragma_tok,
          SET_EXPR_LOCATION (ret, loc);
          return add_stmt (ret);
        }
+      else if (strcmp (p, "loop") == 0)
+       {
+         tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
+         if (cclauses == NULL)
+           cclauses = cclauses_buf;
+
+         cp_lexer_consume_token (parser->lexer);
+         if (!flag_openmp)  /* flag_openmp_simd  */
+           return cp_parser_omp_loop (parser, pragma_tok, p_name, mask,
+                                      cclauses, if_p);
+         keep_next_level (true);
+         sb = begin_omp_structured_block ();
+         save = cp_parser_begin_omp_structured_block (parser);
+         ret = cp_parser_omp_loop (parser, pragma_tok, p_name, mask,
+                                   cclauses, if_p);
+         cp_parser_end_omp_structured_block (parser, save);
+         tree body = finish_omp_structured_block (sb);
+         if (ret == NULL)
+           return ret;
+         clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
+         ret = make_node (OMP_TEAMS);
+         TREE_TYPE (ret) = void_type_node;
+         OMP_TEAMS_CLAUSES (ret) = clauses;
+         OMP_TEAMS_BODY (ret) = body;
+         OMP_TEAMS_COMBINED (ret) = 1;
+         SET_EXPR_LOCATION (ret, loc);
+         return add_stmt (ret);
+       }
     }
   if (!flag_openmp)  /* flag_openmp_simd  */
     {
@@ -37909,7 +38779,8 @@ cp_parser_omp_teams (cp_parser *parser, cp_token *pragma_tok,
        ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE)       \
        | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)          \
        | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF)           \
-       | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR))
+       | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR) \
+       | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR))
 
 static tree
 cp_parser_omp_target_data (cp_parser *parser, cp_token *pragma_tok, bool *if_p)
@@ -37945,7 +38816,8 @@ cp_parser_omp_target_data (cp_parser *parser, cp_token *pragma_tok, bool *if_p)
            *pc = OMP_CLAUSE_CHAIN (*pc);
            continue;
          }
-      else if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_PTR)
+      else if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_PTR
+              || OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_ADDR)
        map_seen = 3;
       pc = &OMP_CLAUSE_CHAIN (*pc);
     }
@@ -37955,7 +38827,8 @@ cp_parser_omp_target_data (cp_parser *parser, cp_token *pragma_tok, bool *if_p)
       if (map_seen == 0)
        error_at (pragma_tok->location,
                  "%<#pragma omp target data%> must contain at least "
-                 "one %<map%> or %<use_device_ptr%> clause");
+                 "one %<map%>, %<use_device_ptr%> or %<use_device_addr%> "
+                 "clause");
       return NULL_TREE;
     }
 
@@ -39015,12 +39888,15 @@ cp_parser_late_parsing_omp_declare_simd (cp_parser *parser, tree attrs)
 
 #define OMP_DECLARE_TARGET_CLAUSE_MASK                         \
        ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO)           \
-       | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK))
+       | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK)         \
+       | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE_TYPE))
 
 static void
 cp_parser_omp_declare_target (cp_parser *parser, cp_token *pragma_tok)
 {
   tree clauses = NULL_TREE;
+  int device_type = 0;
+  bool only_device_type = true;
   if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
     clauses
       = cp_parser_omp_all_clauses (parser, OMP_DECLARE_TARGET_CLAUSE_MASK,
@@ -39038,17 +39914,18 @@ cp_parser_omp_declare_target (cp_parser *parser, cp_token *pragma_tok)
       scope_chain->omp_declare_target_attribute++;
       return;
     }
-  if (scope_chain->omp_declare_target_attribute)
-    error_at (pragma_tok->location,
-             "%<#pragma omp declare target%> with clauses in between "
-             "%<#pragma omp declare target%> without clauses and "
-             "%<#pragma omp end declare target%>");
+  for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
+    if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE)
+      device_type |= OMP_CLAUSE_DEVICE_TYPE_KIND (c);
   for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
     {
+      if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE)
+       continue;
       tree t = OMP_CLAUSE_DECL (c), id;
       tree at1 = lookup_attribute ("omp declare target", DECL_ATTRIBUTES (t));
       tree at2 = lookup_attribute ("omp declare target link",
                                   DECL_ATTRIBUTES (t));
+      only_device_type = false;
       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINK)
        {
          id = get_identifier ("omp declare target link");
@@ -39081,7 +39958,34 @@ cp_parser_omp_declare_target (cp_parser *parser, cp_token *pragma_tok)
                }
            }
        }
+      if (TREE_CODE (t) != FUNCTION_DECL)
+       continue;
+      if ((device_type & OMP_CLAUSE_DEVICE_TYPE_HOST) != 0)
+       {
+         tree at3 = lookup_attribute ("omp declare target host",
+                                      DECL_ATTRIBUTES (t));
+         if (at3 == NULL_TREE)
+           {
+             id = get_identifier ("omp declare target host");
+             DECL_ATTRIBUTES (t)
+               = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
+           }
+       }
+      if ((device_type & OMP_CLAUSE_DEVICE_TYPE_NOHOST) != 0)
+       {
+         tree at3 = lookup_attribute ("omp declare target nohost",
+                                      DECL_ATTRIBUTES (t));
+         if (at3 == NULL_TREE)
+           {
+             id = get_identifier ("omp declare target nohost");
+             DECL_ATTRIBUTES (t)
+               = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
+           }
+       }
     }
+  if (device_type && only_device_type)
+    warning_at (OMP_CLAUSE_LOCATION (clauses), 0,
+               "directive with only %<device_type%> clauses ignored");
 }
 
 static void
@@ -39305,7 +40209,7 @@ cp_parser_omp_declare_reduction (cp_parser *parser, cp_token *pragma_tok,
   cp_token_cache *cp;
   int errs;
   void *p;
-    
+
   /* Get the high-water mark for the DECLARATOR_OBSTACK.  */
   p = obstack_alloc (&declarator_obstack, 0);
 
@@ -39383,8 +40287,7 @@ cp_parser_omp_declare_reduction (cp_parser *parser, cp_token *pragma_tok,
                           || id_equal (orig_reduc_id, "max")))))
        error_at (loc, "predeclared arithmetic type %qT in "
                       "%<#pragma omp declare reduction%>", type);
-      else if (TREE_CODE (type) == FUNCTION_TYPE
-              || TREE_CODE (type) == METHOD_TYPE
+      else if (FUNC_OR_METHOD_TYPE_P (type)
               || TREE_CODE (type) == ARRAY_TYPE)
        error_at (loc, "function or array type %qT in "
                       "%<#pragma omp declare reduction%>", type);
@@ -39392,8 +40295,8 @@ cp_parser_omp_declare_reduction (cp_parser *parser, cp_token *pragma_tok,
        error_at (loc, "reference type %qT in "
                       "%<#pragma omp declare reduction%>", type);
       else if (TYPE_QUALS_NO_ADDR_SPACE (type))
-       error_at (loc, "const, volatile or __restrict qualified type %qT in "
-                      "%<#pragma omp declare reduction%>", type);
+       error_at (loc, "%<const%>, %<volatile%> or %<__restrict%>-qualified "
+                 "type %qT in %<#pragma omp declare reduction%>", type);
       else
        types.safe_push (type);
 
@@ -39891,6 +40794,9 @@ cp_parser_oacc_routine (cp_parser *parser, cp_token *pragma_tok,
        = cp_parser_oacc_all_clauses (parser, OACC_ROUTINE_CLAUSE_MASK,
                                      "#pragma acc routine",
                                      cp_lexer_peek_token (parser->lexer));
+      /* The clauses are in reverse order; fix that to make later diagnostic
+        emission easier.  */
+      data.clauses = nreverse (data.clauses);
 
       if (decl && is_overloaded_fn (decl)
          && (TREE_CODE (decl) != FUNCTION_DECL
@@ -39987,6 +40893,9 @@ cp_parser_late_parsing_oacc_routine (cp_parser *parser, tree attrs)
   parser->oacc_routine->clauses
     = cp_parser_oacc_all_clauses (parser, OACC_ROUTINE_CLAUSE_MASK,
                                  "#pragma acc routine", pragma_tok);
+  /* The clauses are in reverse order; fix that to make later diagnostic
+     emission easier.  */
+  parser->oacc_routine->clauses = nreverse (parser->oacc_routine->clauses);
   cp_parser_pop_lexer (parser);
   /* Later, cp_finalize_oacc_routine will process the clauses, and then set
      fndecl_seen.  */
@@ -40021,33 +40930,42 @@ cp_finalize_oacc_routine (cp_parser *parser, tree fndecl, bool is_defn)
          return;
        }
 
-      if (oacc_get_fn_attrib (fndecl))
+      int compatible
+       = oacc_verify_routine_clauses (fndecl, &parser->oacc_routine->clauses,
+                                      parser->oacc_routine->loc,
+                                      "#pragma acc routine");
+      if (compatible < 0)
        {
-         error_at (parser->oacc_routine->loc,
-                   "%<#pragma acc routine%> already applied to %qD", fndecl);
          parser->oacc_routine = NULL;
          return;
        }
-
-      if (TREE_USED (fndecl) || (!is_defn && DECL_SAVED_TREE (fndecl)))
+      if (compatible > 0)
        {
-         error_at (parser->oacc_routine->loc,
-                   TREE_USED (fndecl)
-                   ? G_("%<#pragma acc routine%> must be applied before use")
-                   : G_("%<#pragma acc routine%> must be applied before "
-                        "definition"));
-         parser->oacc_routine = NULL;
-         return;
        }
+      else
+       {
+         if (TREE_USED (fndecl) || (!is_defn && DECL_SAVED_TREE (fndecl)))
+           {
+             error_at (parser->oacc_routine->loc,
+                       TREE_USED (fndecl)
+                       ? G_("%<#pragma acc routine%> must be applied before"
+                            " use")
+                       : G_("%<#pragma acc routine%> must be applied before"
+                            " definition"));
+             parser->oacc_routine = NULL;
+             return;
+           }
 
-      /* Process the routine's dimension clauses.  */
-      tree dims = oacc_build_routine_dims (parser->oacc_routine->clauses);
-      oacc_replace_fn_attrib (fndecl, dims);
+         /* Set the routine's level of parallelism.  */
+         tree dims = oacc_build_routine_dims (parser->oacc_routine->clauses);
+         oacc_replace_fn_attrib (fndecl, dims);
 
-      /* Add an "omp declare target" attribute.  */
-      DECL_ATTRIBUTES (fndecl)
-       = tree_cons (get_identifier ("omp declare target"),
-                    NULL_TREE, DECL_ATTRIBUTES (fndecl));
+         /* Add an "omp declare target" attribute.  */
+         DECL_ATTRIBUTES (fndecl)
+           = tree_cons (get_identifier ("omp declare target"),
+                        parser->oacc_routine->clauses,
+                        DECL_ATTRIBUTES (fndecl));
+       }
 
       /* Don't unset parser->oacc_routine here: we may still need it to
         diagnose wrong usage.  But, remember that we've used this "#pragma acc
@@ -40118,6 +41036,11 @@ cp_parser_omp_construct (cp_parser *parser, cp_token *pragma_tok, bool *if_p)
       stmt = cp_parser_omp_for (parser, pragma_tok, p_name, mask, NULL,
                                if_p);
       break;
+    case PRAGMA_OMP_LOOP:
+      strcpy (p_name, "#pragma omp");
+      stmt = cp_parser_omp_loop (parser, pragma_tok, p_name, mask, NULL,
+                                if_p);
+      break;
     case PRAGMA_OMP_MASTER:
       strcpy (p_name, "#pragma omp");
       stmt = cp_parser_omp_master (parser, pragma_tok, p_name, mask, NULL,
@@ -40244,11 +41167,15 @@ cp_parser_transaction (cp_parser *parser, cp_token *token)
   else if (keyword == RID_ATOMIC_CANCEL)
     {
       /* cancel-and-throw is unimplemented.  */
-      sorry ("atomic_cancel");
+      sorry ("%<atomic_cancel%>");
       noex = NULL_TREE;
     }
   else
-    noex = cp_parser_noexcept_specification_opt (parser, true, NULL, true);
+    noex = cp_parser_noexcept_specification_opt (parser,
+                                                CP_PARSER_FLAGS_NONE,
+                                                /*require_constexpr=*/true,
+                                                /*consumed_expr=*/NULL,
+                                                /*return_cond=*/true);
 
   /* Keep track if we're in the lexical scope of an outer transaction.  */
   new_in = this_in | (old_in & TM_STMT_ATTR_OUTER);
@@ -40308,8 +41235,11 @@ cp_parser_transaction_expression (cp_parser *parser, enum rid keyword)
   parser->in_transaction = this_in;
 
   /* Parse a noexcept specification.  */
-  noex = cp_parser_noexcept_specification_opt (parser, false, &noex_expr,
-                                              true);
+  noex = cp_parser_noexcept_specification_opt (parser,
+                                              CP_PARSER_FLAGS_NONE,
+                                              /*require_constexpr=*/false,
+                                              &noex_expr,
+                                              /*return_cond=*/true);
 
   if (!noex || !noex_expr
       || cp_lexer_peek_token (parser->lexer)->type == CPP_OPEN_PAREN)
@@ -40473,7 +41403,10 @@ cp_parser_initial_pragma (cp_token *first_token)
 
   cp_lexer_get_preprocessor_token (NULL, first_token);
   if (cp_parser_pragma_kind (first_token) != PRAGMA_GCC_PCH_PREPROCESS)
-    return;
+    {
+      c_common_no_more_pch ();
+      return;
+    }
 
   cp_lexer_get_preprocessor_token (NULL, first_token);
   if (first_token->type == CPP_STRING)
@@ -40747,6 +41680,7 @@ cp_parser_pragma (cp_parser *parser, enum pragma_context context, bool *if_p)
     case PRAGMA_OMP_CRITICAL:
     case PRAGMA_OMP_DISTRIBUTE:
     case PRAGMA_OMP_FOR:
+    case PRAGMA_OMP_LOOP:
     case PRAGMA_OMP_MASTER:
     case PRAGMA_OMP_PARALLEL:
     case PRAGMA_OMP_SECTIONS:
@@ -40786,8 +41720,14 @@ cp_parser_pragma (cp_parser *parser, enum pragma_context context, bool *if_p)
       cp_parser_omp_end_declare_target (parser, pragma_tok);
       return false;
 
+    case PRAGMA_OMP_SCAN:
+      error_at (pragma_tok->location,
+               "%<#pragma omp scan%> may only be used in "
+               "a loop construct with %<inscan%> %<reduction%> clause");
+      break;
+
     case PRAGMA_OMP_SECTION:
-      error_at (pragma_tok->location, 
+      error_at (pragma_tok->location,
                "%<#pragma omp section%> may only be used in "
                "%<#pragma omp sections%> construct");
       break;
@@ -41093,7 +42033,7 @@ synthesize_implicit_template_parm  (cp_parser *parser, tree constr)
       non_type = true;
     }
 
-  // Attach the constraint to the parm before processing.
+  /* Attach the constraint to the parm before processing.  */
   tree node = build_tree_list (NULL_TREE, synth_tmpl_parm);
   TREE_TYPE (node) = constr;
   tree new_parm
@@ -41136,8 +42076,8 @@ synthesize_implicit_template_parm  (cp_parser *parser, tree constr)
       TREE_VEC_ELT (new_parms, new_parm_idx) = parser->implicit_template_parms;
     }
 
-  // If the new parameter was constrained, we need to add that to the
-  // constraints in the template parameter list.
+  /* If the new parameter was constrained, we need to add that to the
+     constraints in the template parameter list.  */
   if (tree req = TEMPLATE_PARM_CONSTRAINTS (tree_last (new_parm)))
     {
       tree reqs = TEMPLATE_PARMS_CONSTRAINTS (current_template_parms);