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:
parent
1eb1ad6c36
commit
9717080968
|
@ -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) {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue