aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/Parse/ParseExpr.cpp1
-rw-r--r--lib/Parse/ParseExprCXX.cpp2
-rw-r--r--lib/Parse/Parser.cpp8
-rw-r--r--lib/Parse/RAIIObjectsForParser.h75
4 files changed, 79 insertions, 7 deletions
diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp
index 6d31396cc0..2a1fba655a 100644
--- a/lib/Parse/ParseExpr.cpp
+++ b/lib/Parse/ParseExpr.cpp
@@ -1888,7 +1888,6 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr,
bool isTypeCast, ParsedType &CastTy,
SourceLocation &RParenLoc) {
assert(Tok.is(tok::l_paren) && "Not a paren expr!");
- GreaterThanIsOperatorScope G(GreaterThanIsOperator, true);
BalancedDelimiterTracker T(*this, tok::l_paren);
if (T.consumeOpen())
return ExprError();
diff --git a/lib/Parse/ParseExprCXX.cpp b/lib/Parse/ParseExprCXX.cpp
index 715218448a..68eff7cf5f 100644
--- a/lib/Parse/ParseExprCXX.cpp
+++ b/lib/Parse/ParseExprCXX.cpp
@@ -1235,8 +1235,6 @@ Parser::ParseCXXTypeConstructExpression(const DeclSpec &DS) {
MultiExprArg(&InitList, 1),
SourceLocation());
} else {
- GreaterThanIsOperatorScope G(GreaterThanIsOperator, true);
-
BalancedDelimiterTracker T(*this, tok::l_paren);
T.consumeOpen();
diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp
index 56b6641bd8..0d7d047e00 100644
--- a/lib/Parse/Parser.cpp
+++ b/lib/Parse/Parser.cpp
@@ -1704,13 +1704,13 @@ Parser::DeclGroupPtrTy Parser::ParseModuleImport(SourceLocation AtLoc) {
return Actions.ConvertDeclToDeclGroup(Import.get());
}
-bool Parser::BalancedDelimiterTracker::diagnoseOverflow() {
+bool BalancedDelimiterTracker::diagnoseOverflow() {
P.Diag(P.Tok, diag::err_parser_impl_limit_overflow);
P.SkipUntil(tok::eof);
return true;
}
-bool Parser::BalancedDelimiterTracker::expectAndConsume(unsigned DiagID,
+bool BalancedDelimiterTracker::expectAndConsume(unsigned DiagID,
const char *Msg,
tok::TokenKind SkipToToc ) {
LOpen = P.Tok.getLocation();
@@ -1723,7 +1723,7 @@ bool Parser::BalancedDelimiterTracker::expectAndConsume(unsigned DiagID,
return diagnoseOverflow();
}
-bool Parser::BalancedDelimiterTracker::diagnoseMissingClose() {
+bool BalancedDelimiterTracker::diagnoseMissingClose() {
assert(!P.Tok.is(Close) && "Should have consumed closing delimiter");
const char *LHSName = "unknown";
@@ -1741,6 +1741,6 @@ bool Parser::BalancedDelimiterTracker::diagnoseMissingClose() {
return true;
}
-void Parser::BalancedDelimiterTracker::skipToEnd() {
+void BalancedDelimiterTracker::skipToEnd() {
P.SkipUntil(Close, false);
}
diff --git a/lib/Parse/RAIIObjectsForParser.h b/lib/Parse/RAIIObjectsForParser.h
index 64431276bf..e13c4cfeb3 100644
--- a/lib/Parse/RAIIObjectsForParser.h
+++ b/lib/Parse/RAIIObjectsForParser.h
@@ -332,6 +332,81 @@ namespace clang {
}
};
+ /// \brief RAII class that helps handle the parsing of an open/close delimiter
+ /// pair, such as braces { ... } or parentheses ( ... ).
+ class BalancedDelimiterTracker : public GreaterThanIsOperatorScope {
+ Parser& P;
+ tok::TokenKind Kind, Close;
+ SourceLocation (Parser::*Consumer)();
+ SourceLocation LOpen, LClose;
+
+ unsigned short &getDepth() {
+ switch (Kind) {
+ 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)
+ : GreaterThanIsOperatorScope(p.GreaterThanIsOperator, true),
+ 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() {
+ 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() {
+ if (P.Tok.is(Close)) {
+ LClose = (P.*Consumer)();
+ return false;
+ }
+
+ return diagnoseMissingClose();
+ }
+ void skipToEnd();
+ };
+
} // end namespace clang
#endif