forked from OSchip/llvm-project
Switch ParseStructDeclaration to a callback-based API. This will make
it easier to track within Sema whether the parser is parsing a declaration. llvm-svn: 85855
This commit is contained in:
parent
616798c31f
commit
cfefb6d197
|
@ -979,8 +979,12 @@ private:
|
||||||
void ParseEnumBody(SourceLocation StartLoc, DeclPtrTy TagDecl);
|
void ParseEnumBody(SourceLocation StartLoc, DeclPtrTy TagDecl);
|
||||||
void ParseStructUnionBody(SourceLocation StartLoc, unsigned TagType,
|
void ParseStructUnionBody(SourceLocation StartLoc, unsigned TagType,
|
||||||
DeclPtrTy TagDecl);
|
DeclPtrTy TagDecl);
|
||||||
void ParseStructDeclaration(DeclSpec &DS,
|
|
||||||
llvm::SmallVectorImpl<FieldDeclarator> &Fields);
|
struct FieldCallback {
|
||||||
|
virtual DeclPtrTy invoke(FieldDeclarator &Field) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
void ParseStructDeclaration(DeclSpec &DS, FieldCallback &Callback);
|
||||||
|
|
||||||
bool isDeclarationSpecifier();
|
bool isDeclarationSpecifier();
|
||||||
bool isTypeSpecifierQualifier();
|
bool isTypeSpecifierQualifier();
|
||||||
|
|
|
@ -1468,8 +1468,7 @@ bool Parser::ParseOptionalTypeSpecifier(DeclSpec &DS, bool& isInvalid,
|
||||||
/// [GNU] declarator[opt] ':' constant-expression attributes[opt]
|
/// [GNU] declarator[opt] ':' constant-expression attributes[opt]
|
||||||
///
|
///
|
||||||
void Parser::
|
void Parser::
|
||||||
ParseStructDeclaration(DeclSpec &DS,
|
ParseStructDeclaration(DeclSpec &DS, FieldCallback &Fields) {
|
||||||
llvm::SmallVectorImpl<FieldDeclarator> &Fields) {
|
|
||||||
if (Tok.is(tok::kw___extension__)) {
|
if (Tok.is(tok::kw___extension__)) {
|
||||||
// __extension__ silences extension warnings in the subexpression.
|
// __extension__ silences extension warnings in the subexpression.
|
||||||
ExtensionRAIIObject O(Diags); // Use RAII to do this.
|
ExtensionRAIIObject O(Diags); // Use RAII to do this.
|
||||||
|
@ -1489,9 +1488,16 @@ ParseStructDeclaration(DeclSpec &DS,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read struct-declarators until we find the semicolon.
|
// Read struct-declarators until we find the semicolon.
|
||||||
Fields.push_back(FieldDeclarator(DS));
|
bool FirstDeclarator = true;
|
||||||
while (1) {
|
while (1) {
|
||||||
FieldDeclarator &DeclaratorInfo = Fields.back();
|
FieldDeclarator DeclaratorInfo(DS);
|
||||||
|
|
||||||
|
// Attributes are only allowed here on successive declarators.
|
||||||
|
if (!FirstDeclarator && Tok.is(tok::kw___attribute)) {
|
||||||
|
SourceLocation Loc;
|
||||||
|
AttributeList *AttrList = ParseAttributes(&Loc);
|
||||||
|
DeclaratorInfo.D.AddAttributes(AttrList, Loc);
|
||||||
|
}
|
||||||
|
|
||||||
/// struct-declarator: declarator
|
/// struct-declarator: declarator
|
||||||
/// struct-declarator: declarator[opt] ':' constant-expression
|
/// struct-declarator: declarator[opt] ':' constant-expression
|
||||||
|
@ -1514,6 +1520,9 @@ ParseStructDeclaration(DeclSpec &DS,
|
||||||
DeclaratorInfo.D.AddAttributes(AttrList, Loc);
|
DeclaratorInfo.D.AddAttributes(AttrList, Loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We're done with this declarator; invoke the callback.
|
||||||
|
(void) Fields.invoke(DeclaratorInfo);
|
||||||
|
|
||||||
// If we don't have a comma, it is either the end of the list (a ';')
|
// If we don't have a comma, it is either the end of the list (a ';')
|
||||||
// or an error, bail out.
|
// or an error, bail out.
|
||||||
if (Tok.isNot(tok::comma))
|
if (Tok.isNot(tok::comma))
|
||||||
|
@ -1522,15 +1531,7 @@ ParseStructDeclaration(DeclSpec &DS,
|
||||||
// Consume the comma.
|
// Consume the comma.
|
||||||
ConsumeToken();
|
ConsumeToken();
|
||||||
|
|
||||||
// Parse the next declarator.
|
FirstDeclarator = false;
|
||||||
Fields.push_back(FieldDeclarator(DS));
|
|
||||||
|
|
||||||
// Attributes are only allowed on the second declarator.
|
|
||||||
if (Tok.is(tok::kw___attribute)) {
|
|
||||||
SourceLocation Loc;
|
|
||||||
AttributeList *AttrList = ParseAttributes(&Loc);
|
|
||||||
Fields.back().D.AddAttributes(AttrList, Loc);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1562,7 +1563,6 @@ void Parser::ParseStructUnionBody(SourceLocation RecordLoc,
|
||||||
<< DeclSpec::getSpecifierName((DeclSpec::TST)TagType);
|
<< DeclSpec::getSpecifierName((DeclSpec::TST)TagType);
|
||||||
|
|
||||||
llvm::SmallVector<DeclPtrTy, 32> FieldDecls;
|
llvm::SmallVector<DeclPtrTy, 32> FieldDecls;
|
||||||
llvm::SmallVector<FieldDeclarator, 8> FieldDeclarators;
|
|
||||||
|
|
||||||
// While we still have something to read, read the declarations in the struct.
|
// While we still have something to read, read the declarations in the struct.
|
||||||
while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
|
while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
|
||||||
|
@ -1578,28 +1578,39 @@ void Parser::ParseStructUnionBody(SourceLocation RecordLoc,
|
||||||
|
|
||||||
// Parse all the comma separated declarators.
|
// Parse all the comma separated declarators.
|
||||||
DeclSpec DS;
|
DeclSpec DS;
|
||||||
FieldDeclarators.clear();
|
|
||||||
if (!Tok.is(tok::at)) {
|
|
||||||
ParseStructDeclaration(DS, FieldDeclarators);
|
|
||||||
|
|
||||||
// Convert them all to fields.
|
if (!Tok.is(tok::at)) {
|
||||||
for (unsigned i = 0, e = FieldDeclarators.size(); i != e; ++i) {
|
struct CFieldCallback : FieldCallback {
|
||||||
FieldDeclarator &FD = FieldDeclarators[i];
|
Parser &P;
|
||||||
DeclPtrTy Field;
|
DeclPtrTy TagDecl;
|
||||||
// Install the declarator into the current TagDecl.
|
llvm::SmallVectorImpl<DeclPtrTy> &FieldDecls;
|
||||||
if (FD.D.getExtension()) {
|
|
||||||
// Silences extension warnings
|
CFieldCallback(Parser &P, DeclPtrTy TagDecl,
|
||||||
ExtensionRAIIObject O(Diags);
|
llvm::SmallVectorImpl<DeclPtrTy> &FieldDecls) :
|
||||||
Field = Actions.ActOnField(CurScope, TagDecl,
|
P(P), TagDecl(TagDecl), FieldDecls(FieldDecls) {}
|
||||||
DS.getSourceRange().getBegin(),
|
|
||||||
FD.D, FD.BitfieldSize);
|
virtual DeclPtrTy invoke(FieldDeclarator &FD) {
|
||||||
} else {
|
const DeclSpec &DS = FD.D.getDeclSpec();
|
||||||
Field = Actions.ActOnField(CurScope, TagDecl,
|
DeclPtrTy Field;
|
||||||
DS.getSourceRange().getBegin(),
|
|
||||||
FD.D, FD.BitfieldSize);
|
// Install the declarator into the current TagDecl.
|
||||||
|
if (FD.D.getExtension()) {
|
||||||
|
// Silences extension warnings
|
||||||
|
ExtensionRAIIObject O(P.Diags);
|
||||||
|
Field = P.Actions.ActOnField(P.CurScope, TagDecl,
|
||||||
|
DS.getSourceRange().getBegin(),
|
||||||
|
FD.D, FD.BitfieldSize);
|
||||||
|
} else {
|
||||||
|
Field = P.Actions.ActOnField(P.CurScope, TagDecl,
|
||||||
|
DS.getSourceRange().getBegin(),
|
||||||
|
FD.D, FD.BitfieldSize);
|
||||||
|
}
|
||||||
|
FieldDecls.push_back(Field);
|
||||||
|
return Field;
|
||||||
}
|
}
|
||||||
FieldDecls.push_back(Field);
|
} Callback(*this, TagDecl, FieldDecls);
|
||||||
}
|
|
||||||
|
ParseStructDeclaration(DS, Callback);
|
||||||
} else { // Handle @defs
|
} else { // Handle @defs
|
||||||
ConsumeToken();
|
ConsumeToken();
|
||||||
if (!Tok.isObjCAtKeyword(tok::objc_defs)) {
|
if (!Tok.isObjCAtKeyword(tok::objc_defs)) {
|
||||||
|
|
|
@ -305,51 +305,68 @@ void Parser::ParseObjCInterfaceDeclList(DeclPtrTy interfaceDecl,
|
||||||
if (Tok.is(tok::l_paren))
|
if (Tok.is(tok::l_paren))
|
||||||
ParseObjCPropertyAttribute(OCDS);
|
ParseObjCPropertyAttribute(OCDS);
|
||||||
|
|
||||||
|
struct ObjCPropertyCallback : FieldCallback {
|
||||||
|
Parser &P;
|
||||||
|
DeclPtrTy IDecl;
|
||||||
|
llvm::SmallVectorImpl<DeclPtrTy> &Props;
|
||||||
|
ObjCDeclSpec &OCDS;
|
||||||
|
SourceLocation AtLoc;
|
||||||
|
tok::ObjCKeywordKind MethodImplKind;
|
||||||
|
|
||||||
|
ObjCPropertyCallback(Parser &P, DeclPtrTy IDecl,
|
||||||
|
llvm::SmallVectorImpl<DeclPtrTy> &Props,
|
||||||
|
ObjCDeclSpec &OCDS, SourceLocation AtLoc,
|
||||||
|
tok::ObjCKeywordKind MethodImplKind) :
|
||||||
|
P(P), IDecl(IDecl), Props(Props), OCDS(OCDS), AtLoc(AtLoc),
|
||||||
|
MethodImplKind(MethodImplKind) {
|
||||||
|
}
|
||||||
|
|
||||||
|
DeclPtrTy invoke(FieldDeclarator &FD) {
|
||||||
|
if (FD.D.getIdentifier() == 0) {
|
||||||
|
P.Diag(AtLoc, diag::err_objc_property_requires_field_name)
|
||||||
|
<< FD.D.getSourceRange();
|
||||||
|
return DeclPtrTy();
|
||||||
|
}
|
||||||
|
if (FD.BitfieldSize) {
|
||||||
|
P.Diag(AtLoc, diag::err_objc_property_bitfield)
|
||||||
|
<< FD.D.getSourceRange();
|
||||||
|
return DeclPtrTy();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Install the property declarator into interfaceDecl.
|
||||||
|
IdentifierInfo *SelName =
|
||||||
|
OCDS.getGetterName() ? OCDS.getGetterName() : FD.D.getIdentifier();
|
||||||
|
|
||||||
|
Selector GetterSel =
|
||||||
|
P.PP.getSelectorTable().getNullarySelector(SelName);
|
||||||
|
IdentifierInfo *SetterName = OCDS.getSetterName();
|
||||||
|
Selector SetterSel;
|
||||||
|
if (SetterName)
|
||||||
|
SetterSel = P.PP.getSelectorTable().getSelector(1, &SetterName);
|
||||||
|
else
|
||||||
|
SetterSel = SelectorTable::constructSetterName(P.PP.getIdentifierTable(),
|
||||||
|
P.PP.getSelectorTable(),
|
||||||
|
FD.D.getIdentifier());
|
||||||
|
bool isOverridingProperty = false;
|
||||||
|
DeclPtrTy Property =
|
||||||
|
P.Actions.ActOnProperty(P.CurScope, AtLoc, FD, OCDS,
|
||||||
|
GetterSel, SetterSel, IDecl,
|
||||||
|
&isOverridingProperty,
|
||||||
|
MethodImplKind);
|
||||||
|
if (!isOverridingProperty)
|
||||||
|
Props.push_back(Property);
|
||||||
|
|
||||||
|
return Property;
|
||||||
|
}
|
||||||
|
} Callback(*this, interfaceDecl, allProperties,
|
||||||
|
OCDS, AtLoc, MethodImplKind);
|
||||||
|
|
||||||
// Parse all the comma separated declarators.
|
// Parse all the comma separated declarators.
|
||||||
DeclSpec DS;
|
DeclSpec DS;
|
||||||
llvm::SmallVector<FieldDeclarator, 8> FieldDeclarators;
|
ParseStructDeclaration(DS, Callback);
|
||||||
ParseStructDeclaration(DS, FieldDeclarators);
|
|
||||||
|
|
||||||
ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list, "",
|
ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list, "",
|
||||||
tok::at);
|
tok::at);
|
||||||
|
|
||||||
// Convert them all to property declarations.
|
|
||||||
for (unsigned i = 0, e = FieldDeclarators.size(); i != e; ++i) {
|
|
||||||
FieldDeclarator &FD = FieldDeclarators[i];
|
|
||||||
if (FD.D.getIdentifier() == 0) {
|
|
||||||
Diag(AtLoc, diag::err_objc_property_requires_field_name)
|
|
||||||
<< FD.D.getSourceRange();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (FD.BitfieldSize) {
|
|
||||||
Diag(AtLoc, diag::err_objc_property_bitfield)
|
|
||||||
<< FD.D.getSourceRange();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Install the property declarator into interfaceDecl.
|
|
||||||
IdentifierInfo *SelName =
|
|
||||||
OCDS.getGetterName() ? OCDS.getGetterName() : FD.D.getIdentifier();
|
|
||||||
|
|
||||||
Selector GetterSel =
|
|
||||||
PP.getSelectorTable().getNullarySelector(SelName);
|
|
||||||
IdentifierInfo *SetterName = OCDS.getSetterName();
|
|
||||||
Selector SetterSel;
|
|
||||||
if (SetterName)
|
|
||||||
SetterSel = PP.getSelectorTable().getSelector(1, &SetterName);
|
|
||||||
else
|
|
||||||
SetterSel = SelectorTable::constructSetterName(PP.getIdentifierTable(),
|
|
||||||
PP.getSelectorTable(),
|
|
||||||
FD.D.getIdentifier());
|
|
||||||
bool isOverridingProperty = false;
|
|
||||||
DeclPtrTy Property = Actions.ActOnProperty(CurScope, AtLoc, FD, OCDS,
|
|
||||||
GetterSel, SetterSel,
|
|
||||||
interfaceDecl,
|
|
||||||
&isOverridingProperty,
|
|
||||||
MethodImplKind);
|
|
||||||
if (!isOverridingProperty)
|
|
||||||
allProperties.push_back(Property);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -858,7 +875,6 @@ void Parser::ParseObjCClassInstanceVariables(DeclPtrTy interfaceDecl,
|
||||||
SourceLocation atLoc) {
|
SourceLocation atLoc) {
|
||||||
assert(Tok.is(tok::l_brace) && "expected {");
|
assert(Tok.is(tok::l_brace) && "expected {");
|
||||||
llvm::SmallVector<DeclPtrTy, 32> AllIvarDecls;
|
llvm::SmallVector<DeclPtrTy, 32> AllIvarDecls;
|
||||||
llvm::SmallVector<FieldDeclarator, 8> FieldDeclarators;
|
|
||||||
|
|
||||||
ParseScope ClassScope(this, Scope::DeclScope|Scope::ClassScope);
|
ParseScope ClassScope(this, Scope::DeclScope|Scope::ClassScope);
|
||||||
|
|
||||||
|
@ -893,21 +909,31 @@ void Parser::ParseObjCClassInstanceVariables(DeclPtrTy interfaceDecl,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct ObjCIvarCallback : FieldCallback {
|
||||||
|
Parser &P;
|
||||||
|
DeclPtrTy IDecl;
|
||||||
|
tok::ObjCKeywordKind visibility;
|
||||||
|
llvm::SmallVectorImpl<DeclPtrTy> &AllIvarDecls;
|
||||||
|
|
||||||
|
ObjCIvarCallback(Parser &P, DeclPtrTy IDecl, tok::ObjCKeywordKind V,
|
||||||
|
llvm::SmallVectorImpl<DeclPtrTy> &AllIvarDecls) :
|
||||||
|
P(P), IDecl(IDecl), visibility(V), AllIvarDecls(AllIvarDecls) {
|
||||||
|
}
|
||||||
|
|
||||||
|
DeclPtrTy invoke(FieldDeclarator &FD) {
|
||||||
|
// Install the declarator into the interface decl.
|
||||||
|
DeclPtrTy Field
|
||||||
|
= P.Actions.ActOnIvar(P.CurScope,
|
||||||
|
FD.D.getDeclSpec().getSourceRange().getBegin(),
|
||||||
|
IDecl, FD.D, FD.BitfieldSize, visibility);
|
||||||
|
AllIvarDecls.push_back(Field);
|
||||||
|
return Field;
|
||||||
|
}
|
||||||
|
} Callback(*this, interfaceDecl, visibility, AllIvarDecls);
|
||||||
|
|
||||||
// Parse all the comma separated declarators.
|
// Parse all the comma separated declarators.
|
||||||
DeclSpec DS;
|
DeclSpec DS;
|
||||||
FieldDeclarators.clear();
|
ParseStructDeclaration(DS, Callback);
|
||||||
ParseStructDeclaration(DS, FieldDeclarators);
|
|
||||||
|
|
||||||
// Convert them all to fields.
|
|
||||||
for (unsigned i = 0, e = FieldDeclarators.size(); i != e; ++i) {
|
|
||||||
FieldDeclarator &FD = FieldDeclarators[i];
|
|
||||||
// Install the declarator into interfaceDecl.
|
|
||||||
DeclPtrTy Field = Actions.ActOnIvar(CurScope,
|
|
||||||
DS.getSourceRange().getBegin(),
|
|
||||||
interfaceDecl,
|
|
||||||
FD.D, FD.BitfieldSize, visibility);
|
|
||||||
AllIvarDecls.push_back(Field);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Tok.is(tok::semi)) {
|
if (Tok.is(tok::semi)) {
|
||||||
ConsumeToken();
|
ConsumeToken();
|
||||||
|
|
Loading…
Reference in New Issue