From: Chris Lattner Date: Sun, 6 Apr 2008 05:26:30 +0000 (+0000) Subject: Use token lookahead to simplify some code that is rarely executed. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5dcc6ce4a68b3bd4b89c5697c9728e1533e71e03;p=clang Use token lookahead to simplify some code that is rarely executed. Since it is rare, the cost is not significant and we enjoy the simplification. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@49263 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h index 962b3370b7..01879479a8 100644 --- a/include/clang/Parse/Parser.h +++ b/include/clang/Parse/Parser.h @@ -336,7 +336,6 @@ private: 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); diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index 9b8ecf8bd3..1659af30e6 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -1440,24 +1440,20 @@ void Parser::ParseBracketDeclarator(Declarator &D) { // 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(); diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp index 46714b73ea..dff7c14524 100644 --- a/lib/Parse/ParseExpr.cpp +++ b/lib/Parse/ParseExpr.cpp @@ -270,42 +270,6 @@ ParseAssignmentExprWithLeadingIdentifier(const Token &IdTok) { } -/// 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