diff options
| author | Serge Pavlov <sepavloff@gmail.com> | 2015-09-19 05:32:57 +0000 |
|---|---|---|
| committer | Serge Pavlov <sepavloff@gmail.com> | 2015-09-19 05:32:57 +0000 |
| commit | c4e04a29640335082eec854bbfdcf3d3a1f897c3 (patch) | |
| tree | b969eed8446a32911bea64ca2705fe4dbc01f7b6 /clang/lib/Parse | |
| parent | 0510cd5161bf66747bccf09dbbe6728029efa83c (diff) | |
| download | bcm5719-llvm-c4e04a29640335082eec854bbfdcf3d3a1f897c3.tar.gz bcm5719-llvm-c4e04a29640335082eec854bbfdcf3d3a1f897c3.zip | |
[Modules] More descriptive diagnostics for misplaced import directive
If an import directive was put into wrong context, the error message was obscure,
complaining on misbalanced braces. To get more descriptive messages, annotation
tokens related to modules are processed where they must not be seen.
Differential Revision: http://reviews.llvm.org/D11844
llvm-svn: 248085
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 |

