forked from OSchip/llvm-project
Parse: Replace polymorphic functor objects with lambdas and llvm::function_ref.
No change in functionality. llvm-svn: 217025
This commit is contained in:
parent
12ad3b1911
commit
a39beb9dd6
|
@ -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();
|
||||||
|
|
|
@ -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)) {
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
Loading…
Reference in New Issue