2004-09-20 Paolo Bonzini * parser.c (cp_parser_token_tree_map_node, cp_parser_pm_expression, cp_parser_additive_expression, cp_parser_multiplicative_expression, cp_parser_shift_expression, cp_parser_relational_expression, cp_parser_equality_expression, cp_parser_and_expression, cp_parser_exclusive_or_expression, cp_parser_inclusive_or_expression, cp_parser_logical_and_expression, cp_parser_logical_or_expression): Removed. (enum cp_parser_prec, struct cp_parser_token_tree_map_node, binops, binops_by_token): New. (cp_parser_assignment_expression): Use cp_parser_binary_expression. (cp_parser_new): Initialize binops_by_token. (cp_parser_binary_expression): Rewritten. *** 3.5-altivec/gcc/gcc/cp/parser.c Mon Sep 20 09:12:00 2004 --- 3.5/gcc/gcc/cp/parser.c Wed Sep 22 12:09:14 2004 *************** *** 1255,1272 **** Future Improvements ------------------- ! The performance of the parser could probably be improved ! substantially. Some possible improvements include: ! ! - The expression parser recurses through the various levels of ! precedence as specified in the grammar, rather than using an ! operator-precedence technique. Therefore, parsing a simple ! identifier requires multiple recursive calls. ! ! - We could often eliminate the need to parse tentatively by ! looking ahead a little bit. In some places, this approach ! might not entirely eliminate the need to parse tentatively, but ! it might still speed up the average case. */ /* Flags that are passed to some parsing functions. These values can be bitwise-ored together. */ --- 1255,1265 ---- Future Improvements ------------------- ! The performance of the parser could probably be improved substantially. ! We could often eliminate the need to parse tentatively by looking ahead ! a little bit. In some places, this approach might not entirely eliminate ! the need to parse tentatively, but it might still speed up the average ! case. */ /* Flags that are passed to some parsing functions. These values can be bitwise-ored together. */ *************** *** 1294,1313 **** CP_PARSER_DECLARATOR_EITHER } cp_parser_declarator_kind; ! /* A mapping from a token type to a corresponding tree node type. */ ! typedef struct cp_parser_token_tree_map_node { /* The token type. */ ! ENUM_BITFIELD (cpp_ttype) token_type : 8; /* The corresponding tree code. */ ! ENUM_BITFIELD (tree_code) tree_type : 8; ! } cp_parser_token_tree_map_node; ! ! /* A complete map consists of several ordinary entries, followed by a ! terminator. The terminating entry has a token_type of CPP_EOF. */ ! ! typedef cp_parser_token_tree_map_node cp_parser_token_tree_map[]; /* The status of a tentative parse. */ --- 1287,1325 ---- CP_PARSER_DECLARATOR_EITHER } cp_parser_declarator_kind; ! /* The precedence values used to parse binary expressions. The minimum value ! of PREC must be 1, because zero is reserved to quickly discriminate ! binary operators from other tokens. */ ! ! enum cp_parser_prec ! { ! PREC_NOT_OPERATOR, ! PREC_LOGICAL_OR_EXPRESSION, ! PREC_LOGICAL_AND_EXPRESSION, ! PREC_INCLUSIVE_OR_EXPRESSION, ! PREC_EXCLUSIVE_OR_EXPRESSION, ! PREC_AND_EXPRESSION, ! PREC_RELATIONAL_EXPRESSION, ! PREC_EQUALITY_EXPRESSION, ! PREC_SHIFT_EXPRESSION, ! PREC_ADDITIVE_EXPRESSION, ! PREC_MULTIPLICATIVE_EXPRESSION, ! PREC_PM_EXPRESSION, ! NUM_PREC_VALUES = PREC_PM_EXPRESSION ! }; ! ! /* A mapping from a token type to a corresponding tree node type, with a ! precedence value. */ ! typedef struct cp_parser_binary_operations_map_node { /* The token type. */ ! enum cpp_ttype token_type; /* The corresponding tree code. */ ! enum tree_code tree_type; ! /* The precedence of this operator. */ ! enum cp_parser_prec prec; ! } cp_parser_binary_operations_map_node; /* The status of a tentative parse. */ *************** *** 1322,1329 **** CP_PARSER_STATUS_KIND_COMMITTED } cp_parser_status_kind; ! /* Context that is saved and restored when parsing tentatively. */ typedef struct cp_parser_context GTY (()) { /* If this is a tentative parsing context, the status of the --- 1334,1350 ---- CP_PARSER_STATUS_KIND_COMMITTED } cp_parser_status_kind; ! typedef struct cp_parser_expression_stack_entry ! { ! tree lhs; ! enum tree_code tree_type; ! int prec; ! } cp_parser_expression_stack_entry; + typedef struct cp_parser_expression_stack_entry + cp_parser_expression_stack[NUM_PREC_VALUES]; + + /* Context that is saved and restored when parsing tentatively. */ typedef struct cp_parser_context GTY (()) { /* If this is a tentative parsing context, the status of the *************** *** 1334,1339 **** --- 1355,1361 ---- scope given by OBJECT_TYPE (the type of `x' or `*x') and also in the context of the containing expression. */ tree object_type; + /* The next parsing context in the stack. */ struct cp_parser_context *next; } cp_parser_context; *************** *** 1349,1354 **** --- 1371,1464 ---- static GTY((deletable)) cp_parser_context* cp_parser_context_free_list; + static const cp_parser_binary_operations_map_node binops[] = { + /* pm-expression: + cast-expression + pm-expression .* cast-expression + pm-expression ->* cast-expression */ + { CPP_DEREF_STAR, MEMBER_REF, PREC_PM_EXPRESSION }, + { CPP_DOT_STAR, DOTSTAR_EXPR, PREC_PM_EXPRESSION }, + + /* multiplicative-expression: + pm-expression + multiplicative-expression * pm-expression + multiplicative-expression / pm-expression + multiplicative-expression % pm-expression */ + { CPP_MULT, MULT_EXPR, PREC_MULTIPLICATIVE_EXPRESSION }, + { CPP_DIV, TRUNC_DIV_EXPR, PREC_MULTIPLICATIVE_EXPRESSION }, + { CPP_MOD, TRUNC_MOD_EXPR, PREC_MULTIPLICATIVE_EXPRESSION }, + + /* additive-expression: + multiplicative-expression + additive-expression + multiplicative-expression + additive-expression - multiplicative-expression */ + { CPP_PLUS, PLUS_EXPR, PREC_ADDITIVE_EXPRESSION }, + { CPP_MINUS, MINUS_EXPR, PREC_ADDITIVE_EXPRESSION }, + + /* shift-expression: + additive-expression + shift-expression << additive-expression + shift-expression >> additive-expression */ + { CPP_LSHIFT, LSHIFT_EXPR, PREC_SHIFT_EXPRESSION }, + { CPP_RSHIFT, RSHIFT_EXPR, PREC_SHIFT_EXPRESSION }, + + /* relational-expression: + shift-expression + relational-expression < shift-expression + relational-expression > shift-expression + relational-expression <= shift-expression + relational-expression >= shift-expression + + GNU Extension: + + relational-expression: + relational-expression ? shift-expression */ + { CPP_LESS, LT_EXPR, PREC_RELATIONAL_EXPRESSION }, + { CPP_GREATER, GT_EXPR, PREC_RELATIONAL_EXPRESSION }, + { CPP_LESS_EQ, LE_EXPR, PREC_RELATIONAL_EXPRESSION }, + { CPP_GREATER_EQ, GE_EXPR, PREC_RELATIONAL_EXPRESSION }, + { CPP_MIN, MIN_EXPR, PREC_RELATIONAL_EXPRESSION }, + { CPP_MAX, MAX_EXPR, PREC_RELATIONAL_EXPRESSION }, + + /* equality-expression: + relational-expression + equality-expression == relational-expression + equality-expression != relational-expression */ + { CPP_EQ_EQ, EQ_EXPR, PREC_EQUALITY_EXPRESSION }, + { CPP_NOT_EQ, NE_EXPR, PREC_EQUALITY_EXPRESSION }, + + /* and-expression: + equality-expression + and-expression & equality-expression */ + { CPP_AND, BIT_AND_EXPR, PREC_AND_EXPRESSION }, + + /* exclusive-or-expression: + and-expression + exclusive-or-expression ^ and-expression */ + { CPP_XOR, BIT_XOR_EXPR, PREC_EXCLUSIVE_OR_EXPRESSION }, + + /* inclusive-or-expression: + exclusive-or-expression + inclusive-or-expression | exclusive-or-expression */ + { CPP_OR, BIT_IOR_EXPR, PREC_INCLUSIVE_OR_EXPRESSION }, + + /* logical-and-expression: + inclusive-or-expression + logical-and-expression && inclusive-or-expression */ + { CPP_AND_AND, TRUTH_ANDIF_EXPR, PREC_LOGICAL_AND_EXPRESSION }, + + /* logical-or-expression: + logical-and-expression + logical-or-expression || logical-and-expression */ + { CPP_OR_OR, TRUTH_ORIF_EXPR, PREC_LOGICAL_OR_EXPRESSION } + }; + + /* The same as binops, but initialized by cp_parser_new so that + binops_by_token[N].token_type == N. Used in cp_parser_binary_expression + for speed. */ + static cp_parser_binary_operations_map_node binops_by_token[N_TTYPES]; + /* Constructors and destructors. */ /* Construct a new context. The context below this one on the stack *************** *** 1369,1374 **** --- 1479,1485 ---- } else context = GGC_CNEW (cp_parser_context); + /* No errors have occurred yet in this context. */ context->status = CP_PARSER_STATUS_KIND_NO_ERROR; /* If this is not the bottomost context, copy information that we *************** *** 1588,1614 **** (cp_parser *); static tree cp_parser_cast_expression (cp_parser *, bool); ! static tree cp_parser_pm_expression ! (cp_parser *); ! static tree cp_parser_multiplicative_expression ! (cp_parser *); ! static tree cp_parser_additive_expression ! (cp_parser *); ! static tree cp_parser_shift_expression ! (cp_parser *); ! static tree cp_parser_relational_expression ! (cp_parser *); ! static tree cp_parser_equality_expression ! (cp_parser *); ! static tree cp_parser_and_expression ! (cp_parser *); ! static tree cp_parser_exclusive_or_expression ! (cp_parser *); ! static tree cp_parser_inclusive_or_expression ! (cp_parser *); ! static tree cp_parser_logical_and_expression ! (cp_parser *); ! static tree cp_parser_logical_or_expression (cp_parser *); static tree cp_parser_question_colon_clause (cp_parser *, tree); --- 1699,1705 ---- (cp_parser *); static tree cp_parser_cast_expression (cp_parser *, bool); ! static tree cp_parser_binary_expression (cp_parser *); static tree cp_parser_question_colon_clause (cp_parser *, tree); *************** *** 1862,1869 **** (cp_parser *, unsigned); static tree cp_parser_simple_cast_expression (cp_parser *); - static tree cp_parser_binary_expression - (cp_parser *, const cp_parser_token_tree_map, cp_parser_expression_fn); static tree cp_parser_global_scope_opt (cp_parser *, bool); static bool cp_parser_constructor_declarator_p --- 1953,1958 ---- *************** *** 2558,2568 **** --- 2647,2663 ---- { cp_parser *parser; cp_lexer *lexer; + unsigned i; /* cp_lexer_new_main is called before calling ggc_alloc because cp_lexer_new_main might load a PCH file. */ lexer = cp_lexer_new_main (); + /* Initialize the binops_by_token so that we can get the tree + directly from the token. */ + for (i = 0; i < sizeof (binops) / sizeof (binops[0]); i++) + binops_by_token[binops[i].token_type] = binops[i]; + parser = GGC_CNEW (cp_parser); parser->lexer = lexer; parser->context = cp_parser_context_new (NULL); *************** *** 5275,5536 **** return cp_parser_unary_expression (parser, address_p); } ! /* Parse a pm-expression. ! ! pm-expression: ! cast-expression ! pm-expression .* cast-expression ! pm-expression ->* cast-expression ! ! Returns a representation of the expression. */ ! ! static tree ! cp_parser_pm_expression (cp_parser* parser) ! { ! static const cp_parser_token_tree_map map = { ! { CPP_DEREF_STAR, MEMBER_REF }, ! { CPP_DOT_STAR, DOTSTAR_EXPR }, ! { CPP_EOF, ERROR_MARK } ! }; ! ! return cp_parser_binary_expression (parser, map, ! cp_parser_simple_cast_expression); ! } ! ! /* Parse a multiplicative-expression. ! ! multiplicative-expression: ! pm-expression ! multiplicative-expression * pm-expression ! multiplicative-expression / pm-expression ! multiplicative-expression % pm-expression ! ! Returns a representation of the expression. */ ! ! static tree ! cp_parser_multiplicative_expression (cp_parser* parser) ! { ! static const cp_parser_token_tree_map map = { ! { CPP_MULT, MULT_EXPR }, ! { CPP_DIV, TRUNC_DIV_EXPR }, ! { CPP_MOD, TRUNC_MOD_EXPR }, ! { CPP_EOF, ERROR_MARK } ! }; ! ! return cp_parser_binary_expression (parser, ! map, ! cp_parser_pm_expression); ! } ! ! /* Parse an additive-expression. ! ! additive-expression: ! multiplicative-expression ! additive-expression + multiplicative-expression ! additive-expression - multiplicative-expression ! ! Returns a representation of the expression. */ ! ! static tree ! cp_parser_additive_expression (cp_parser* parser) ! { ! static const cp_parser_token_tree_map map = { ! { CPP_PLUS, PLUS_EXPR }, ! { CPP_MINUS, MINUS_EXPR }, ! { CPP_EOF, ERROR_MARK } ! }; ! ! return cp_parser_binary_expression (parser, ! map, ! cp_parser_multiplicative_expression); ! } ! ! /* Parse a shift-expression. ! ! shift-expression: ! additive-expression ! shift-expression << additive-expression ! shift-expression >> additive-expression ! ! Returns a representation of the expression. */ ! ! static tree ! cp_parser_shift_expression (cp_parser* parser) ! { ! static const cp_parser_token_tree_map map = { ! { CPP_LSHIFT, LSHIFT_EXPR }, ! { CPP_RSHIFT, RSHIFT_EXPR }, ! { CPP_EOF, ERROR_MARK } ! }; ! ! return cp_parser_binary_expression (parser, ! map, ! cp_parser_additive_expression); ! } ! ! /* Parse a relational-expression. ! ! relational-expression: ! shift-expression ! relational-expression < shift-expression ! relational-expression > shift-expression ! relational-expression <= shift-expression ! relational-expression >= shift-expression ! ! GNU Extension: ! ! relational-expression: ! relational-expression ? shift-expression ! ! Returns a representation of the expression. */ ! ! static tree ! cp_parser_relational_expression (cp_parser* parser) ! { ! static const cp_parser_token_tree_map map = { ! { CPP_LESS, LT_EXPR }, ! { CPP_GREATER, GT_EXPR }, ! { CPP_LESS_EQ, LE_EXPR }, ! { CPP_GREATER_EQ, GE_EXPR }, ! { CPP_MIN, MIN_EXPR }, ! { CPP_MAX, MAX_EXPR }, ! { CPP_EOF, ERROR_MARK } ! }; ! ! return cp_parser_binary_expression (parser, ! map, ! cp_parser_shift_expression); ! } ! ! /* Parse an equality-expression. ! ! equality-expression: ! relational-expression ! equality-expression == relational-expression ! equality-expression != relational-expression ! ! Returns a representation of the expression. */ ! ! static tree ! cp_parser_equality_expression (cp_parser* parser) ! { ! static const cp_parser_token_tree_map map = { ! { CPP_EQ_EQ, EQ_EXPR }, ! { CPP_NOT_EQ, NE_EXPR }, ! { CPP_EOF, ERROR_MARK } ! }; ! ! return cp_parser_binary_expression (parser, ! map, ! cp_parser_relational_expression); ! } ! ! /* Parse an and-expression. ! ! and-expression: ! equality-expression ! and-expression & equality-expression ! ! Returns a representation of the expression. */ ! ! static tree ! cp_parser_and_expression (cp_parser* parser) ! { ! static const cp_parser_token_tree_map map = { ! { CPP_AND, BIT_AND_EXPR }, ! { CPP_EOF, ERROR_MARK } ! }; ! ! return cp_parser_binary_expression (parser, ! map, ! cp_parser_equality_expression); ! } ! /* Parse an exclusive-or-expression. ! exclusive-or-expression: ! and-expression ! exclusive-or-expression ^ and-expression ! Returns a representation of the expression. */ static tree ! cp_parser_exclusive_or_expression (cp_parser* parser) { ! static const cp_parser_token_tree_map map = { ! { CPP_XOR, BIT_XOR_EXPR }, ! { CPP_EOF, ERROR_MARK } ! }; ! ! return cp_parser_binary_expression (parser, ! map, ! cp_parser_and_expression); ! } ! ! /* Parse an inclusive-or-expression. ! inclusive-or-expression: ! exclusive-or-expression ! inclusive-or-expression | exclusive-or-expression ! Returns a representation of the expression. */ ! static tree ! cp_parser_inclusive_or_expression (cp_parser* parser) ! { ! static const cp_parser_token_tree_map map = { ! { CPP_OR, BIT_IOR_EXPR }, ! { CPP_EOF, ERROR_MARK } ! }; ! return cp_parser_binary_expression (parser, ! map, ! cp_parser_exclusive_or_expression); ! } ! /* Parse a logical-and-expression. ! logical-and-expression: ! inclusive-or-expression ! logical-and-expression && inclusive-or-expression ! Returns a representation of the expression. */ ! static tree ! cp_parser_logical_and_expression (cp_parser* parser) ! { ! static const cp_parser_token_tree_map map = { ! { CPP_AND_AND, TRUTH_ANDIF_EXPR }, ! { CPP_EOF, ERROR_MARK } ! }; ! return cp_parser_binary_expression (parser, ! map, ! cp_parser_inclusive_or_expression); } - /* Parse a logical-or-expression. - - logical-or-expression: - logical-and-expression - logical-or-expression || logical-and-expression - - Returns a representation of the expression. */ - - static tree - cp_parser_logical_or_expression (cp_parser* parser) - { - static const cp_parser_token_tree_map map = { - { CPP_OR_OR, TRUTH_ORIF_EXPR }, - { CPP_EOF, ERROR_MARK } - }; - - return cp_parser_binary_expression (parser, - map, - cp_parser_logical_and_expression); - } /* Parse the `? expression : assignment-expression' part of a conditional-expression. The LOGICAL_OR_EXPR is the --- 5370,5485 ---- return cp_parser_unary_expression (parser, address_p); } ! /* Parse a binary-expression of the general form: ! binary-expression: ! simple-cast-expression ! binary-expression binary-expression ! The binops_by_token map is used to get the tree codes for each type. ! binary-expressions are associated according to a precedence table. */ ! #define TOKEN_PRECEDENCE(token) \ ! ((token->type == CPP_GREATER && !parser->greater_than_is_operator_p) \ ! ? PREC_NOT_OPERATOR \ ! : binops_by_token[token->type].prec) static tree ! cp_parser_binary_expression (cp_parser* parser) { ! cp_parser_expression_stack stack; ! cp_parser_expression_stack_entry *sp = &stack[0]; ! tree lhs, rhs; ! cp_token *token; ! enum tree_code tree_type; ! enum cp_parser_prec prec = PREC_NOT_OPERATOR, new_prec, lookahead_prec; ! bool overloaded_p; ! /* Parse the first expression. */ ! lhs = cp_parser_simple_cast_expression (parser); ! for (;;) ! { ! /* Get an operator token. */ ! token = cp_lexer_peek_token (parser->lexer); ! new_prec = TOKEN_PRECEDENCE (token); ! /* Popping an entry off the stack means we completed a subexpression: ! - either we found a token which is not an operator (`>' where it is not ! an operator, or prec == PREC_NOT_OPERATOR), in which case popping ! will happen repeatedly; ! - or, we found an operator which has lower priority. This is the case ! where the recursive descent *ascends*, as in `3 * 4 + 5' after ! parsing `3 * 4'. */ ! if (new_prec <= prec) ! { ! if (sp == stack) ! break; ! else ! goto pop; ! } ! get_rhs: ! tree_type = binops_by_token[token->type].tree_type; ! /* We used the operator token. */ ! cp_lexer_consume_token (parser->lexer); ! /* Parse the beginning of the RHS of this new, higher priority ! expression. */ ! rhs = cp_parser_simple_cast_expression (parser); ! /* Get another operator token. Look up its precedence to avoid ! building a useless (immediately popped) stack entry for common ! cases such as 3 + 4 + 5 or 3 * 4 + 5. */ ! token = cp_lexer_peek_token (parser->lexer); ! lookahead_prec = TOKEN_PRECEDENCE (token); ! if (lookahead_prec > new_prec) ! { ! /* ... and prepare to parse the RHS of this new, higher priority ! expression. */ ! sp->prec = prec; ! sp->tree_type = tree_type; ! sp->lhs = lhs; ! sp++; ! lhs = rhs; ! prec = new_prec; ! new_prec = lookahead_prec; ! goto get_rhs; ! ! pop: ! /* If the stack is not empty, we have parsed into LHS the right side ! (`4' in the example above) of an expression we had suspended. ! We can use the information on the stack to recover the LHS (`3') ! from the stack together with the tree code (`MULT_EXPR'), and ! the precedence of the higher level subexpression ! (`PREC_ADDITIVE_EXPRESSION'). TOKEN is the CPP_PLUS token, ! which will be used to actually build the additive expression. */ ! --sp; ! prec = sp->prec; ! tree_type = sp->tree_type; ! rhs = lhs; ! lhs = sp->lhs; ! } ! overloaded_p = false; ! lhs = build_x_binary_op (tree_type, lhs, rhs, &overloaded_p); ! /* If the binary operator required the use of an overloaded operator, ! then this expression cannot be an integral constant-expression. ! An overloaded operator can be used even if both operands are ! otherwise permissible in an integral constant-expression if at ! least one of the operands is of enumeration type. */ ! ! if (overloaded_p ! && (cp_parser_non_integral_constant_expression ! (parser, "calls to overloaded operators"))) ! return error_mark_node; ! } ! return lhs; } /* Parse the `? expression : assignment-expression' part of a conditional-expression. The LOGICAL_OR_EXPR is the *************** *** 5594,5601 **** logical-or-expression. */ else { ! /* Parse the logical-or-expression. */ ! expr = cp_parser_logical_or_expression (parser); /* If the next token is a `?' then we're actually looking at a conditional-expression. */ if (cp_lexer_next_token_is (parser->lexer, CPP_QUERY)) --- 5543,5550 ---- logical-or-expression. */ else { ! /* Parse the binary expressions (logical-or-expression). */ ! expr = cp_parser_binary_expression (parser); /* If the next token is a `?' then we're actually looking at a conditional-expression. */ if (cp_lexer_next_token_is (parser->lexer, CPP_QUERY)) *************** *** 14538,14616 **** return false; } - /* Parse a binary-expression of the general form: - - binary-expression: - - binary-expression - - The TOKEN_TREE_MAP maps types to codes. FN is used - to parser the s. If the first production is used, then the - value returned by FN is returned directly. Otherwise, a node with - the indicated EXPR_TYPE is returned, with operands corresponding to - the two sub-expressions. */ - - static tree - cp_parser_binary_expression (cp_parser* parser, - const cp_parser_token_tree_map token_tree_map, - cp_parser_expression_fn fn) - { - tree lhs; - - /* Parse the first expression. */ - lhs = (*fn) (parser); - /* Now, look for more expressions. */ - while (true) - { - cp_token *token; - const cp_parser_token_tree_map_node *map_node; - tree rhs; - - /* Peek at the next token. */ - token = cp_lexer_peek_token (parser->lexer); - /* If the token is `>', and that's not an operator at the - moment, then we're done. */ - if (token->type == CPP_GREATER - && !parser->greater_than_is_operator_p) - break; - /* If we find one of the tokens we want, build the corresponding - tree representation. */ - for (map_node = token_tree_map; - map_node->token_type != CPP_EOF; - ++map_node) - if (map_node->token_type == token->type) - { - /* Assume that an overloaded operator will not be used. */ - bool overloaded_p = false; - - /* Consume the operator token. */ - cp_lexer_consume_token (parser->lexer); - /* Parse the right-hand side of the expression. */ - rhs = (*fn) (parser); - /* Build the binary tree node. */ - lhs = build_x_binary_op (map_node->tree_type, lhs, rhs, - &overloaded_p); - /* If the binary operator required the use of an - overloaded operator, then this expression cannot be an - integral constant-expression. An overloaded operator - can be used even if both operands are otherwise - permissible in an integral constant-expression if at - least one of the operands is of enumeration type. */ - if (overloaded_p - && (cp_parser_non_integral_constant_expression - (parser, "calls to overloaded operators"))) - lhs = error_mark_node; - break; - } - - /* If the token wasn't one of the ones we want, we're done. */ - if (map_node->token_type == CPP_EOF) - break; - } - - return lhs; - } - /* Parse an optional `::' token indicating that the following name is from the global namespace. If so, PARSER->SCOPE is set to the GLOBAL_NAMESPACE. Otherwise, PARSER->SCOPE is set to NULL_TREE, --- 14487,14492 ----