diff options
Diffstat (limited to 'clang/Parse/ParseDecl.cpp')
| -rw-r--r-- | clang/Parse/ParseDecl.cpp | 101 |
1 files changed, 60 insertions, 41 deletions
diff --git a/clang/Parse/ParseDecl.cpp b/clang/Parse/ParseDecl.cpp index 7dbba29575c..781d09b7bc0 100644 --- a/clang/Parse/ParseDecl.cpp +++ b/clang/Parse/ParseDecl.cpp @@ -579,10 +579,10 @@ void Parser::ParseStructUnionBody(SourceLocation RecordLoc, } } - Actions.ParseRecordBody(RecordLoc, TagDecl, &FieldDecls[0],FieldDecls.size()); - MatchRHSPunctuation(tok::r_brace, LBraceLoc); + Actions.ParseRecordBody(RecordLoc, TagDecl, &FieldDecls[0],FieldDecls.size()); + // If attributes exist after struct contents, parse them. if (Tok.getKind() == tok::kw___attribute) ParseAttributes(); @@ -597,6 +597,25 @@ void Parser::ParseStructUnionBody(SourceLocation RecordLoc, /// '}' attributes[opt] /// 'enum' identifier /// [GNU] 'enum' attributes[opt] identifier +void Parser::ParseEnumSpecifier(DeclSpec &DS) { + assert(Tok.getKind() == tok::kw_enum && "Not an enum specifier"); + SourceLocation StartLoc = ConsumeToken(); + + // Parse the tag portion of this. + DeclTy *TagDecl; + if (ParseTag(TagDecl, DeclSpec::TST_enum, StartLoc)) + return; + + if (Tok.getKind() == tok::l_brace) + ParseEnumBody(StartLoc, TagDecl); + + // TODO: semantic analysis on the declspec for enums. + const char *PrevSpec = 0; + if (DS.SetTypeSpecType(DeclSpec::TST_enum, StartLoc, PrevSpec, TagDecl)) + Diag(StartLoc, diag::err_invalid_decl_spec_combination, PrevSpec); +} + +/// ParseEnumBody - Parse a {} enclosed enumerator-list. /// enumerator-list: /// enumerator /// enumerator-list ',' enumerator @@ -606,55 +625,55 @@ void Parser::ParseStructUnionBody(SourceLocation RecordLoc, /// enumeration-constant: /// identifier /// -void Parser::ParseEnumSpecifier(DeclSpec &DS) { - assert(Tok.getKind() == tok::kw_enum && "Not an enum specifier"); - SourceLocation StartLoc = ConsumeToken(); +void Parser::ParseEnumBody(SourceLocation StartLoc, DeclTy *EnumDecl) { + SourceLocation LBraceLoc = ConsumeBrace(); - // Parse the tag portion of this. - DeclTy *TagDecl; - if (ParseTag(TagDecl, DeclSpec::TST_enum, StartLoc)) - return; + if (Tok.getKind() == tok::r_brace) + Diag(Tok, diag::ext_empty_struct_union_enum, "enum"); - if (Tok.getKind() == tok::l_brace) { - SourceLocation LBraceLoc = ConsumeBrace(); - - if (Tok.getKind() == tok::r_brace) - Diag(Tok, diag::ext_empty_struct_union_enum, "enum"); + SmallVector<DeclTy*, 32> EnumConstantDecls; + + // Parse the enumerator-list. + while (Tok.getKind() == tok::identifier) { + IdentifierInfo *Ident = Tok.getIdentifierInfo(); + SourceLocation IdentLoc = ConsumeToken(); - // Parse the enumerator-list. - while (Tok.getKind() == tok::identifier) { - ConsumeToken(); - - if (Tok.getKind() == tok::equal) { - ConsumeToken(); - ExprResult Res = ParseConstantExpression(); - if (Res.isInvalid) SkipUntil(tok::comma, true, false); - } - - if (Tok.getKind() != tok::comma) - break; - SourceLocation CommaLoc = ConsumeToken(); - - if (Tok.getKind() != tok::identifier && !getLang().C99) - Diag(CommaLoc, diag::ext_c99_enumerator_list_comma); + SourceLocation EqualLoc; + ExprTy *AssignedVal = 0; + if (Tok.getKind() == tok::equal) { + EqualLoc = ConsumeToken(); + ExprResult Res = ParseConstantExpression(); + if (Res.isInvalid) + SkipUntil(tok::comma, true, false); + else + AssignedVal = Res.Val; } - // Eat the }. - MatchRHSPunctuation(tok::r_brace, LBraceLoc); - - // If attributes exist after the identifier list, parse them. - if (Tok.getKind() == tok::kw___attribute) - ParseAttributes(); + // Install the enumerator constant into EnumDecl. + DeclTy *ConstDecl = Actions.ParseEnumConstant(CurScope, EnumDecl, + IdentLoc, Ident, + EqualLoc, AssignedVal); + EnumConstantDecls.push_back(ConstDecl); + + if (Tok.getKind() != tok::comma) + break; + SourceLocation CommaLoc = ConsumeToken(); + + if (Tok.getKind() != tok::identifier && !getLang().C99) + Diag(CommaLoc, diag::ext_c99_enumerator_list_comma); } - // TODO: semantic analysis on the declspec for enums. + // Eat the }. + MatchRHSPunctuation(tok::r_brace, LBraceLoc); + + Actions.ParseEnumBody(StartLoc, EnumDecl, &EnumConstantDecls[0], + EnumConstantDecls.size()); - const char *PrevSpec = 0; - if (DS.SetTypeSpecType(DeclSpec::TST_enum, StartLoc, PrevSpec, TagDecl)) - Diag(StartLoc, diag::err_invalid_decl_spec_combination, PrevSpec); + // If attributes exist after the identifier list, parse them. + if (Tok.getKind() == tok::kw___attribute) + ParseAttributes(); } - /// isTypeSpecifierQualifier - Return true if the current token could be the /// start of a specifier-qualifier-list. bool Parser::isTypeSpecifierQualifier() const { |

