From 4564bc1123137e1d7e7810104bf9ffd022c947b9 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Thu, 10 Aug 2006 23:14:52 +0000 Subject: [PATCH] Factor some code into the new Parser::MatchRHSPunctuation method. llvm-svn: 38864 --- clang/Parse/ParseDecl.cpp | 11 ++---- clang/Parse/ParseExpr.cpp | 57 ++++++++++++++---------------- clang/Parse/ParseStmt.cpp | 10 ++---- clang/Parse/Parser.cpp | 24 +++++++++++++ clang/include/clang/Parse/Parser.h | 16 ++++++--- 5 files changed, 67 insertions(+), 51 deletions(-) diff --git a/clang/Parse/ParseDecl.cpp b/clang/Parse/ParseDecl.cpp index 6c06797ea7ae..f3465516fdff 100644 --- a/clang/Parse/ParseDecl.cpp +++ b/clang/Parse/ParseDecl.cpp @@ -481,14 +481,9 @@ void Parser::ParseParenDeclarator(Declarator &D) { // direct-declarator: '(' attributes declarator ')' [TODO] if (isGrouping) { ParseDeclaratorInternal(D); - if (Tok.getKind() == tok::r_paren) { - ConsumeParen(); - } else { - // expected ')': skip until we find ')'. - Diag(Tok, diag::err_expected_rparen); - Diag(StartLoc, diag::err_matching, "("); - SkipUntil(tok::r_paren); - } + // Match the ')'. + MatchRHSPunctuation(tok::r_paren, StartLoc, "(", + diag::err_expected_rparen); return; } diff --git a/clang/Parse/ParseExpr.cpp b/clang/Parse/ParseExpr.cpp index 9b74eea791f6..cf8a2f52135d 100644 --- a/clang/Parse/ParseExpr.cpp +++ b/clang/Parse/ParseExpr.cpp @@ -34,9 +34,22 @@ void Parser::ParseAssignmentExpression() { ParseExpression(); } - +/// ParseCastExpression +/// cast-expression: [C99 6.5.4] +/// unary-expression +/// '(' type-name ')' cast-expression +/// void Parser::ParseCastExpression() { - ParseUnaryExpression(); + // If this doesn't start with an '(', then it is a unary-expression. + if (Tok.getKind() != tok::l_paren) + return ParseUnaryExpression(); + + // Otherwise this is either a cast, a compound literal, or a parenthesized + // expression. + SourceLocation LParenLoc = Tok.getLocation(); + ConsumeParen(); + + assert(0); } /// ParseUnaryExpression @@ -135,13 +148,8 @@ void Parser::ParseSizeofAlignofExpression() { } - if (Tok.getKind() == tok::r_paren) { - ConsumeParen(); - } else { - Diag(Tok, diag::err_expected_rparen); - Diag(LParenLoc, diag::err_matching, "("); - SkipUntil(tok::r_paren); - } + // Match the ')'. + MatchRHSPunctuation(tok::r_paren, LParenLoc, "(", diag::err_expected_rparen); } /// ParsePostfixExpression @@ -238,13 +246,8 @@ void Parser::ParsePostfixExpression() { Loc = Tok.getLocation(); ConsumeBracket(); ParseExpression(); - if (Tok.getKind() == tok::r_square) { - ConsumeBracket(); - } else { - Diag(Tok, diag::err_expected_rsquare); - Diag(Loc, diag::err_matching, "["); - SkipUntil(tok::r_square); - } + // Match the ']'. + MatchRHSPunctuation(tok::r_square, Loc, "[", diag::err_expected_rsquare); break; case tok::l_paren: // p-e: p-e '(' argument-expression-list[opt] ')' @@ -260,13 +263,8 @@ void Parser::ParsePostfixExpression() { ConsumeToken(); // Next argument. } - if (Tok.getKind() == tok::r_paren) { - ConsumeParen(); - } else { - Diag(Tok, diag::err_expected_rparen); - Diag(Loc, diag::err_matching, "("); - SkipUntil(tok::r_paren); - } + // Match the ')'. + MatchRHSPunctuation(tok::r_paren, Loc, "(", diag::err_expected_rparen); break; case tok::arrow: // postfix-expression: p-e '->' identifier @@ -294,12 +292,12 @@ void Parser::ParsePostfixExpression() { /// primary-expression: [C99 6.5.1] /// string-literal void Parser::ParseStringLiteralExpression() { - assert(isStringLiteral() && "Not a string literal!"); + assert(isTokenStringLiteral() && "Not a string literal!"); ConsumeStringToken(); // String concat. Note that keywords like __func__ and __FUNCTION__ aren't // considered to be strings. - while (isStringLiteral()) + while (isTokenStringLiteral()) ConsumeStringToken(); } @@ -328,10 +326,7 @@ void Parser::ParseParenExpression(bool ParenExprOnly) { ParseExpression(); } - if (Tok.getKind() == tok::r_paren) { - ConsumeParen(); - } else { - Diag(Tok, diag::err_expected_rparen); - Diag(OpenLoc, diag::err_matching, "("); - } + + // Match the ')'. + MatchRHSPunctuation(tok::r_paren, OpenLoc, "(", diag::err_expected_rparen); } diff --git a/clang/Parse/ParseStmt.cpp b/clang/Parse/ParseStmt.cpp index 25dda3a4060f..abcaa5fe033a 100644 --- a/clang/Parse/ParseStmt.cpp +++ b/clang/Parse/ParseStmt.cpp @@ -444,14 +444,8 @@ void Parser::ParseForStatement() { ParseExpression(); } - if (Tok.getKind() == tok::r_paren) { - ConsumeParen(); - } else { - Diag(Tok, diag::err_expected_rparen); - Diag(LParenLoc, diag::err_matching, "("); - SkipUntil(tok::r_paren); - return; - } + // Match the ')'. + MatchRHSPunctuation(tok::r_paren, LParenLoc, "(", diag::err_expected_rparen); // Read the body statement. ParseStatement(); diff --git a/clang/Parse/Parser.cpp b/clang/Parse/Parser.cpp index 8c483e74e980..b469dc687262 100644 --- a/clang/Parse/Parser.cpp +++ b/clang/Parse/Parser.cpp @@ -36,6 +36,30 @@ void Parser::Diag(SourceLocation Loc, unsigned DiagID, Diags.Report(Loc, DiagID, Msg); } +/// MatchRHSPunctuation - For punctuation with a LHS and RHS (e.g. '['/']'), +/// this helper function matches and consumes the specified RHS token if +/// present. If not present, it emits the specified diagnostic indicating +/// that the parser failed to match the RHS of the token at LHSLoc. LHSName +/// should be the name of the unmatched LHS token. +void Parser::MatchRHSPunctuation(tok::TokenKind RHSTok, SourceLocation LHSLoc, + const char *LHSName, unsigned DiagID) { + + if (Tok.getKind() == RHSTok) { + if (isTokenParen()) + ConsumeParen(); + else if (isTokenBracket()) + ConsumeBracket(); + else if (isTokenBrace()) + ConsumeBrace(); + else + ConsumeParen(); + } else { + Diag(Tok, DiagID); + Diag(LHSLoc, diag::err_matching, LHSName); + SkipUntil(RHSTok); + } +} + //===----------------------------------------------------------------------===// // Error recovery. //===----------------------------------------------------------------------===// diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h index d7b51f0bd244..3be6b267642c 100644 --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -75,9 +75,9 @@ public: return Tok.getKind() == tok::l_brace || Tok.getKind() == tok::r_brace; } - /// isStringLiteral - True if this token is a string-literal. + /// isTokenStringLiteral - True if this token is a string-literal. /// - bool isStringLiteral() const { + bool isTokenStringLiteral() const { return Tok.getKind() == tok::string_literal; } @@ -86,7 +86,7 @@ public: /// tokens must be consumed with custom methods below. void ConsumeToken() { // Note: update Parser::SkipUntil if any other special tokens are added. - assert(!isStringLiteral() && !isTokenParen() && !isTokenBracket() && + assert(!isTokenStringLiteral() && !isTokenParen() && !isTokenBracket() && !isTokenBrace() && "Should consume special tokens with Consume*Token"); PP.Lex(Tok); @@ -133,11 +133,19 @@ public: /// handles string literal concatenation, as per C99 5.1.1.2, translation /// phase #6. void ConsumeStringToken() { - assert(isStringLiteral() && + assert(isTokenStringLiteral() && "Should only consume string literals with this method"); PP.Lex(Tok); } + /// MatchRHSPunctuation - For punctuation with a LHS and RHS (e.g. '['/']'), + /// this helper function matches and consumes the specified RHS token if + /// present. If not present, it emits the specified diagnostic indicating + /// that the parser failed to match the RHS of the token at LHSLoc. LHSName + /// should be the name of the unmatched LHS token. + void MatchRHSPunctuation(tok::TokenKind RHSTok, SourceLocation LHSLoc, + const char *LHSName, unsigned Diag); + private: //===--------------------------------------------------------------------===// // Error recovery.