ExprResult ParseExpressionWithLeadingIdentifier(const Token &Tok);
ExprResult ParseExpressionWithLeadingAt(SourceLocation AtLoc);
ExprResult ParseAssignmentExprWithLeadingIdentifier(const Token &Tok);
- ExprResult ParseAssignmentExpressionWithLeadingStar(const Token &Tok);
ExprResult ParseRHSOfBinaryExpression(ExprResult LHS, unsigned MinPrec);
ExprResult ParseCastExpression(bool isUnaryExpression);
// Handle "direct-declarator [ type-qual-list[opt] * ]".
bool isStar = false;
ExprResult NumElements(false);
- if (Tok.is(tok::star)) {
+
+ // Handle the case where we have '[*]' as the array size. However, a leading
+ // star could be the start of an expression, for example 'X[*p + 4]'. Verify
+ // the the token after the star is a ']'. Since stars in arrays are
+ // infrequent, use of lookahead is not costly here.
+ if (Tok.is(tok::star) && GetLookAheadToken(1).is(tok::r_square)) {
// Remember the '*' token, in case we have to un-get it.
Token StarTok = Tok;
ConsumeToken();
- // Check that the ']' token is present to avoid incorrectly parsing
- // expressions starting with '*' as [*].
- if (Tok.is(tok::r_square)) {
- if (StaticLoc.isValid())
- Diag(StaticLoc, diag::err_unspecified_vla_size_with_static);
- StaticLoc = SourceLocation(); // Drop the static.
- isStar = true;
- } else {
- // Otherwise, the * must have been some expression (such as '*ptr') that
- // started an assignment-expr. We already consumed the token, but now we
- // need to reparse it. This handles cases like 'X[*p + 4]'
- NumElements = ParseAssignmentExpressionWithLeadingStar(StarTok);
- }
+ if (StaticLoc.isValid())
+ Diag(StaticLoc, diag::err_unspecified_vla_size_with_static);
+ StaticLoc = SourceLocation(); // Drop the static.
+ isStar = true;
} else if (Tok.isNot(tok::r_square)) {
// Parse the assignment-expression now.
NumElements = ParseAssignmentExpression();
}
-/// ParseAssignmentExpressionWithLeadingStar - This special purpose method is
-/// used in contexts where we have already consumed a '*' (which we saved in
-/// 'StarTok'), then discovered that the '*' was really the leading token of an
-/// expression. For example, in "*(int*)P+B", we consumed "*" (which is
-/// now in 'StarTok') and the current token is "(".
-Parser::ExprResult Parser::
-ParseAssignmentExpressionWithLeadingStar(const Token &StarTok) {
- // We know that 'StarTok' must correspond to this production:
- // unary-expression: unary-operator cast-expression
- // where 'unary-operator' is '*'.
-
- // Parse the cast-expression that follows the '*'. This will parse the
- // "*(int*)P" part of "*(int*)P+B".
- ExprResult Res = ParseCastExpression(false);
- if (Res.isInvalid) return Res;
-
- // Combine StarTok + Res to get the new AST for the combined expression..
- Res = Actions.ActOnUnaryOp(StarTok.getLocation(), tok::star, Res.Val);
- if (Res.isInvalid) return Res;
-
-
- // We have to parse an entire cast-expression before starting the
- // ParseRHSOfBinaryExpression method (which parses any trailing binops). Since
- // we know that the only production above us is the cast-expression
- // production, and because the only alternative productions start with a '('
- // token (we know we had a '*'), there is no work to do to get a whole
- // cast-expression.
-
- // At this point, the "*(int*)P" part of "*(int*)P+B" has been consumed. Once
- // this is done, we can invoke ParseRHSOfBinaryExpression to consume any
- // trailing operators (e.g. "+" in this example) and connected chunks of the
- // assignment-expression.
- return ParseRHSOfBinaryExpression(Res, prec::Assignment);
-}
-
-
/// ParseRHSOfBinaryExpression - Parse a binary expression that starts with
/// LHS and has a precedence of at least MinPrec.
Parser::ExprResult