diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-06-25 21:37:02 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-06-25 21:37:02 +0000 |
commit | 369b9f997cc2bf19aebe0220ab484b80c5932eb2 (patch) | |
tree | ca6bfb0919b31794f0c6e133bbe2a81b55a48a7f /clang/lib/Parse/ParseDecl.cpp | |
parent | c272bab5a51067accdfc29d6339d3ce8717baf9e (diff) | |
download | bcm5719-llvm-369b9f997cc2bf19aebe0220ab484b80c5932eb2.tar.gz bcm5719-llvm-369b9f997cc2bf19aebe0220ab484b80c5932eb2.zip |
Extend the "expected ';' after struct" logic to also apply to enums, and to
struct and enum forward-declarations.
llvm-svn: 159164
Diffstat (limited to 'clang/lib/Parse/ParseDecl.cpp')
-rw-r--r-- | clang/lib/Parse/ParseDecl.cpp | 27 |
1 files changed, 23 insertions, 4 deletions
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index 96c57581e85..7d0f9c22cb0 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -3156,8 +3156,17 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS, } else { TUK = Sema::TUK_Definition; } - } else if (Tok.is(tok::semi) && DSC != DSC_type_specifier) { - TUK = (DS.isFriendSpecified() ? Sema::TUK_Friend : Sema::TUK_Declaration); + } else if (DSC != DSC_type_specifier && + (Tok.is(tok::semi) || + (Tok.isAtStartOfLine() && !isValidAfterTypeSpecifier()))) { + TUK = DS.isFriendSpecified() ? Sema::TUK_Friend : Sema::TUK_Declaration; + if (Tok.isNot(tok::semi)) { + // A semicolon was missing after this declaration. Diagnose and recover. + ExpectAndConsume(tok::semi, diag::err_expected_semi_after_tagdecl, + "enum"); + PP.EnterToken(Tok); + Tok.setKind(tok::semi); + } } else { TUK = Sema::TUK_Reference; } @@ -3248,9 +3257,8 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS, return; } - if (Tok.is(tok::l_brace) && TUK != Sema::TUK_Reference) { + if (Tok.is(tok::l_brace) && TUK != Sema::TUK_Reference) ParseEnumBody(StartLoc, TagDecl); - } if (DS.SetTypeSpecType(DeclSpec::TST_enum, StartLoc, NameLoc.isValid() ? NameLoc : StartLoc, @@ -3355,6 +3363,17 @@ void Parser::ParseEnumBody(SourceLocation StartLoc, Decl *EnumDecl) { EnumScope.Exit(); Actions.ActOnTagFinishDefinition(getCurScope(), EnumDecl, T.getCloseLocation()); + + // The next token must be valid after an enum definition. If not, a ';' + // was probably forgotten. + if (!isValidAfterTypeSpecifier()) { + ExpectAndConsume(tok::semi, diag::err_expected_semi_after_tagdecl, "enum"); + // Push this token back into the preprocessor and change our current token + // to ';' so that the rest of the code recovers as though there were an + // ';' after the definition. + PP.EnterToken(Tok); + Tok.setKind(tok::semi); + } } /// isTypeSpecifierQualifier - Return true if the current token could be the |