static cp_token_cache *cp_token_cache_new
(cp_token *, cp_token *);
-static tree cp_parser_noexcept_specification_opt
- (cp_parser *, bool, bool *, bool, bool);
static tree cp_parser_late_noexcept_specifier
(cp_parser *, tree);
static void noexcept_override_late_checks
{
/* 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;
}
case RID_DECLTYPE:
case RID_UNDERLYING_TYPE:
case RID_CONSTEXPR:
+ case RID_CONSTINIT:
return true;
default:
/* 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
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
static void cp_parser_explicit_specialization
(cp_parser *);
-/* Exception handling [gram.exception] */
+/* Exception handling [gram.except] */
static tree cp_parser_try_block
(cp_parser *);
static tree cp_parser_throw_expression
(cp_parser *);
static tree cp_parser_exception_specification_opt
- (cp_parser *, bool = false);
+ (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 */
(cp_parser *);
static bool cp_parser_skip_to_closing_square_bracket
(cp_parser *);
-static int cp_parser_skip_to_closing_square_bracket_1
- (cp_parser *, enum cpp_ttype);
/* Concept-related syntactic transformations */
&& id_equal (id, "thread_local"))
inform (location, "C++11 %<thread_local%> only available with "
"%<-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%>");
else if (processing_template_decl && current_class_type
== 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. */
index = cp_parser_braced_list (parser, &expr_nonconst_p);
}
else
- {
- /* [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. */
- if (warn_comma_subscript)
- {
- /* Save tokens so that we can put them back. */
- cp_lexer_save_tokens (parser->lexer);
-
- /* Look for ',' that is not nested in () or {}. */
- if (cp_parser_skip_to_closing_square_bracket_1 (parser,
- CPP_COMMA) == -1)
- {
- auto_diagnostic_group d;
- warning_at (cp_lexer_peek_token (parser->lexer)->location,
- OPT_Wcomma_subscript,
- "top-level comma expression in array subscript "
- "is deprecated");
- }
-
- /* Roll back the tokens we skipped. */
- cp_lexer_rollback_tokens (parser->lexer);
- }
-
- 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;
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;
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))
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);
}
}
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);
std_attrs = cp_parser_std_attribute_spec_seq (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);
/* 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. */
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 ());
}
}
{
/* decl-specifier:
friend
- constexpr */
+ constexpr
+ constinit */
case RID_FRIEND:
if (!at_class_scope_p ())
{
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);
/* 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);
&& !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
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);
/*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);
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,
`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)
tree tx_qual = cp_parser_tx_qualifier_opt (parser);
/* And the exception-specification. */
exception_specification
- = cp_parser_exception_specification_opt (parser, friend_p);
+ = cp_parser_exception_specification_opt (parser, flags);
attrs = cp_parser_std_attribute_spec_seq (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);
}
/* Consume tokens up to, and including, the next non-nested closing `]'.
- Returns 1 iff we found a closing `]'. Returns -1 if OR_TTYPE is not
- CPP_EOF and we found an unnested token of that type. */
+ Returns true iff we found a closing `]'. */
-static int
-cp_parser_skip_to_closing_square_bracket_1 (cp_parser *parser,
- enum cpp_ttype or_ttype)
+static bool
+cp_parser_skip_to_closing_square_bracket (cp_parser *parser)
{
unsigned square_depth = 0;
- unsigned paren_depth = 0;
- unsigned brace_depth = 0;
while (true)
{
- cp_token *token = cp_lexer_peek_token (parser->lexer);
-
- /* Have we found what we're looking for before the closing square? */
- if (token->type == or_ttype && or_ttype != CPP_EOF
- && brace_depth == 0 && paren_depth == 0 && square_depth == 0)
- return -1;
+ cp_token * token = cp_lexer_peek_token (parser->lexer);
switch (token->type)
{
/* FALLTHRU */
case CPP_EOF:
/* If we've run out of tokens, then there is no closing `]'. */
- return 0;
+ return false;
case CPP_OPEN_SQUARE:
++square_depth;
break;
case CPP_CLOSE_SQUARE:
- if (square_depth-- == 0)
+ if (!square_depth--)
{
cp_lexer_consume_token (parser->lexer);
- return 1;
+ return true;
}
break;
- case CPP_OPEN_BRACE:
- ++brace_depth;
- break;
-
- case CPP_CLOSE_BRACE:
- if (brace_depth-- == 0)
- return 0;
- break;
-
- case CPP_OPEN_PAREN:
- ++paren_depth;
- break;
-
- case CPP_CLOSE_PAREN:
- if (paren_depth-- == 0)
- return 0;
- break;
-
default:
break;
}
}
}
-/* Consume tokens up to, and including, the next non-nested closing `]'.
- Returns true iff we found a closing `]'. */
-
-static bool
-cp_parser_skip_to_closing_square_bracket (cp_parser *parser)
-{
- return cp_parser_skip_to_closing_square_bracket_1 (parser, CPP_EOF) == 1;
-}
-
/* Return true if we are looking at an array-designator, false otherwise. */
static bool
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,
/* 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,
- /*friend_p=*/false);
+ /*return_cond=*/false);
/* Revert to the main lexer. */
cp_parser_pop_lexer (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. If FRIEND_P is true,
- the function with this noexcept-specification had the `friend' specifier. */
+ 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,
- bool friend_p)
+ bool return_cond)
{
cp_token *token;
const char *saved_message;
/* No need to delay parsing for a number literal or true/false. */
&& !literal_p
&& at_class_scope_p ()
- /* Don't delay parsing for friend member functions. */
- && !friend_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);
throw ( type-id-list [opt] )
Returns a TREE_LIST representing the exception-specification. The
- TREE_VALUE of each node is a type. If FRIEND_P is true, the function
- with this noexcept-specification had the `friend' specifier. */
+ 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, bool friend_p)
+cp_parser_exception_specification_opt (cp_parser* parser, cp_parser_flags flags)
{
cp_token *token;
tree type_id_list;
/* Is it a noexcept-specification? */
type_id_list
- = cp_parser_noexcept_specification_opt (parser,
+ = cp_parser_noexcept_specification_opt (parser, flags,
/*require_constexpr=*/true,
/*consumed_expr=*/NULL,
- /*return_cond=*/false,
- friend_p);
+ /*return_cond=*/false);
if (type_id_list != NULL_TREE)
return type_id_list;
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);
"typedef",
"using",
"constexpr",
- "__complex"
+ "__complex",
+ "constinit"
};
gcc_rich_location richloc (location);
richloc.add_fixit_remove ();
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;
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 )] */
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);
#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,
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");
}
}
}
+ 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
}
else
noex = cp_parser_noexcept_specification_opt (parser,
+ CP_PARSER_FLAGS_NONE,
/*require_constexpr=*/true,
/*consumed_expr=*/NULL,
- /*return_cond=*/true,
- /*friend_p=*/false);
+ /*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);
/* Parse a noexcept specification. */
noex = cp_parser_noexcept_specification_opt (parser,
+ CP_PARSER_FLAGS_NONE,
/*require_constexpr=*/false,
&noex_expr,
- /*return_cond=*/true,
- /*friend_p=*/false);
+ /*return_cond=*/true);
if (!noex || !noex_expr
|| cp_lexer_peek_token (parser->lexer)->type == CPP_OPEN_PAREN)
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)
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
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);