Parse: Replace polymorphic functor objects with lambdas and llvm::function_ref.

No change in functionality.

llvm-svn: 217025
This commit is contained in:
Benjamin Kramer 2014-09-03 11:06:10 +00:00
parent 12ad3b1911
commit a39beb9dd6
4 changed files with 65 additions and 134 deletions

View File

@ -1782,16 +1782,9 @@ private:
void ParseStructUnionBody(SourceLocation StartLoc, unsigned TagType, void ParseStructUnionBody(SourceLocation StartLoc, unsigned TagType,
Decl *TagDecl); Decl *TagDecl);
struct FieldCallback { void ParseStructDeclaration(
virtual void invoke(ParsingFieldDeclarator &Field) = 0; ParsingDeclSpec &DS,
virtual ~FieldCallback() {} llvm::function_ref<void(ParsingFieldDeclarator &)> FieldsCallback);
private:
virtual void _anchor();
};
struct ObjCPropertyCallback;
void ParseStructDeclaration(ParsingDeclSpec &DS, FieldCallback &Callback);
bool isDeclarationSpecifier(bool DisambiguatingWithExpression = false); bool isDeclarationSpecifier(bool DisambiguatingWithExpression = false);
bool isTypeSpecifierQualifier(); bool isTypeSpecifierQualifier();

View File

@ -3235,14 +3235,15 @@ void Parser::ParseDeclarationSpecifiers(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:: void Parser::ParseStructDeclaration(
ParseStructDeclaration(ParsingDeclSpec &DS, FieldCallback &Fields) { ParsingDeclSpec &DS,
llvm::function_ref<void(ParsingFieldDeclarator &)> FieldsCallback) {
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.
ConsumeToken(); ConsumeToken();
return ParseStructDeclaration(DS, Fields); return ParseStructDeclaration(DS, FieldsCallback);
} }
// Parse the common specifier-qualifiers-list piece. // Parse the common specifier-qualifiers-list piece.
@ -3289,7 +3290,7 @@ ParseStructDeclaration(ParsingDeclSpec &DS, FieldCallback &Fields) {
MaybeParseGNUAttributes(DeclaratorInfo.D); MaybeParseGNUAttributes(DeclaratorInfo.D);
// We're done with this declarator; invoke the callback. // We're done with this declarator; invoke the callback.
Fields.invoke(DeclaratorInfo); FieldsCallback(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.
@ -3353,28 +3354,19 @@ void Parser::ParseStructUnionBody(SourceLocation RecordLoc,
} }
if (!Tok.is(tok::at)) { if (!Tok.is(tok::at)) {
struct CFieldCallback : FieldCallback { auto CFieldCallback = [&](ParsingFieldDeclarator &FD) {
Parser &P; // Install the declarator into the current TagDecl.
Decl *TagDecl; Decl *Field =
SmallVectorImpl<Decl *> &FieldDecls; Actions.ActOnField(getCurScope(), TagDecl,
FD.D.getDeclSpec().getSourceRange().getBegin(),
CFieldCallback(Parser &P, Decl *TagDecl, FD.D, FD.BitfieldSize);
SmallVectorImpl<Decl *> &FieldDecls) : FieldDecls.push_back(Field);
P(P), TagDecl(TagDecl), FieldDecls(FieldDecls) {} FD.complete(Field);
};
void invoke(ParsingFieldDeclarator &FD) override {
// Install the declarator into the current TagDecl.
Decl *Field = P.Actions.ActOnField(P.getCurScope(), TagDecl,
FD.D.getDeclSpec().getSourceRange().getBegin(),
FD.D, FD.BitfieldSize);
FieldDecls.push_back(Field);
FD.complete(Field);
}
} Callback(*this, TagDecl, FieldDecls);
// Parse all the comma separated declarators. // Parse all the comma separated declarators.
ParsingDeclSpec DS(*this); ParsingDeclSpec DS(*this);
ParseStructDeclaration(DS, Callback); ParseStructDeclaration(DS, CFieldCallback);
} else { // Handle @defs } else { // Handle @defs
ConsumeToken(); ConsumeToken();
if (!Tok.isObjCAtKeyword(tok::objc_defs)) { if (!Tok.isObjCAtKeyword(tok::objc_defs)) {

View File

@ -307,72 +307,6 @@ Decl *Parser::ParseObjCAtInterfaceDeclaration(SourceLocation AtLoc,
return ClsType; return ClsType;
} }
/// The Objective-C property callback. This should be defined where
/// it's used, but instead it's been lifted to here to support VS2005.
struct Parser::ObjCPropertyCallback : FieldCallback {
private:
virtual void anchor();
public:
Parser &P;
SmallVectorImpl<Decl *> &Props;
ObjCDeclSpec &OCDS;
SourceLocation AtLoc;
SourceLocation LParenLoc;
tok::ObjCKeywordKind MethodImplKind;
ObjCPropertyCallback(Parser &P,
SmallVectorImpl<Decl *> &Props,
ObjCDeclSpec &OCDS, SourceLocation AtLoc,
SourceLocation LParenLoc,
tok::ObjCKeywordKind MethodImplKind) :
P(P), Props(Props), OCDS(OCDS), AtLoc(AtLoc), LParenLoc(LParenLoc),
MethodImplKind(MethodImplKind) {
}
void invoke(ParsingFieldDeclarator &FD) override {
if (FD.D.getIdentifier() == nullptr) {
P.Diag(AtLoc, diag::err_objc_property_requires_field_name)
<< FD.D.getSourceRange();
return;
}
if (FD.BitfieldSize) {
P.Diag(AtLoc, diag::err_objc_property_bitfield)
<< FD.D.getSourceRange();
return;
}
// 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::constructSetterSelector(P.PP.getIdentifierTable(),
P.PP.getSelectorTable(),
FD.D.getIdentifier());
bool isOverridingProperty = false;
Decl *Property =
P.Actions.ActOnProperty(P.getCurScope(), AtLoc, LParenLoc,
FD, OCDS,
GetterSel, SetterSel,
&isOverridingProperty,
MethodImplKind);
if (!isOverridingProperty)
Props.push_back(Property);
FD.complete(Property);
}
};
void Parser::ObjCPropertyCallback::anchor() {
}
/// objc-interface-decl-list: /// objc-interface-decl-list:
/// empty /// empty
/// objc-interface-decl-list objc-property-decl [OBJC2] /// objc-interface-decl-list objc-property-decl [OBJC2]
@ -511,12 +445,44 @@ void Parser::ParseObjCInterfaceDeclList(tok::ObjCKeywordKind contextKey,
ParseObjCPropertyAttribute(OCDS); ParseObjCPropertyAttribute(OCDS);
} }
ObjCPropertyCallback Callback(*this, allProperties, auto ObjCPropertyCallback = [&](ParsingFieldDeclarator &FD) {
OCDS, AtLoc, LParenLoc, MethodImplKind); if (FD.D.getIdentifier() == nullptr) {
Diag(AtLoc, diag::err_objc_property_requires_field_name)
<< FD.D.getSourceRange();
return;
}
if (FD.BitfieldSize) {
Diag(AtLoc, diag::err_objc_property_bitfield)
<< FD.D.getSourceRange();
return;
}
// 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::constructSetterSelector(
PP.getIdentifierTable(), PP.getSelectorTable(),
FD.D.getIdentifier());
bool isOverridingProperty = false;
Decl *Property = Actions.ActOnProperty(
getCurScope(), AtLoc, LParenLoc, FD, OCDS, GetterSel, SetterSel,
&isOverridingProperty, MethodImplKind);
if (!isOverridingProperty)
allProperties.push_back(Property);
FD.complete(Property);
};
// Parse all the comma separated declarators. // Parse all the comma separated declarators.
ParsingDeclSpec DS(*this); ParsingDeclSpec DS(*this);
ParseStructDeclaration(DS, Callback); ParseStructDeclaration(DS, ObjCPropertyCallback);
ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list); ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list);
break; break;
@ -1338,35 +1304,22 @@ void Parser::ParseObjCClassInstanceVariables(Decl *interfaceDecl,
Sema::PCC_ObjCInstanceVariableList); Sema::PCC_ObjCInstanceVariableList);
return cutOffParsing(); return cutOffParsing();
} }
struct ObjCIvarCallback : FieldCallback {
Parser &P;
Decl *IDecl;
tok::ObjCKeywordKind visibility;
SmallVectorImpl<Decl *> &AllIvarDecls;
ObjCIvarCallback(Parser &P, Decl *IDecl, tok::ObjCKeywordKind V, auto ObjCIvarCallback = [&](ParsingFieldDeclarator &FD) {
SmallVectorImpl<Decl *> &AllIvarDecls) : Actions.ActOnObjCContainerStartDefinition(interfaceDecl);
P(P), IDecl(IDecl), visibility(V), AllIvarDecls(AllIvarDecls) { // Install the declarator into the interface decl.
} Decl *Field = Actions.ActOnIvar(
getCurScope(), FD.D.getDeclSpec().getSourceRange().getBegin(), FD.D,
FD.BitfieldSize, visibility);
Actions.ActOnObjCContainerFinishDefinition();
if (Field)
AllIvarDecls.push_back(Field);
FD.complete(Field);
};
void invoke(ParsingFieldDeclarator &FD) override {
P.Actions.ActOnObjCContainerStartDefinition(IDecl);
// Install the declarator into the interface decl.
Decl *Field
= P.Actions.ActOnIvar(P.getCurScope(),
FD.D.getDeclSpec().getSourceRange().getBegin(),
FD.D, FD.BitfieldSize, visibility);
P.Actions.ActOnObjCContainerFinishDefinition();
if (Field)
AllIvarDecls.push_back(Field);
FD.complete(Field);
}
} Callback(*this, interfaceDecl, visibility, AllIvarDecls);
// Parse all the comma separated declarators. // Parse all the comma separated declarators.
ParsingDeclSpec DS(*this); ParsingDeclSpec DS(*this);
ParseStructDeclaration(DS, Callback); ParseStructDeclaration(DS, ObjCIvarCallback);
if (Tok.is(tok::semi)) { if (Tok.is(tok::semi)) {
ConsumeToken(); ConsumeToken();

View File

@ -1756,13 +1756,6 @@ SourceLocation Parser::handleUnexpectedCodeCompletionToken() {
return PrevTokLocation; return PrevTokLocation;
} }
// Anchor the Parser::FieldCallback vtable to this translation unit.
// We use a spurious method instead of the destructor because
// destroying FieldCallbacks can actually be slightly
// performance-sensitive.
void Parser::FieldCallback::_anchor() {
}
// Code-completion pass-through functions // Code-completion pass-through functions
void Parser::CodeCompleteDirective(bool InConditional) { void Parser::CodeCompleteDirective(bool InConditional) {