summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/tools/clang/lib/Parse/Parser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Parse/Parser.cpp')
-rw-r--r--contrib/llvm/tools/clang/lib/Parse/Parser.cpp86
1 files changed, 76 insertions, 10 deletions
diff --git a/contrib/llvm/tools/clang/lib/Parse/Parser.cpp b/contrib/llvm/tools/clang/lib/Parse/Parser.cpp
index 0574a63..b3eeb9d 100644
--- a/contrib/llvm/tools/clang/lib/Parse/Parser.cpp
+++ b/contrib/llvm/tools/clang/lib/Parse/Parser.cpp
@@ -282,6 +282,7 @@ bool Parser::SkipUntil(ArrayRef<tok::TokenKind> Toks, SkipUntilFlags Flags) {
// Ran out of tokens.
return false;
+ case tok::annot_pragma_openmp:
case tok::annot_pragma_openmp_end:
// Stop before an OpenMP pragma boundary.
case tok::annot_module_begin:
@@ -1067,10 +1068,17 @@ Decl *Parser::ParseFunctionDefinition(ParsingDeclarator &D,
// Tell the actions module that we have entered a function definition with the
// specified Declarator for the function.
- Decl *Res = TemplateInfo.TemplateParams?
- Actions.ActOnStartOfFunctionTemplateDef(getCurScope(),
- *TemplateInfo.TemplateParams, D)
- : Actions.ActOnStartOfFunctionDef(getCurScope(), D);
+ Sema::SkipBodyInfo SkipBody;
+ Decl *Res = Actions.ActOnStartOfFunctionDef(getCurScope(), D,
+ TemplateInfo.TemplateParams
+ ? *TemplateInfo.TemplateParams
+ : MultiTemplateParamsArg(),
+ &SkipBody);
+
+ if (SkipBody.ShouldSkip) {
+ SkipFunctionBody();
+ return Res;
+ }
// Break out of the ParsingDeclarator context before we parse the body.
D.complete(Res);
@@ -1086,14 +1094,16 @@ Decl *Parser::ParseFunctionDefinition(ParsingDeclarator &D,
SourceLocation KWLoc;
if (TryConsumeToken(tok::kw_delete, KWLoc)) {
Diag(KWLoc, getLangOpts().CPlusPlus11
- ? diag::warn_cxx98_compat_deleted_function
- : diag::ext_deleted_function);
+ ? diag::warn_cxx98_compat_defaulted_deleted_function
+ : diag::ext_defaulted_deleted_function)
+ << 1 /* deleted */;
Actions.SetDeclDeleted(Res, KWLoc);
Delete = true;
} else if (TryConsumeToken(tok::kw_default, KWLoc)) {
Diag(KWLoc, getLangOpts().CPlusPlus11
- ? diag::warn_cxx98_compat_defaulted_function
- : diag::ext_defaulted_function);
+ ? diag::warn_cxx98_compat_defaulted_deleted_function
+ : diag::ext_defaulted_deleted_function)
+ << 0 /* defaulted */;
Actions.SetDeclDefaulted(Res, KWLoc);
} else {
llvm_unreachable("function definition after = not 'delete' or 'default'");
@@ -1137,6 +1147,28 @@ Decl *Parser::ParseFunctionDefinition(ParsingDeclarator &D,
return ParseFunctionStatementBody(Res, BodyScope);
}
+void Parser::SkipFunctionBody() {
+ if (Tok.is(tok::equal)) {
+ SkipUntil(tok::semi);
+ return;
+ }
+
+ bool IsFunctionTryBlock = Tok.is(tok::kw_try);
+ if (IsFunctionTryBlock)
+ ConsumeToken();
+
+ CachedTokens Skipped;
+ if (ConsumeAndStoreFunctionPrologue(Skipped))
+ SkipMalformedDecl();
+ else {
+ SkipUntil(tok::r_brace);
+ while (IsFunctionTryBlock && Tok.is(tok::kw_catch)) {
+ SkipUntil(tok::l_brace);
+ SkipUntil(tok::r_brace);
+ }
+ }
+}
+
/// ParseKNRParamDeclarations - Parse 'declaration-list[opt]' which provides
/// types for a function with a K&R-style identifier list for arguments.
void Parser::ParseKNRParamDeclarations(Declarator &D) {
@@ -1493,7 +1525,7 @@ bool Parser::TryKeywordIdentFallback(bool DisableKeyword) {
<< PP.getSpelling(Tok)
<< DisableKeyword;
if (DisableKeyword)
- Tok.getIdentifierInfo()->RevertTokenIDToIdentifier();
+ Tok.getIdentifierInfo()->revertTokenIDToIdentifier();
Tok.setKind(tok::identifier);
return true;
}
@@ -1989,6 +2021,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;
@@ -2016,7 +2079,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
OpenPOWER on IntegriCloud