mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-12-26 09:49:48 +00:00
Move late-parsed class member attribute handling adjacent to all the
other late-parsed class component handling. No functionality change intended.
This commit is contained in:
parent
e49584a34a
commit
4f5f6c1b83
@ -225,6 +225,7 @@ Parser::LateParsedDeclaration::~LateParsedDeclaration() {}
|
||||
void Parser::LateParsedDeclaration::ParseLexedMethodDeclarations() {}
|
||||
void Parser::LateParsedDeclaration::ParseLexedMemberInitializers() {}
|
||||
void Parser::LateParsedDeclaration::ParseLexedMethodDefs() {}
|
||||
void Parser::LateParsedDeclaration::ParseLexedAttributes() {}
|
||||
void Parser::LateParsedDeclaration::ParseLexedPragmas() {}
|
||||
|
||||
Parser::LateParsedClass::LateParsedClass(Parser *P, ParsingClass *C)
|
||||
@ -246,6 +247,10 @@ void Parser::LateParsedClass::ParseLexedMethodDefs() {
|
||||
Self->ParseLexedMethodDefs(*Class);
|
||||
}
|
||||
|
||||
void Parser::LateParsedClass::ParseLexedAttributes() {
|
||||
Self->ParseLexedAttributes(*Class);
|
||||
}
|
||||
|
||||
void Parser::LateParsedClass::ParseLexedPragmas() {
|
||||
Self->ParseLexedPragmas(*Class);
|
||||
}
|
||||
@ -262,6 +267,10 @@ void Parser::LateParsedMemberInitializer::ParseLexedMemberInitializers() {
|
||||
Self->ParseLexedMemberInitializer(*this);
|
||||
}
|
||||
|
||||
void Parser::LateParsedAttribute::ParseLexedAttributes() {
|
||||
Self->ParseLexedAttribute(*this, true, false);
|
||||
}
|
||||
|
||||
void Parser::LateParsedPragma::ParseLexedPragmas() {
|
||||
Self->ParseLexedPragma(*this);
|
||||
}
|
||||
@ -662,6 +671,141 @@ void Parser::ParseLexedMemberInitializer(LateParsedMemberInitializer &MI) {
|
||||
ConsumeAnyToken();
|
||||
}
|
||||
|
||||
/// Wrapper class which calls ParseLexedAttribute, after setting up the
|
||||
/// scope appropriately.
|
||||
void Parser::ParseLexedAttributes(ParsingClass &Class) {
|
||||
// Deal with templates
|
||||
// FIXME: Test cases to make sure this does the right thing for templates.
|
||||
bool HasTemplateScope = !Class.TopLevelClass && Class.TemplateScope;
|
||||
ParseScope ClassTemplateScope(this, Scope::TemplateParamScope,
|
||||
HasTemplateScope);
|
||||
if (HasTemplateScope)
|
||||
Actions.ActOnReenterTemplateScope(getCurScope(), Class.TagOrTemplate);
|
||||
|
||||
// Set or update the scope flags.
|
||||
bool AlreadyHasClassScope = Class.TopLevelClass;
|
||||
unsigned ScopeFlags = Scope::ClassScope|Scope::DeclScope;
|
||||
ParseScope ClassScope(this, ScopeFlags, !AlreadyHasClassScope);
|
||||
ParseScopeFlags ClassScopeFlags(this, ScopeFlags, AlreadyHasClassScope);
|
||||
|
||||
// Enter the scope of nested classes
|
||||
if (!AlreadyHasClassScope)
|
||||
Actions.ActOnStartDelayedMemberDeclarations(getCurScope(),
|
||||
Class.TagOrTemplate);
|
||||
if (!Class.LateParsedDeclarations.empty()) {
|
||||
for (unsigned i = 0, ni = Class.LateParsedDeclarations.size(); i < ni; ++i){
|
||||
Class.LateParsedDeclarations[i]->ParseLexedAttributes();
|
||||
}
|
||||
}
|
||||
|
||||
if (!AlreadyHasClassScope)
|
||||
Actions.ActOnFinishDelayedMemberDeclarations(getCurScope(),
|
||||
Class.TagOrTemplate);
|
||||
}
|
||||
|
||||
/// Parse all attributes in LAs, and attach them to Decl D.
|
||||
void Parser::ParseLexedAttributeList(LateParsedAttrList &LAs, Decl *D,
|
||||
bool EnterScope, bool OnDefinition) {
|
||||
assert(LAs.parseSoon() &&
|
||||
"Attribute list should be marked for immediate parsing.");
|
||||
for (unsigned i = 0, ni = LAs.size(); i < ni; ++i) {
|
||||
if (D)
|
||||
LAs[i]->addDecl(D);
|
||||
ParseLexedAttribute(*LAs[i], EnterScope, OnDefinition);
|
||||
delete LAs[i];
|
||||
}
|
||||
LAs.clear();
|
||||
}
|
||||
|
||||
/// Finish parsing an attribute for which parsing was delayed.
|
||||
/// This will be called at the end of parsing a class declaration
|
||||
/// for each LateParsedAttribute. We consume the saved tokens and
|
||||
/// create an attribute with the arguments filled in. We add this
|
||||
/// to the Attribute list for the decl.
|
||||
void Parser::ParseLexedAttribute(LateParsedAttribute &LA,
|
||||
bool EnterScope, bool OnDefinition) {
|
||||
// Create a fake EOF so that attribute parsing won't go off the end of the
|
||||
// attribute.
|
||||
Token AttrEnd;
|
||||
AttrEnd.startToken();
|
||||
AttrEnd.setKind(tok::eof);
|
||||
AttrEnd.setLocation(Tok.getLocation());
|
||||
AttrEnd.setEofData(LA.Toks.data());
|
||||
LA.Toks.push_back(AttrEnd);
|
||||
|
||||
// Append the current token at the end of the new token stream so that it
|
||||
// doesn't get lost.
|
||||
LA.Toks.push_back(Tok);
|
||||
PP.EnterTokenStream(LA.Toks, true, /*IsReinject=*/true);
|
||||
// Consume the previously pushed token.
|
||||
ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true);
|
||||
|
||||
ParsedAttributes Attrs(AttrFactory);
|
||||
SourceLocation endLoc;
|
||||
|
||||
if (LA.Decls.size() > 0) {
|
||||
Decl *D = LA.Decls[0];
|
||||
NamedDecl *ND = dyn_cast<NamedDecl>(D);
|
||||
RecordDecl *RD = dyn_cast_or_null<RecordDecl>(D->getDeclContext());
|
||||
|
||||
// Allow 'this' within late-parsed attributes.
|
||||
Sema::CXXThisScopeRAII ThisScope(Actions, RD, Qualifiers(),
|
||||
ND && ND->isCXXInstanceMember());
|
||||
|
||||
if (LA.Decls.size() == 1) {
|
||||
// If the Decl is templatized, add template parameters to scope.
|
||||
bool HasTemplateScope = EnterScope && D->isTemplateDecl();
|
||||
ParseScope TempScope(this, Scope::TemplateParamScope, HasTemplateScope);
|
||||
if (HasTemplateScope)
|
||||
Actions.ActOnReenterTemplateScope(Actions.CurScope, D);
|
||||
|
||||
// If the Decl is on a function, add function parameters to the scope.
|
||||
bool HasFunScope = EnterScope && D->isFunctionOrFunctionTemplate();
|
||||
ParseScope FnScope(
|
||||
this, Scope::FnScope | Scope::DeclScope | Scope::CompoundStmtScope,
|
||||
HasFunScope);
|
||||
if (HasFunScope)
|
||||
Actions.ActOnReenterFunctionContext(Actions.CurScope, D);
|
||||
|
||||
ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs, &endLoc,
|
||||
nullptr, SourceLocation(), ParsedAttr::AS_GNU,
|
||||
nullptr);
|
||||
|
||||
if (HasFunScope) {
|
||||
Actions.ActOnExitFunctionContext();
|
||||
FnScope.Exit(); // Pop scope, and remove Decls from IdResolver
|
||||
}
|
||||
if (HasTemplateScope) {
|
||||
TempScope.Exit();
|
||||
}
|
||||
} else {
|
||||
// If there are multiple decls, then the decl cannot be within the
|
||||
// function scope.
|
||||
ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs, &endLoc,
|
||||
nullptr, SourceLocation(), ParsedAttr::AS_GNU,
|
||||
nullptr);
|
||||
}
|
||||
} else {
|
||||
Diag(Tok, diag::warn_attribute_no_decl) << LA.AttrName.getName();
|
||||
}
|
||||
|
||||
if (OnDefinition && !Attrs.empty() && !Attrs.begin()->isCXX11Attribute() &&
|
||||
Attrs.begin()->isKnownToGCC())
|
||||
Diag(Tok, diag::warn_attribute_on_function_definition)
|
||||
<< &LA.AttrName;
|
||||
|
||||
for (unsigned i = 0, ni = LA.Decls.size(); i < ni; ++i)
|
||||
Actions.ActOnFinishDelayedAttribute(getCurScope(), LA.Decls[i], Attrs);
|
||||
|
||||
// Due to a parsing error, we either went over the cached tokens or
|
||||
// there are still cached tokens left, so we skip the leftover tokens.
|
||||
while (Tok.isNot(tok::eof))
|
||||
ConsumeAnyToken();
|
||||
|
||||
if (Tok.is(tok::eof) && Tok.getEofData() == AttrEnd.getEofData())
|
||||
ConsumeAnyToken();
|
||||
}
|
||||
|
||||
void Parser::ParseLexedPragmas(ParsingClass &Class) {
|
||||
bool HasTemplateScope = !Class.TopLevelClass && Class.TemplateScope;
|
||||
ParseScope ClassTemplateScope(this, Scope::TemplateParamScope,
|
||||
|
@ -1409,154 +1409,6 @@ void Parser::ParseObjCBridgeRelatedAttribute(IdentifierInfo &ObjCBridgeRelated,
|
||||
Syntax);
|
||||
}
|
||||
|
||||
// Late Parsed Attributes:
|
||||
// See other examples of late parsing in lib/Parse/ParseCXXInlineMethods
|
||||
|
||||
void Parser::LateParsedDeclaration::ParseLexedAttributes() {}
|
||||
|
||||
void Parser::LateParsedClass::ParseLexedAttributes() {
|
||||
Self->ParseLexedAttributes(*Class);
|
||||
}
|
||||
|
||||
void Parser::LateParsedAttribute::ParseLexedAttributes() {
|
||||
Self->ParseLexedAttribute(*this, true, false);
|
||||
}
|
||||
|
||||
/// Wrapper class which calls ParseLexedAttribute, after setting up the
|
||||
/// scope appropriately.
|
||||
void Parser::ParseLexedAttributes(ParsingClass &Class) {
|
||||
// Deal with templates
|
||||
// FIXME: Test cases to make sure this does the right thing for templates.
|
||||
bool HasTemplateScope = !Class.TopLevelClass && Class.TemplateScope;
|
||||
ParseScope ClassTemplateScope(this, Scope::TemplateParamScope,
|
||||
HasTemplateScope);
|
||||
if (HasTemplateScope)
|
||||
Actions.ActOnReenterTemplateScope(getCurScope(), Class.TagOrTemplate);
|
||||
|
||||
// Set or update the scope flags.
|
||||
bool AlreadyHasClassScope = Class.TopLevelClass;
|
||||
unsigned ScopeFlags = Scope::ClassScope|Scope::DeclScope;
|
||||
ParseScope ClassScope(this, ScopeFlags, !AlreadyHasClassScope);
|
||||
ParseScopeFlags ClassScopeFlags(this, ScopeFlags, AlreadyHasClassScope);
|
||||
|
||||
// Enter the scope of nested classes
|
||||
if (!AlreadyHasClassScope)
|
||||
Actions.ActOnStartDelayedMemberDeclarations(getCurScope(),
|
||||
Class.TagOrTemplate);
|
||||
if (!Class.LateParsedDeclarations.empty()) {
|
||||
for (unsigned i = 0, ni = Class.LateParsedDeclarations.size(); i < ni; ++i){
|
||||
Class.LateParsedDeclarations[i]->ParseLexedAttributes();
|
||||
}
|
||||
}
|
||||
|
||||
if (!AlreadyHasClassScope)
|
||||
Actions.ActOnFinishDelayedMemberDeclarations(getCurScope(),
|
||||
Class.TagOrTemplate);
|
||||
}
|
||||
|
||||
/// Parse all attributes in LAs, and attach them to Decl D.
|
||||
void Parser::ParseLexedAttributeList(LateParsedAttrList &LAs, Decl *D,
|
||||
bool EnterScope, bool OnDefinition) {
|
||||
assert(LAs.parseSoon() &&
|
||||
"Attribute list should be marked for immediate parsing.");
|
||||
for (unsigned i = 0, ni = LAs.size(); i < ni; ++i) {
|
||||
if (D)
|
||||
LAs[i]->addDecl(D);
|
||||
ParseLexedAttribute(*LAs[i], EnterScope, OnDefinition);
|
||||
delete LAs[i];
|
||||
}
|
||||
LAs.clear();
|
||||
}
|
||||
|
||||
/// Finish parsing an attribute for which parsing was delayed.
|
||||
/// This will be called at the end of parsing a class declaration
|
||||
/// for each LateParsedAttribute. We consume the saved tokens and
|
||||
/// create an attribute with the arguments filled in. We add this
|
||||
/// to the Attribute list for the decl.
|
||||
void Parser::ParseLexedAttribute(LateParsedAttribute &LA,
|
||||
bool EnterScope, bool OnDefinition) {
|
||||
// Create a fake EOF so that attribute parsing won't go off the end of the
|
||||
// attribute.
|
||||
Token AttrEnd;
|
||||
AttrEnd.startToken();
|
||||
AttrEnd.setKind(tok::eof);
|
||||
AttrEnd.setLocation(Tok.getLocation());
|
||||
AttrEnd.setEofData(LA.Toks.data());
|
||||
LA.Toks.push_back(AttrEnd);
|
||||
|
||||
// Append the current token at the end of the new token stream so that it
|
||||
// doesn't get lost.
|
||||
LA.Toks.push_back(Tok);
|
||||
PP.EnterTokenStream(LA.Toks, true, /*IsReinject=*/true);
|
||||
// Consume the previously pushed token.
|
||||
ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true);
|
||||
|
||||
ParsedAttributes Attrs(AttrFactory);
|
||||
SourceLocation endLoc;
|
||||
|
||||
if (LA.Decls.size() > 0) {
|
||||
Decl *D = LA.Decls[0];
|
||||
NamedDecl *ND = dyn_cast<NamedDecl>(D);
|
||||
RecordDecl *RD = dyn_cast_or_null<RecordDecl>(D->getDeclContext());
|
||||
|
||||
// Allow 'this' within late-parsed attributes.
|
||||
Sema::CXXThisScopeRAII ThisScope(Actions, RD, Qualifiers(),
|
||||
ND && ND->isCXXInstanceMember());
|
||||
|
||||
if (LA.Decls.size() == 1) {
|
||||
// If the Decl is templatized, add template parameters to scope.
|
||||
bool HasTemplateScope = EnterScope && D->isTemplateDecl();
|
||||
ParseScope TempScope(this, Scope::TemplateParamScope, HasTemplateScope);
|
||||
if (HasTemplateScope)
|
||||
Actions.ActOnReenterTemplateScope(Actions.CurScope, D);
|
||||
|
||||
// If the Decl is on a function, add function parameters to the scope.
|
||||
bool HasFunScope = EnterScope && D->isFunctionOrFunctionTemplate();
|
||||
ParseScope FnScope(
|
||||
this, Scope::FnScope | Scope::DeclScope | Scope::CompoundStmtScope,
|
||||
HasFunScope);
|
||||
if (HasFunScope)
|
||||
Actions.ActOnReenterFunctionContext(Actions.CurScope, D);
|
||||
|
||||
ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs, &endLoc,
|
||||
nullptr, SourceLocation(), ParsedAttr::AS_GNU,
|
||||
nullptr);
|
||||
|
||||
if (HasFunScope) {
|
||||
Actions.ActOnExitFunctionContext();
|
||||
FnScope.Exit(); // Pop scope, and remove Decls from IdResolver
|
||||
}
|
||||
if (HasTemplateScope) {
|
||||
TempScope.Exit();
|
||||
}
|
||||
} else {
|
||||
// If there are multiple decls, then the decl cannot be within the
|
||||
// function scope.
|
||||
ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs, &endLoc,
|
||||
nullptr, SourceLocation(), ParsedAttr::AS_GNU,
|
||||
nullptr);
|
||||
}
|
||||
} else {
|
||||
Diag(Tok, diag::warn_attribute_no_decl) << LA.AttrName.getName();
|
||||
}
|
||||
|
||||
if (OnDefinition && !Attrs.empty() && !Attrs.begin()->isCXX11Attribute() &&
|
||||
Attrs.begin()->isKnownToGCC())
|
||||
Diag(Tok, diag::warn_attribute_on_function_definition)
|
||||
<< &LA.AttrName;
|
||||
|
||||
for (unsigned i = 0, ni = LA.Decls.size(); i < ni; ++i)
|
||||
Actions.ActOnFinishDelayedAttribute(getCurScope(), LA.Decls[i], Attrs);
|
||||
|
||||
// Due to a parsing error, we either went over the cached tokens or
|
||||
// there are still cached tokens left, so we skip the leftover tokens.
|
||||
while (Tok.isNot(tok::eof))
|
||||
ConsumeAnyToken();
|
||||
|
||||
if (Tok.is(tok::eof) && Tok.getEofData() == AttrEnd.getEofData())
|
||||
ConsumeAnyToken();
|
||||
}
|
||||
|
||||
void Parser::ParseTypeTagForDatatypeAttribute(IdentifierInfo &AttrName,
|
||||
SourceLocation AttrNameLoc,
|
||||
ParsedAttributes &Attrs,
|
||||
|
Loading…
Reference in New Issue
Block a user