Added Parser::ParseStructDeclaration() as a result of refactoring Parser::ParseStructUnionBody().

Motivation: Objective-C can now share this rule. It also makes Parser::ParseStructUnionBody()
a bit smaller/cleaner..

llvm-svn: 41201
This commit is contained in:
Steve Naroff 2007-08-20 22:28:22 +00:00
parent 1eb1ad6c36
commit 9717080968
2 changed files with 82 additions and 74 deletions

View File

@ -599,16 +599,7 @@ void Parser::ParseStructUnionSpecifier(DeclSpec &DS) {
Diag(StartLoc, diag::err_invalid_decl_spec_combination, PrevSpec); Diag(StartLoc, diag::err_invalid_decl_spec_combination, PrevSpec);
} }
/// ParseStructDeclaration
/// ParseStructUnionBody
/// struct-contents:
/// struct-declaration-list
/// [EXT] empty
/// [GNU] "struct-declaration-list" without terminatoring ';'
/// struct-declaration-list:
/// struct-declaration
/// struct-declaration-list struct-declaration
/// [OBC] '@' 'defs' '(' class-name ')' [TODO]
/// struct-declaration: /// struct-declaration:
/// specifier-qualifier-list struct-declarator-list ';' /// specifier-qualifier-list struct-declarator-list ';'
/// [GNU] __extension__ struct-declaration /// [GNU] __extension__ struct-declaration
@ -623,6 +614,83 @@ void Parser::ParseStructUnionSpecifier(DeclSpec &DS) {
/// declarator[opt] ':' constant-expression /// declarator[opt] ':' constant-expression
/// [GNU] declarator[opt] ':' constant-expression attributes[opt] /// [GNU] declarator[opt] ':' constant-expression attributes[opt]
/// ///
void Parser::ParseStructDeclaration(DeclTy *TagDecl,
llvm::SmallVector<DeclTy*, 32> &FieldDecls) {
// FIXME: When __extension__ is specified, disable extension diagnostics.
if (Tok.getKind() == tok::kw___extension__)
ConsumeToken();
// Parse the common specifier-qualifiers-list piece.
DeclSpec DS;
SourceLocation SpecQualLoc = Tok.getLocation();
ParseSpecifierQualifierList(DS);
// TODO: Does specifier-qualifier list correctly check that *something* is
// specified?
// If there are no declarators, issue a warning.
if (Tok.getKind() == tok::semi) {
Diag(SpecQualLoc, diag::w_no_declarators);
ConsumeToken();
return;
}
// Read struct-declarators until we find the semicolon.
Declarator DeclaratorInfo(DS, Declarator::MemberContext);
while (1) {
/// struct-declarator: declarator
/// struct-declarator: declarator[opt] ':' constant-expression
if (Tok.getKind() != tok::colon)
ParseDeclarator(DeclaratorInfo);
ExprTy *BitfieldSize = 0;
if (Tok.getKind() == tok::colon) {
ConsumeToken();
ExprResult Res = ParseConstantExpression();
if (Res.isInvalid) {
SkipUntil(tok::semi, true, true);
} else {
BitfieldSize = Res.Val;
}
}
// If attributes exist after the declarator, parse them.
if (Tok.getKind() == tok::kw___attribute)
DeclaratorInfo.AddAttributes(ParseAttributes());
// Install the declarator into the current TagDecl.
DeclTy *Field = Actions.ParseField(CurScope, TagDecl, SpecQualLoc,
DeclaratorInfo, BitfieldSize);
FieldDecls.push_back(Field);
// If we don't have a comma, it is either the end of the list (a ';')
// or an error, bail out.
if (Tok.getKind() != tok::comma)
break;
// Consume the comma.
ConsumeToken();
// Parse the next declarator.
DeclaratorInfo.clear();
// Attributes are only allowed on the second declarator.
if (Tok.getKind() == tok::kw___attribute)
DeclaratorInfo.AddAttributes(ParseAttributes());
}
return;
}
/// ParseStructUnionBody
/// struct-contents:
/// struct-declaration-list
/// [EXT] empty
/// [GNU] "struct-declaration-list" without terminatoring ';'
/// struct-declaration-list:
/// struct-declaration
/// struct-declaration-list struct-declaration
/// [OBC] '@' 'defs' '(' class-name ')' [TODO]
///
void Parser::ParseStructUnionBody(SourceLocation RecordLoc, void Parser::ParseStructUnionBody(SourceLocation RecordLoc,
unsigned TagType, DeclTy *TagDecl) { unsigned TagType, DeclTy *TagDecl) {
SourceLocation LBraceLoc = ConsumeBrace(); SourceLocation LBraceLoc = ConsumeBrace();
@ -646,70 +714,8 @@ void Parser::ParseStructUnionBody(SourceLocation RecordLoc,
ConsumeToken(); ConsumeToken();
continue; continue;
} }
ParseStructDeclaration(TagDecl, FieldDecls);
// FIXME: When __extension__ is specified, disable extension diagnostics.
if (Tok.getKind() == tok::kw___extension__)
ConsumeToken();
// Parse the common specifier-qualifiers-list piece.
DeclSpec DS;
SourceLocation SpecQualLoc = Tok.getLocation();
ParseSpecifierQualifierList(DS);
// TODO: Does specifier-qualifier list correctly check that *something* is
// specified?
// If there are no declarators, issue a warning.
if (Tok.getKind() == tok::semi) {
Diag(SpecQualLoc, diag::w_no_declarators);
ConsumeToken();
continue;
}
// Read struct-declarators until we find the semicolon.
Declarator DeclaratorInfo(DS, Declarator::MemberContext);
while (1) {
/// struct-declarator: declarator
/// struct-declarator: declarator[opt] ':' constant-expression
if (Tok.getKind() != tok::colon)
ParseDeclarator(DeclaratorInfo);
ExprTy *BitfieldSize = 0;
if (Tok.getKind() == tok::colon) {
ConsumeToken();
ExprResult Res = ParseConstantExpression();
if (Res.isInvalid) {
SkipUntil(tok::semi, true, true);
} else {
BitfieldSize = Res.Val;
}
}
// If attributes exist after the declarator, parse them.
if (Tok.getKind() == tok::kw___attribute)
DeclaratorInfo.AddAttributes(ParseAttributes());
// Install the declarator into the current TagDecl.
DeclTy *Field = Actions.ParseField(CurScope, TagDecl, SpecQualLoc,
DeclaratorInfo, BitfieldSize);
FieldDecls.push_back(Field);
// If we don't have a comma, it is either the end of the list (a ';')
// or an error, bail out.
if (Tok.getKind() != tok::comma)
break;
// Consume the comma.
ConsumeToken();
// Parse the next declarator.
DeclaratorInfo.clear();
// Attributes are only allowed on the second declarator.
if (Tok.getKind() == tok::kw___attribute)
DeclaratorInfo.AddAttributes(ParseAttributes());
}
if (Tok.getKind() == tok::semi) { if (Tok.getKind() == tok::semi) {
ConsumeToken(); ConsumeToken();
} else if (Tok.getKind() == tok::r_brace) { } else if (Tok.getKind() == tok::r_brace) {

View File

@ -359,7 +359,9 @@ private:
void ParseStructUnionSpecifier(DeclSpec &DS); void ParseStructUnionSpecifier(DeclSpec &DS);
void ParseStructUnionBody(SourceLocation StartLoc, unsigned TagType, void ParseStructUnionBody(SourceLocation StartLoc, unsigned TagType,
DeclTy *TagDecl); DeclTy *TagDecl);
void ParseStructDeclaration(DeclTy *TagDecl,
llvm::SmallVector<DeclTy*, 32> &FieldDecls);
bool isDeclarationSpecifier() const; bool isDeclarationSpecifier() const;
bool isTypeSpecifierQualifier() const; bool isTypeSpecifierQualifier() const;