diff options
Diffstat (limited to 'clang/lib/Parse')
| -rw-r--r-- | clang/lib/Parse/ParseDecl.cpp | 3 | ||||
| -rw-r--r-- | clang/lib/Parse/ParseDeclCXX.cpp | 8 | ||||
| -rw-r--r-- | clang/lib/Parse/ParseStmt.cpp | 3 | ||||
| -rw-r--r-- | clang/lib/Parse/Parser.cpp | 36 |
4 files changed, 44 insertions, 6 deletions
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index 80d25426f66..f5983c0295e 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -3589,7 +3589,8 @@ void Parser::ParseStructUnionBody(SourceLocation RecordLoc, SmallVector<Decl *, 32> FieldDecls; // While we still have something to read, read the declarations in the struct. - while (Tok.isNot(tok::r_brace) && !isEofOrEom()) { + while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof) && + !tryParseMisplacedModuleImport()) { // Each iteration of this loop reads one struct-declaration. // Check for extraneous top-level semicolon. diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index 1a0d262279f..5e59d5dba28 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -210,7 +210,8 @@ void Parser::ParseInnerNamespace(std::vector<SourceLocation> &IdentLoc, ParsedAttributes &attrs, BalancedDelimiterTracker &Tracker) { if (index == Ident.size()) { - while (Tok.isNot(tok::r_brace) && !isEofOrEom()) { + while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof) && + !tryParseMisplacedModuleImport()) { ParsedAttributesWithRange attrs(AttrFactory); MaybeParseCXX11Attributes(attrs); MaybeParseMicrosoftAttributes(attrs); @@ -3063,11 +3064,12 @@ void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc, if (TagDecl) { // While we still have something to read, read the member-declarations. - while (Tok.isNot(tok::r_brace) && !isEofOrEom()) + while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof) && + !tryParseMisplacedModuleImport()) { // Each iteration of this loop reads one member-declaration. ParseCXXClassMemberDeclarationWithPragmas( CurAS, AccessAttrs, static_cast<DeclSpec::TST>(TagType), TagDecl); - + } T.consumeClose(); } else { SkipUntil(tok::r_brace); diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp index b658cef234e..312c5e6f511 100644 --- a/clang/lib/Parse/ParseStmt.cpp +++ b/clang/lib/Parse/ParseStmt.cpp @@ -944,7 +944,8 @@ StmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) { Stmts.push_back(R.get()); } - while (Tok.isNot(tok::r_brace) && !isEofOrEom()) { + while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof) && + !tryParseMisplacedModuleImport()) { if (Tok.is(tok::annot_pragma_unused)) { HandlePragmaUnused(); continue; diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp index 35e853f64fc..5b0704658a2 100644 --- a/clang/lib/Parse/Parser.cpp +++ b/clang/lib/Parse/Parser.cpp @@ -2018,6 +2018,37 @@ Parser::DeclGroupPtrTy Parser::ParseModuleImport(SourceLocation AtLoc) { return Actions.ConvertDeclToDeclGroup(Import.get()); } +/// \brief Try recover parser when module annotation appears where it must not +/// be found. +/// \returns false if the recover was successful and parsing may be continued, or +/// true if parser must bail out to top level and handle the token there. +bool Parser::parseMisplacedModuleImport() { + while (true) { + switch (Tok.getKind()) { + case tok::annot_module_end: + // Inform caller that recovery failed, the error must be handled at upper + // level. + return true; + case tok::annot_module_begin: + Actions.diagnoseMisplacedModuleImport(reinterpret_cast<Module *>( + Tok.getAnnotationValue()), Tok.getLocation()); + return true; + case tok::annot_module_include: + // Module import found where it should not be, for instance, inside a + // namespace. Recover by importing the module. + Actions.ActOnModuleInclude(Tok.getLocation(), + reinterpret_cast<Module *>( + Tok.getAnnotationValue())); + ConsumeToken(); + // If there is another module import, process it. + continue; + default: + return false; + } + } + return false; +} + bool BalancedDelimiterTracker::diagnoseOverflow() { P.Diag(P.Tok, diag::err_bracket_depth_exceeded) << P.getLangOpts().BracketDepth; @@ -2045,7 +2076,10 @@ bool BalancedDelimiterTracker::expectAndConsume(unsigned DiagID, bool BalancedDelimiterTracker::diagnoseMissingClose() { assert(!P.Tok.is(Close) && "Should have consumed closing delimiter"); - P.Diag(P.Tok, diag::err_expected) << Close; + if (P.Tok.is(tok::annot_module_end)) + P.Diag(P.Tok, diag::err_missing_before_module_end) << Close; + else + P.Diag(P.Tok, diag::err_expected) << Close; P.Diag(LOpen, diag::note_matching) << Kind; // If we're not already at some kind of closing bracket, skip to our closing |

