From: Douglas Gregor Date: Thu, 8 Mar 2012 01:00:17 +0000 (+0000) Subject: Streamline BalancedDelimiterTracker, by eliminating the duplicate X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d78ef5b941ce2937228b010e8443f92025f9d683;p=clang Streamline BalancedDelimiterTracker, by eliminating the duplicate paren/brace/bracket tracking (the Consume* functions already did it), removing the use of ConsumeAnyToken(), and moving the hot paths inline with the error paths out-of-line. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@152274 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h index cf8f978c9e..abc3717cef 100644 --- a/include/clang/Parse/Parser.h +++ b/include/clang/Parse/Parser.h @@ -432,88 +432,78 @@ private: return PP.LookAhead(0); } - class BalancedDelimiterTracker; - - /// \brief Tracks information about the current nesting depth of - /// opening delimiters of each kind. - class DelimiterTracker { - private: - friend class Parser; - friend class BalancedDelimiterTracker; - - unsigned Paren, Brace, Square, Less, LLLess; - unsigned& get(tok::TokenKind t) { - switch (t) { - default: llvm_unreachable("Unexpected balanced token"); - case tok::l_brace: return Brace; - case tok::l_paren: return Paren; - case tok::l_square: return Square; - case tok::less: return Less; - case tok::lesslessless: return LLLess; - } - } - - void push(tok::TokenKind t) { - get(t)++; - } - - void pop(tok::TokenKind t) { - get(t)--; - } - - unsigned getDepth(tok::TokenKind t) { - return get(t); - } - - public: - DelimiterTracker() : Paren(0), Brace(0), Square(0), Less(0), LLLess(0) { } - }; - /// \brief RAII class that helps handle the parsing of an open/close delimiter /// pair, such as braces { ... } or parentheses ( ... ). class BalancedDelimiterTracker { - tok::TokenKind Kind, Close; Parser& P; - bool Cleanup; - const unsigned MaxDepth; + tok::TokenKind Kind, Close; + SourceLocation (Parser::*Consumer)(); SourceLocation LOpen, LClose; - void assignClosingDelimiter() { + unsigned short &getDepth() { switch (Kind) { - default: llvm_unreachable("Unexpected balanced token"); - case tok::l_brace: Close = tok::r_brace; break; - case tok::l_paren: Close = tok::r_paren; break; - case tok::l_square: Close = tok::r_square; break; - case tok::less: Close = tok::greater; break; - case tok::lesslessless: Close = tok::greatergreatergreater; break; + case tok::l_brace: return P.BraceCount; + case tok::l_square: return P.BracketCount; + case tok::l_paren: return P.ParenCount; + default: llvm_unreachable("Wrong token kind"); } } - + + enum { MaxDepth = 256 }; + + bool diagnoseOverflow(); + bool diagnoseMissingClose(); + public: - BalancedDelimiterTracker(Parser& p, tok::TokenKind k) - : Kind(k), P(p), Cleanup(false), MaxDepth(256) { - assignClosingDelimiter(); - } - - ~BalancedDelimiterTracker() { - if (Cleanup) - P.QuantityTracker.pop(Kind); + BalancedDelimiterTracker(Parser& p, tok::TokenKind k) : P(p), Kind(k) { + switch (Kind) { + default: llvm_unreachable("Unexpected balanced token"); + case tok::l_brace: + Close = tok::r_brace; + Consumer = &Parser::ConsumeBrace; + break; + case tok::l_paren: + Close = tok::r_paren; + Consumer = &Parser::ConsumeParen; + break; + + case tok::l_square: + Close = tok::r_square; + Consumer = &Parser::ConsumeBracket; + break; + } } SourceLocation getOpenLocation() const { return LOpen; } SourceLocation getCloseLocation() const { return LClose; } SourceRange getRange() const { return SourceRange(LOpen, LClose); } - bool consumeOpen(); + bool consumeOpen() { + if (!P.Tok.is(Kind)) + return true; + + if (getDepth() < MaxDepth) { + LOpen = (P.*Consumer)(); + return false; + } + + return diagnoseOverflow(); + } + bool expectAndConsume(unsigned DiagID, const char *Msg = "", tok::TokenKind SkipToTok = tok::unknown); - bool consumeClose(); + bool consumeClose() { + if (P.Tok.is(Close)) { + LClose = (P.*Consumer)(); + return false; + } + + return diagnoseMissingClose(); + } void skipToEnd(); }; - DelimiterTracker QuantityTracker; - /// getTypeAnnotation - Read a parsed type out of an annotation token. static ParsedType getTypeAnnotation(Token &Tok) { return ParsedType::getFromOpaquePtr(Tok.getAnnotationValue()); diff --git a/lib/Parse/ParseCXXInlineMethods.cpp b/lib/Parse/ParseCXXInlineMethods.cpp index 8cec31ca0d..6fe33f4860 100644 --- a/lib/Parse/ParseCXXInlineMethods.cpp +++ b/lib/Parse/ParseCXXInlineMethods.cpp @@ -193,7 +193,7 @@ void Parser::ParseCXXNonStaticMemberInitializer(Decl *VarD) { tok::TokenKind kind = Tok.getKind(); if (kind == tok::equal) { Toks.push_back(Tok); - ConsumeAnyToken(); + ConsumeToken(); } if (kind == tok::l_brace) { diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index 3a261f010d..e3d31e34ba 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -818,7 +818,7 @@ void Parser::ParseLexedAttribute(LateParsedAttribute &LA, if (PP.getSourceManager().isBeforeInTranslationUnit(Tok.getLocation(), OrigLoc)) while (Tok.getLocation() != OrigLoc && Tok.isNot(tok::eof)) - ConsumeAnyToken(); + ConsumeAnyToken(); } } diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp index a1c3b05030..669b5b8ba4 100644 --- a/lib/Parse/ParseExpr.cpp +++ b/lib/Parse/ParseExpr.cpp @@ -1318,22 +1318,27 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) { Expr *ExecConfig = 0; - BalancedDelimiterTracker LLLT(*this, tok::lesslessless); BalancedDelimiterTracker PT(*this, tok::l_paren); if (OpKind == tok::lesslessless) { ExprVector ExecConfigExprs(Actions); CommaLocsTy ExecConfigCommaLocs; - LLLT.consumeOpen(); + SourceLocation OpenLoc = ConsumeToken(); if (ParseExpressionList(ExecConfigExprs, ExecConfigCommaLocs)) { LHS = ExprError(); } - if (LHS.isInvalid()) { + SourceLocation CloseLoc = Tok.getLocation(); + if (Tok.is(tok::greatergreatergreater)) { + ConsumeToken(); + } else if (LHS.isInvalid()) { SkipUntil(tok::greatergreatergreater); - } else if (LLLT.consumeClose()) { + } else { // There was an error closing the brackets + Diag(Tok, diag::err_expected_ggg); + Diag(OpenLoc, diag::note_matching) << "<<<"; + SkipUntil(tok::greatergreatergreater); LHS = ExprError(); } @@ -1346,9 +1351,9 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) { if (!LHS.isInvalid()) { ExprResult ECResult = Actions.ActOnCUDAExecConfigExpr(getCurScope(), - LLLT.getOpenLocation(), + OpenLoc, move_arg(ExecConfigExprs), - LLLT.getCloseLocation()); + CloseLoc); if (ECResult.isInvalid()) LHS = ExprError(); else diff --git a/lib/Parse/ParseObjc.cpp b/lib/Parse/ParseObjc.cpp index 971c7d4887..3309b84a23 100644 --- a/lib/Parse/ParseObjc.cpp +++ b/lib/Parse/ParseObjc.cpp @@ -1192,7 +1192,7 @@ ParseObjCProtocolReferences(SmallVectorImpl &Protocols, return true; } - EndLoc = ConsumeAnyToken(); + EndLoc = ConsumeToken(); // Convert the list of protocols identifiers into a list of protocol decls. Actions.FindProtocolDeclaration(WarnOnDeclarations, diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp index 8b1765df39..725a8f8c30 100644 --- a/lib/Parse/Parser.cpp +++ b/lib/Parse/Parser.cpp @@ -1651,68 +1651,43 @@ Parser::DeclGroupPtrTy Parser::ParseModuleImport(SourceLocation AtLoc) { return Actions.ConvertDeclToDeclGroup(Import.get()); } -bool Parser::BalancedDelimiterTracker::consumeOpen() { - // Try to consume the token we are holding - if (P.Tok.is(Kind)) { - P.QuantityTracker.push(Kind); - Cleanup = true; - if (P.QuantityTracker.getDepth(Kind) < MaxDepth) { - LOpen = P.ConsumeAnyToken(); - return false; - } else { - P.Diag(P.Tok, diag::err_parser_impl_limit_overflow); - P.SkipUntil(tok::eof); - } - } - return true; +bool Parser::BalancedDelimiterTracker::diagnoseOverflow() { + P.Diag(P.Tok, diag::err_parser_impl_limit_overflow); + P.SkipUntil(tok::eof); + return true; } bool Parser::BalancedDelimiterTracker::expectAndConsume(unsigned DiagID, const char *Msg, tok::TokenKind SkipToToc ) { LOpen = P.Tok.getLocation(); - if (!P.ExpectAndConsume(Kind, DiagID, Msg, SkipToToc)) { - P.QuantityTracker.push(Kind); - Cleanup = true; - if (P.QuantityTracker.getDepth(Kind) < MaxDepth) { - return false; - } else { - P.Diag(P.Tok, diag::err_parser_impl_limit_overflow); - P.SkipUntil(tok::eof); - } - } - return true; + if (P.ExpectAndConsume(Kind, DiagID, Msg, SkipToToc)) + return true; + + if (getDepth() < MaxDepth) + return false; + + return diagnoseOverflow(); } -bool Parser::BalancedDelimiterTracker::consumeClose() { - if (P.Tok.is(Close)) { - LClose = P.ConsumeAnyToken(); - if (Cleanup) - P.QuantityTracker.pop(Kind); - - Cleanup = false; - return false; - } else { - const char *LHSName = "unknown"; - diag::kind DID = diag::err_parse_error; - switch (Close) { - default: break; - case tok::r_paren : LHSName = "("; DID = diag::err_expected_rparen; break; - case tok::r_brace : LHSName = "{"; DID = diag::err_expected_rbrace; break; - case tok::r_square: LHSName = "["; DID = diag::err_expected_rsquare; break; - case tok::greater: LHSName = "<"; DID = diag::err_expected_greater; break; - case tok::greatergreatergreater: - LHSName = "<<<"; DID = diag::err_expected_ggg; break; - } - P.Diag(P.Tok, DID); - P.Diag(LOpen, diag::note_matching) << LHSName; - if (P.SkipUntil(Close)) - LClose = P.Tok.getLocation(); +bool Parser::BalancedDelimiterTracker::diagnoseMissingClose() { + assert(!P.Tok.is(Close) && "Should have consumed closing delimiter"); + + const char *LHSName = "unknown"; + diag::kind DID = diag::err_parse_error; + switch (Close) { + default: break; + case tok::r_paren : LHSName = "("; DID = diag::err_expected_rparen; break; + case tok::r_brace : LHSName = "{"; DID = diag::err_expected_rbrace; break; + case tok::r_square: LHSName = "["; DID = diag::err_expected_rsquare; break; } + P.Diag(P.Tok, DID); + P.Diag(LOpen, diag::note_matching) << LHSName; + if (P.SkipUntil(Close)) + LClose = P.Tok.getLocation(); return true; } void Parser::BalancedDelimiterTracker::skipToEnd() { P.SkipUntil(Close, false); - Cleanup = false; }