diff options
Diffstat (limited to 'lib/Parse/ParseCXXInlineMethods.cpp')
-rw-r--r-- | lib/Parse/ParseCXXInlineMethods.cpp | 50 |
1 files changed, 28 insertions, 22 deletions
diff --git a/lib/Parse/ParseCXXInlineMethods.cpp b/lib/Parse/ParseCXXInlineMethods.cpp index 87e22fa..5405c0c 100644 --- a/lib/Parse/ParseCXXInlineMethods.cpp +++ b/lib/Parse/ParseCXXInlineMethods.cpp @@ -29,12 +29,14 @@ Parser::ParseCXXInlineMethodDef(AccessSpecifier AS, Declarator &D, "Current token not a '{', ':' or 'try'!"); Action::MultiTemplateParamsArg TemplateParams(Actions, - TemplateInfo.TemplateParams? TemplateInfo.TemplateParams->data() : 0, - TemplateInfo.TemplateParams? TemplateInfo.TemplateParams->size() : 0); + TemplateInfo.TemplateParams ? TemplateInfo.TemplateParams->data() : 0, + TemplateInfo.TemplateParams ? TemplateInfo.TemplateParams->size() : 0); + DeclPtrTy FnD; if (D.getDeclSpec().isFriendSpecified()) // FIXME: Friend templates - FnD = Actions.ActOnFriendFunctionDecl(CurScope, D, true, move(TemplateParams)); + FnD = Actions.ActOnFriendFunctionDecl(CurScope, D, true, + move(TemplateParams)); else // FIXME: pass template information through FnD = Actions.ActOnCXXMemberDeclarator(CurScope, AS, D, move(TemplateParams), 0, 0, @@ -53,7 +55,7 @@ Parser::ParseCXXInlineMethodDef(AccessSpecifier AS, Declarator &D, // We may have a constructor initializer or function-try-block here. if (kind == tok::colon || kind == tok::kw_try) { // Consume everything up to (and including) the left brace. - if (!ConsumeAndStoreUntil(tok::l_brace, tok::unknown, Toks, tok::semi)) { + if (!ConsumeAndStoreUntil(tok::l_brace, Toks)) { // We didn't find the left-brace we expected after the // constructor initializer. if (Tok.is(tok::semi)) { @@ -72,13 +74,13 @@ Parser::ParseCXXInlineMethodDef(AccessSpecifier AS, Declarator &D, ConsumeBrace(); } // Consume everything up to (and including) the matching right brace. - ConsumeAndStoreUntil(tok::r_brace, tok::unknown, Toks); + ConsumeAndStoreUntil(tok::r_brace, Toks, /*StopAtSemi=*/false); // If we're in a function-try-block, we need to store all the catch blocks. if (kind == tok::kw_try) { while (Tok.is(tok::kw_catch)) { - ConsumeAndStoreUntil(tok::l_brace, tok::unknown, Toks); - ConsumeAndStoreUntil(tok::r_brace, tok::unknown, Toks); + ConsumeAndStoreUntil(tok::l_brace, Toks, /*StopAtSemi=*/false); + ConsumeAndStoreUntil(tok::r_brace, Toks, /*StopAtSemi=*/false); } } @@ -98,7 +100,8 @@ void Parser::ParseLexedMethodDeclarations(ParsingClass &Class) { // The current scope is still active if we're the top-level class. // Otherwise we'll need to push and enter a new scope. bool HasClassScope = !Class.TopLevelClass; - ParseScope ClassScope(this, Scope::ClassScope|Scope::DeclScope, HasClassScope); + ParseScope ClassScope(this, Scope::ClassScope|Scope::DeclScope, + HasClassScope); if (HasClassScope) Actions.ActOnStartDelayedMemberDeclarations(CurScope, Class.TagOrTemplate); @@ -217,12 +220,17 @@ void Parser::ParseLexedMethodDefs(ParsingClass &Class) { "ParseFunctionTryBlock left tokens in the token stream!"); continue; } - if (Tok.is(tok::colon)) + if (Tok.is(tok::colon)) { ParseConstructorInitializer(LM.D); - else + + // Error recovery. + if (!Tok.is(tok::l_brace)) { + Actions.ActOnFinishFunctionBody(LM.D, Action::StmtArg(Actions)); + continue; + } + } else Actions.ActOnDefaultCtorInitializers(LM.D); - // FIXME: What if ParseConstructorInitializer doesn't leave us with a '{'?? ParseFunctionStatementBody(LM.D); assert(!PP.getSourceManager().isBeforeInTranslationUnit(origLoc, Tok.getLocation()) && @@ -238,14 +246,12 @@ void Parser::ParseLexedMethodDefs(ParsingClass &Class) { /// ConsumeAndStoreUntil - Consume and store the token at the passed token /// container until the token 'T' is reached (which gets /// consumed/stored too, if ConsumeFinalToken). -/// If EarlyAbortIf is specified, then we will stop early if we find that -/// token at the top level. +/// If StopAtSemi is true, then we will stop early at a ';' character. /// Returns true if token 'T1' or 'T2' was found. /// NOTE: This is a specialized version of Parser::SkipUntil. bool Parser::ConsumeAndStoreUntil(tok::TokenKind T1, tok::TokenKind T2, CachedTokens &Toks, - tok::TokenKind EarlyAbortIf, - bool ConsumeFinalToken) { + bool StopAtSemi, bool ConsumeFinalToken) { // We always want this function to consume at least one token if the first // token isn't T and if not at EOF. bool isFirstTokenConsumed = true; @@ -259,10 +265,6 @@ bool Parser::ConsumeAndStoreUntil(tok::TokenKind T1, tok::TokenKind T2, return true; } - // If we found the early-abort token, return. - if (Tok.is(EarlyAbortIf)) - return false; - switch (Tok.getKind()) { case tok::eof: // Ran out of tokens. @@ -272,19 +274,19 @@ bool Parser::ConsumeAndStoreUntil(tok::TokenKind T1, tok::TokenKind T2, // Recursively consume properly-nested parens. Toks.push_back(Tok); ConsumeParen(); - ConsumeAndStoreUntil(tok::r_paren, tok::unknown, Toks); + ConsumeAndStoreUntil(tok::r_paren, Toks, /*StopAtSemi=*/false); break; case tok::l_square: // Recursively consume properly-nested square brackets. Toks.push_back(Tok); ConsumeBracket(); - ConsumeAndStoreUntil(tok::r_square, tok::unknown, Toks); + ConsumeAndStoreUntil(tok::r_square, Toks, /*StopAtSemi=*/false); break; case tok::l_brace: // Recursively consume properly-nested braces. Toks.push_back(Tok); ConsumeBrace(); - ConsumeAndStoreUntil(tok::r_brace, tok::unknown, Toks); + ConsumeAndStoreUntil(tok::r_brace, Toks, /*StopAtSemi=*/false); break; // Okay, we found a ']' or '}' or ')', which we think should be balanced. @@ -316,6 +318,10 @@ bool Parser::ConsumeAndStoreUntil(tok::TokenKind T1, tok::TokenKind T2, Toks.push_back(Tok); ConsumeStringToken(); break; + case tok::semi: + if (StopAtSemi) + return false; + // FALL THROUGH. default: // consume this token. Toks.push_back(Tok); |