summaryrefslogtreecommitdiffstats
path: root/clang/Parse/ParseDecl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/Parse/ParseDecl.cpp')
-rw-r--r--clang/Parse/ParseDecl.cpp101
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 {
OpenPOWER on IntegriCloud