forked from OSchip/llvm-project
Make sure parens/braces/brackets are correctly balanced.
In a line like: (; the semicolon leaves Parser:ParenCount unbalanced (it's 1 even though we stopped looking for a right paren). This may affect later parsing and result in bad recovery for parsing errors. llvm-svn: 106213
This commit is contained in:
parent
fa533e7652
commit
355094ef06
|
@ -72,6 +72,7 @@ namespace prec {
|
|||
class Parser {
|
||||
friend class PragmaUnusedHandler;
|
||||
friend class ColonProtectionRAIIObject;
|
||||
friend class ParenBraceBracketBalancer;
|
||||
PrettyStackTraceParserEntry CrashInfo;
|
||||
|
||||
Preprocessor &PP;
|
||||
|
|
|
@ -309,6 +309,8 @@ AttributeList* Parser::ParseMicrosoftTypeAttributes(AttributeList *CurrAttr) {
|
|||
Parser::DeclGroupPtrTy Parser::ParseDeclaration(unsigned Context,
|
||||
SourceLocation &DeclEnd,
|
||||
CXX0XAttributeList Attr) {
|
||||
ParenBraceBracketBalancer BalancerRAIIObj(*this);
|
||||
|
||||
DeclPtrTy SingleDecl;
|
||||
switch (Tok.getKind()) {
|
||||
case tok::kw_template:
|
||||
|
|
|
@ -77,6 +77,8 @@ Parser::OwningStmtResult
|
|||
Parser::ParseStatementOrDeclaration(bool OnlyStatement) {
|
||||
const char *SemiError = 0;
|
||||
OwningStmtResult Res(Actions);
|
||||
|
||||
ParenBraceBracketBalancer BalancerRAIIObj(*this);
|
||||
|
||||
CXX0XAttributeList Attr;
|
||||
if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier())
|
||||
|
|
|
@ -127,7 +127,16 @@ SourceLocation Parser::MatchRHSPunctuation(tok::TokenKind RHSTok,
|
|||
}
|
||||
Diag(Tok, DID);
|
||||
Diag(LHSLoc, diag::note_matching) << LHSName;
|
||||
SkipUntil(RHSTok);
|
||||
if (!SkipUntil(RHSTok)) {
|
||||
// We stopped before finding a RHS token, e.g. we encountered a ';'.
|
||||
// Balance Paren/Brace/Bracket counting.
|
||||
switch (RHSTok) {
|
||||
default: break;
|
||||
case tok::r_paren : assert(ParenCount > 0); --ParenCount; break;
|
||||
case tok::r_brace : assert(BraceCount > 0); --BraceCount; break;
|
||||
case tok::r_square: assert(BracketCount > 0); --BracketCount; break;
|
||||
}
|
||||
}
|
||||
return R;
|
||||
}
|
||||
|
||||
|
@ -401,6 +410,8 @@ void Parser::ParseTranslationUnit() {
|
|||
///
|
||||
/// [C++0x/GNU] 'extern' 'template' declaration
|
||||
Parser::DeclGroupPtrTy Parser::ParseExternalDeclaration(CXX0XAttributeList Attr) {
|
||||
ParenBraceBracketBalancer BalancerRAIIObj(*this);
|
||||
|
||||
DeclPtrTy SingleDecl;
|
||||
switch (Tok.getKind()) {
|
||||
case tok::semi:
|
||||
|
|
|
@ -80,6 +80,23 @@ namespace clang {
|
|||
}
|
||||
};
|
||||
|
||||
/// \brief RAII object that makes sure paren/bracket/brace count is correct
|
||||
/// after declaration/statement parsing, even when there's a parsing error.
|
||||
class ParenBraceBracketBalancer {
|
||||
Parser &P;
|
||||
unsigned short ParenCount, BracketCount, BraceCount;
|
||||
public:
|
||||
ParenBraceBracketBalancer(Parser &p)
|
||||
: P(p), ParenCount(p.ParenCount), BracketCount(p.BracketCount),
|
||||
BraceCount(p.BraceCount) { }
|
||||
|
||||
~ParenBraceBracketBalancer() {
|
||||
P.ParenCount = ParenCount;
|
||||
P.BracketCount = BracketCount;
|
||||
P.BraceCount = BraceCount;
|
||||
}
|
||||
};
|
||||
|
||||
} // end namespace clang
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue