Parse: use the EOF token method to lex inline method bodies

Mark the end of the method body with an EOF token, collect it once we
expect to be done with method body parsing.  No functionality change
intended.

llvm-svn: 225765
This commit is contained in:
David Majnemer 2015-01-13 05:06:20 +00:00
parent e8ecb2b144
commit a7ea1b1466
2 changed files with 25 additions and 22 deletions

View File

@ -484,10 +484,16 @@ void Parser::ParseLexedMethodDef(LexedMethod &LM) {
Actions.ActOnReenterTemplateScope(getCurScope(), LM.D);
++CurTemplateDepthTracker;
}
// Save the current token position.
SourceLocation origLoc = Tok.getLocation();
assert(!LM.Toks.empty() && "Empty body!");
Token LastBodyToken = LM.Toks.back();
Token BodyEnd;
BodyEnd.startToken();
BodyEnd.setKind(tok::eof);
BodyEnd.setLocation(
LastBodyToken.getLocation().getLocWithOffset(LastBodyToken.getLength()));
BodyEnd.setEofData(LM.D);
LM.Toks.push_back(BodyEnd);
// Append the current token at the end of the new token stream so that it
// doesn't get lost.
LM.Toks.push_back(Tok);
@ -505,12 +511,11 @@ void Parser::ParseLexedMethodDef(LexedMethod &LM) {
if (Tok.is(tok::kw_try)) {
ParseFunctionTryBlock(LM.D, FnScope);
assert(!PP.getSourceManager().isBeforeInTranslationUnit(origLoc,
Tok.getLocation()) &&
"ParseFunctionTryBlock went over the cached tokens!");
// There could be leftover tokens (e.g. because of an error).
// Skip through until we reach the original token position.
while (Tok.getLocation() != origLoc && Tok.isNot(tok::eof))
while (Tok.isNot(tok::eof))
ConsumeAnyToken();
if (Tok.is(tok::eof) && Tok.getEofData() == LM.D)
ConsumeAnyToken();
return;
}
@ -521,7 +526,11 @@ void Parser::ParseLexedMethodDef(LexedMethod &LM) {
if (!Tok.is(tok::l_brace)) {
FnScope.Exit();
Actions.ActOnFinishFunctionBody(LM.D, nullptr);
while (Tok.getLocation() != origLoc && Tok.isNot(tok::eof))
while (Tok.isNot(tok::eof))
ConsumeAnyToken();
if (Tok.is(tok::eof) && Tok.getEofData() == LM.D)
ConsumeAnyToken();
return;
}
@ -541,17 +550,11 @@ void Parser::ParseLexedMethodDef(LexedMethod &LM) {
if (LM.D)
LM.D->getAsFunction()->setLateTemplateParsed(false);
if (Tok.getLocation() != origLoc) {
// Due to parsing error, we either went over the cached tokens or
// there are still cached tokens left. If it's the latter case skip the
// leftover tokens.
// Since this is an uncommon situation that should be avoided, use the
// expensive isBeforeInTranslationUnit call.
if (PP.getSourceManager().isBeforeInTranslationUnit(Tok.getLocation(),
origLoc))
while (Tok.getLocation() != origLoc && Tok.isNot(tok::eof))
ConsumeAnyToken();
}
while (Tok.isNot(tok::eof))
ConsumeAnyToken();
if (Tok.is(tok::eof) && Tok.getEofData() == LM.D)
ConsumeAnyToken();
if (CXXMethodDecl *MD = dyn_cast_or_null<CXXMethodDecl>(LM.D))
Actions.ActOnFinishInlineMethodDef(MD);

View File

@ -66,12 +66,12 @@ namespace PR16480 {
struct T { int n; };
template<typename> struct A { int n; };
}; // expected-error +{{}}
};
// FIXME: This is valid now, but may be made ill-formed by DR1607.
struct G : X<0> {
G() : X<0 && [](){return 0;}()>{} // expected-error +{{}}
}; // expected-error +{{}}
};
struct Errs : X<0> {
Errs(X<0>) : decltype X<0>() {} // expected-error {{expected '(' after 'decltype'}}