[Sema] Keep attribute lists in the order the attributes were parsed (#162714)

This renames some attribute list related functions, to make callers
think about whether they want to append or prepend to the list, instead
of defaulting to prepending which is often not the desired behaviour
(for the cases where it matters, sometimes we're just adding to an empty
list). Then it adjusts some of these calls to append where they were
previously prepending. This has the effect of making
`err_attributes_are_not_compatible` consistent in emitting diagnostics
as `<new-attr> and <existing-attr> are not compatible`, regardless of
the syntax used to apply the attributes.
This commit is contained in:
Henrik G. Olsson 2025-10-09 22:13:37 -07:00 committed by GitHub
parent a1b5e975c9
commit 3a9440b9f7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 51 additions and 51 deletions

View File

@ -2173,7 +2173,7 @@ private:
if (Tok.is(tok::kw___attribute)) {
ParsedAttributes Attrs(AttrFactory);
ParseGNUAttributes(Attrs, LateAttrs, &D);
D.takeAttributes(Attrs);
D.takeAttributesAppending(Attrs);
}
}
@ -2272,7 +2272,7 @@ private:
if (isAllowedCXX11AttributeSpecifier()) {
ParsedAttributes Attrs(AttrFactory);
ParseCXX11Attributes(Attrs);
D.takeAttributes(Attrs);
D.takeAttributesAppending(Attrs);
}
}
@ -2292,7 +2292,7 @@ private:
ParsedAttributes AttrsWithRange(AttrFactory);
ParseMicrosoftAttributes(AttrsWithRange);
AttrsParsed = !AttrsWithRange.empty();
Attrs.takeAllFrom(AttrsWithRange);
Attrs.takeAllAppendingFrom(AttrsWithRange);
}
return AttrsParsed;
}
@ -5175,7 +5175,7 @@ private:
if (Tok.is(tok::colon)) {
ParsedAttributes Attrs(AttrFactory);
ParseHLSLAnnotations(Attrs, EndLoc, CouldBeBitField);
D.takeAttributes(Attrs);
D.takeAttributesAppending(Attrs);
return true;
}
return false;

View File

@ -835,7 +835,7 @@ public:
/// \endcode
///
void addAttributes(const ParsedAttributesView &AL) {
Attrs.addAll(AL.begin(), AL.end());
Attrs.prepend(AL.begin(), AL.end());
}
bool hasAttributes() const { return !Attrs.empty(); }
@ -843,8 +843,8 @@ public:
ParsedAttributes &getAttributes() { return Attrs; }
const ParsedAttributes &getAttributes() const { return Attrs; }
void takeAttributesFrom(ParsedAttributes &attrs) {
Attrs.takeAllFrom(attrs);
void takeAttributesAppendingingFrom(ParsedAttributes &attrs) {
Attrs.takeAllAppendingFrom(attrs);
}
/// Finish - This does final analysis of the declspec, issuing diagnostics for
@ -2327,7 +2327,7 @@ public:
void AddTypeInfo(const DeclaratorChunk &TI, ParsedAttributes &&attrs,
SourceLocation EndLoc) {
DeclTypeInfo.push_back(TI);
DeclTypeInfo.back().getAttrs().addAll(attrs.begin(), attrs.end());
DeclTypeInfo.back().getAttrs().prepend(attrs.begin(), attrs.end());
getAttributePool().takeAllFrom(attrs.getPool());
if (!EndLoc.isInvalid())
@ -2638,8 +2638,8 @@ public:
return InventedTemplateParameterList;
}
/// takeAttributes - Takes attributes from the given parsed-attributes
/// set and add them to this declarator.
/// takeAttributesAppending - Takes attributes from the given
/// ParsedAttributes set and add them to this declarator.
///
/// These examples both add 3 attributes to "var":
/// short int var __attribute__((aligned(16),common,deprecated));
@ -2647,8 +2647,8 @@ public:
/// __attribute__((common,deprecated));
///
/// Also extends the range of the declarator.
void takeAttributes(ParsedAttributes &attrs) {
Attrs.takeAllFrom(attrs);
void takeAttributesAppending(ParsedAttributes &attrs) {
Attrs.takeAllAppendingFrom(attrs);
if (attrs.Range.getEnd().isValid())
SetRangeEnd(attrs.Range.getEnd());

View File

@ -856,19 +856,19 @@ public:
friend class ParsedAttributesView;
};
void addAll(iterator B, iterator E) {
void prepend(iterator B, iterator E) {
AttrList.insert(AttrList.begin(), B.I, E.I);
}
void addAll(const_iterator B, const_iterator E) {
void prepend(const_iterator B, const_iterator E) {
AttrList.insert(AttrList.begin(), B.I, E.I);
}
void addAllAtEnd(iterator B, iterator E) {
void append(iterator B, iterator E) {
AttrList.insert(AttrList.end(), B.I, E.I);
}
void addAllAtEnd(const_iterator B, const_iterator E) {
void append(const_iterator B, const_iterator E) {
AttrList.insert(AttrList.end(), B.I, E.I);
}
@ -943,18 +943,18 @@ public:
AttributePool &getPool() const { return pool; }
void takeAllFrom(ParsedAttributes &Other) {
void takeAllPrependingFrom(ParsedAttributes &Other) {
assert(&Other != this &&
"ParsedAttributes can't take attributes from itself");
addAll(Other.begin(), Other.end());
prepend(Other.begin(), Other.end());
Other.clearListOnly();
pool.takeAllFrom(Other.pool);
}
void takeAllAtEndFrom(ParsedAttributes &Other) {
void takeAllAppendingFrom(ParsedAttributes &Other) {
assert(&Other != this &&
"ParsedAttributes can't take attributes from itself");
addAllAtEnd(Other.begin(), Other.end());
append(Other.begin(), Other.end());
Other.clearListOnly();
pool.takeAllFrom(Other.pool);
}

View File

@ -1934,12 +1934,12 @@ Parser::DeclGroupPtrTy Parser::ParseSimpleDeclaration(
bool RequireSemi, ForRangeInit *FRI, SourceLocation *DeclSpecStart) {
// Need to retain these for diagnostics before we add them to the DeclSepc.
ParsedAttributesView OriginalDeclSpecAttrs;
OriginalDeclSpecAttrs.addAll(DeclSpecAttrs.begin(), DeclSpecAttrs.end());
OriginalDeclSpecAttrs.prepend(DeclSpecAttrs.begin(), DeclSpecAttrs.end());
OriginalDeclSpecAttrs.Range = DeclSpecAttrs.Range;
// Parse the common declaration-specifiers piece.
ParsingDeclSpec DS(*this);
DS.takeAttributesFrom(DeclSpecAttrs);
DS.takeAttributesAppendingingFrom(DeclSpecAttrs);
ParsedTemplateInfo TemplateInfo;
DeclSpecContext DSContext = getDeclSpecContextFromDeclaratorContext(Context);
@ -2135,7 +2135,7 @@ Parser::DeclGroupPtrTy Parser::ParseDeclGroup(ParsingDeclSpec &DS,
// list. This ensures that we will not attempt to interpret them as statement
// attributes higher up the callchain.
ParsedAttributes LocalAttrs(AttrFactory);
LocalAttrs.takeAllFrom(Attrs);
LocalAttrs.takeAllPrependingFrom(Attrs);
ParsingDeclarator D(*this, DS, LocalAttrs, Context);
if (TemplateInfo.TemplateParams)
D.setTemplateParameterLists(*TemplateInfo.TemplateParams);
@ -3462,7 +3462,7 @@ void Parser::ParseDeclarationSpecifiers(
PA.setInvalid();
}
DS.takeAttributesFrom(attrs);
DS.takeAttributesAppendingingFrom(attrs);
}
// If this is not a declaration specifier token, we're done reading decl
@ -3689,7 +3689,7 @@ void Parser::ParseDeclarationSpecifiers(
if (ParseImplicitInt(DS, &SS, TemplateInfo, AS, DSContext, Attrs)) {
if (!Attrs.empty()) {
AttrsLastTime = true;
attrs.takeAllFrom(Attrs);
attrs.takeAllAppendingFrom(Attrs);
}
continue;
}
@ -3854,7 +3854,7 @@ void Parser::ParseDeclarationSpecifiers(
if (ParseImplicitInt(DS, nullptr, TemplateInfo, AS, DSContext, Attrs)) {
if (!Attrs.empty()) {
AttrsLastTime = true;
attrs.takeAllFrom(Attrs);
attrs.takeAllAppendingFrom(Attrs);
}
continue;
}
@ -4463,7 +4463,7 @@ void Parser::ParseDeclarationSpecifiers(
// take them over and handle them here.
if (!Attributes.empty()) {
AttrsLastTime = true;
attrs.takeAllFrom(Attributes);
attrs.takeAllAppendingFrom(Attributes);
}
continue;
}
@ -4830,7 +4830,7 @@ void Parser::ParseLexedCAttribute(LateParsedAttribute &LA, bool EnterScope,
ConsumeAnyToken();
if (OutAttrs) {
OutAttrs->takeAllFrom(Attrs);
OutAttrs->takeAllAppendingFrom(Attrs);
}
}
@ -6122,7 +6122,7 @@ void Parser::ParseTypeQualifierListOpt(
isAllowedCXX11AttributeSpecifier()) {
ParsedAttributes Attrs(AttrFactory);
ParseCXX11Attributes(Attrs);
DS.takeAttributesFrom(Attrs);
DS.takeAttributesAppendingingFrom(Attrs);
}
SourceLocation EndLoc;
@ -7483,7 +7483,7 @@ void Parser::ParseParameterDeclarationClause(
// Take them so that we only apply the attributes to the first parameter.
// We have already started parsing the decl-specifier sequence, so don't
// parse any parameter-declaration pieces that precede it.
ArgDeclSpecAttrs.takeAllFrom(FirstArgAttrs);
ArgDeclSpecAttrs.takeAllPrependingFrom(FirstArgAttrs);
} else {
// Parse any C++11 attributes.
MaybeParseCXX11Attributes(ArgDeclAttrs);
@ -7505,7 +7505,7 @@ void Parser::ParseParameterDeclarationClause(
DeclSpecContext::DSC_normal,
/*LateAttrs=*/nullptr, AllowImplicitTypename);
DS.takeAttributesFrom(ArgDeclSpecAttrs);
DS.takeAttributesAppendingingFrom(ArgDeclSpecAttrs);
// Parse the declarator. This is "PrototypeContext" or
// "LambdaExprParameterContext", because we must accept either

View File

@ -739,7 +739,7 @@ Parser::DeclGroupPtrTy Parser::ParseUsingDeclaration(
<< FixItHint::CreateInsertionFromRange(
Tok.getLocation(), CharSourceRange::getTokenRange(Range))
<< FixItHint::CreateRemoval(Range);
Attrs.takeAllFrom(MisplacedAttrs);
Attrs.takeAllPrependingFrom(MisplacedAttrs);
}
// Maybe this is an alias-declaration.
@ -787,7 +787,7 @@ Parser::DeclGroupPtrTy Parser::ParseUsingDeclaration(
// Parse (optional) attributes.
MaybeParseAttributes(PAKM_GNU | PAKM_CXX11, Attrs);
DiagnoseCXX11AttributeExtension(Attrs);
Attrs.addAll(PrefixAttrs.begin(), PrefixAttrs.end());
Attrs.prepend(PrefixAttrs.begin(), PrefixAttrs.end());
if (InvalidDeclarator)
SkipUntil(tok::comma, tok::semi, StopBeforeMatch);
@ -1948,7 +1948,7 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
// Recover by adding misplaced attributes to the attribute list
// of the class so they can be applied on the class later.
attrs.takeAllFrom(Attributes);
attrs.takeAllAppendingFrom(Attributes);
}
}
@ -2842,7 +2842,7 @@ Parser::DeclGroupPtrTy Parser::ParseCXXClassMemberDeclaration(
// decl-specifier-seq:
// Parse the common declaration-specifiers piece.
ParsingDeclSpec DS(*this, TemplateDiags);
DS.takeAttributesFrom(DeclSpecAttrs);
DS.takeAttributesAppendingingFrom(DeclSpecAttrs);
if (MalformedTypeSpec)
DS.SetTypeSpecError();

View File

@ -1244,7 +1244,7 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer(
break;
}
D.takeAttributes(Attributes);
D.takeAttributesAppending(Attributes);
}
MultiParseScope TemplateParamScope(*this);

View File

@ -43,7 +43,7 @@ void Parser::MaybeSkipAttributes(tok::ObjCKeywordKind Kind) {
Parser::DeclGroupPtrTy
Parser::ParseObjCAtDirectives(ParsedAttributes &DeclAttrs,
ParsedAttributes &DeclSpecAttrs) {
DeclAttrs.takeAllFrom(DeclSpecAttrs);
DeclAttrs.takeAllPrependingFrom(DeclSpecAttrs);
SourceLocation AtLoc = ConsumeToken(); // the "@"
@ -1065,8 +1065,8 @@ void Parser::ParseObjCTypeQualifierList(ObjCDeclSpec &DS,
/// Take all the decl attributes out of the given list and add
/// them to the given attribute set.
static void takeDeclAttributes(ParsedAttributesView &attrs,
ParsedAttributesView &from) {
static void takeDeclAttributesAppend(ParsedAttributesView &attrs,
ParsedAttributesView &from) {
for (auto &AL : llvm::reverse(from)) {
if (!AL.isUsedAsTypeAttr()) {
from.remove(&AL);
@ -1088,10 +1088,10 @@ static void takeDeclAttributes(ParsedAttributes &attrs,
attrs.getPool().takeAllFrom(D.getDeclSpec().getAttributePool());
// Now actually move the attributes over.
takeDeclAttributes(attrs, D.getMutableDeclSpec().getAttributes());
takeDeclAttributes(attrs, D.getAttributes());
takeDeclAttributesAppend(attrs, D.getMutableDeclSpec().getAttributes());
takeDeclAttributesAppend(attrs, D.getAttributes());
for (unsigned i = 0, e = D.getNumTypeObjects(); i != e; ++i)
takeDeclAttributes(attrs, D.getTypeObject(i).getAttrs());
takeDeclAttributesAppend(attrs, D.getTypeObject(i).getAttrs());
}
ParsedType Parser::ParseObjCTypeName(ObjCDeclSpec &DS,

View File

@ -718,7 +718,7 @@ StmtResult Parser::ParseLabeledStatement(ParsedAttributes &Attrs,
// and followed by a semicolon, GCC will reject (it appears to parse the
// attributes as part of a statement in that case). That looks like a bug.
if (!getLangOpts().CPlusPlus || Tok.is(tok::semi))
Attrs.takeAllFrom(TempAttrs);
Attrs.takeAllAppendingFrom(TempAttrs);
else {
StmtVector Stmts;
ParsedAttributes EmptyCXX11Attrs(AttrFactory);
@ -2407,7 +2407,7 @@ StmtResult Parser::ParsePragmaLoopHint(StmtVector &Stmts,
Stmts, StmtCtx, TrailingElseLoc, Attrs, EmptyDeclSpecAttrs,
PrecedingLabel);
Attrs.takeAllFrom(TempAttrs);
Attrs.takeAllPrependingFrom(TempAttrs);
// Start of attribute range may already be set for some invalid input.
// See PR46336.

View File

@ -196,7 +196,7 @@ Parser::DeclGroupPtrTy Parser::ParseDeclarationAfterTemplate(
ParsingDeclSpec DS(*this, &DiagsFromTParams);
DS.SetRangeStart(DeclSpecAttrs.Range.getBegin());
DS.SetRangeEnd(DeclSpecAttrs.Range.getEnd());
DS.takeAttributesFrom(DeclSpecAttrs);
DS.takeAttributesAppendingingFrom(DeclSpecAttrs);
ParseDeclarationSpecifiers(DS, TemplateInfo, AS,
getDeclSpecContextFromDeclaratorContext(Context));

View File

@ -1083,7 +1083,7 @@ Parser::DeclGroupPtrTy Parser::ParseDeclOrFunctionDefInternal(
"expected uninitialised source range");
DS.SetRangeStart(DeclSpecAttrs.Range.getBegin());
DS.SetRangeEnd(DeclSpecAttrs.Range.getEnd());
DS.takeAttributesFrom(DeclSpecAttrs);
DS.takeAttributesAppendingingFrom(DeclSpecAttrs);
ParsedTemplateInfo TemplateInfo;
MaybeParseMicrosoftAttributes(DS.getAttributes());
@ -1155,7 +1155,7 @@ Parser::DeclGroupPtrTy Parser::ParseDeclOrFunctionDefInternal(
}
DS.abort();
DS.takeAttributesFrom(Attrs);
DS.takeAttributesAppendingingFrom(Attrs);
const char *PrevSpec = nullptr;
unsigned DiagID;

View File

@ -197,7 +197,7 @@ DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto,
[&](DeclSpec::TQ TypeQual, StringRef PrintName, SourceLocation SL) {
I.Fun.MethodQualifiers->SetTypeQual(TypeQual, SL);
});
I.Fun.MethodQualifiers->getAttributes().takeAllFrom(attrs);
I.Fun.MethodQualifiers->getAttributes().takeAllPrependingFrom(attrs);
I.Fun.MethodQualifiers->getAttributePool().takeAllFrom(attrs.getPool());
}

View File

@ -304,7 +304,7 @@ bool ParsedAttr::checkAtMostNumArgs(Sema &S, unsigned Num) const {
void clang::takeAndConcatenateAttrs(ParsedAttributes &First,
ParsedAttributes &&Second) {
First.takeAllAtEndFrom(Second);
First.takeAllAppendingFrom(Second);
if (!First.Range.getBegin().isValid())
First.Range.setBegin(Second.Range.getBegin());

View File

@ -14637,7 +14637,7 @@ StmtResult Sema::ActOnCXXForRangeIdentifier(Scope *S, SourceLocation IdentLoc,
Declarator D(DS, ParsedAttributesView::none(), DeclaratorContext::ForInit);
D.SetIdentifier(Ident, IdentLoc);
D.takeAttributes(Attrs);
D.takeAttributesAppending(Attrs);
D.AddTypeInfo(DeclaratorChunk::getReference(0, IdentLoc, /*lvalue*/ false),
IdentLoc);

View File

@ -20,7 +20,7 @@ struct __attribute__((internal_linkage)) S { // expected-warning{{'internal_link
__attribute__((internal_linkage("foo"))) int g(void) {} // expected-error{{'internal_linkage' attribute takes no arguments}}
int var6 [[clang::internal_linkage]];
int var7 [[clang::internal_linkage]] __attribute__((common)); // expected-error{{'clang::internal_linkage' and 'common' attributes are not compatible}} \
int var7 [[clang::internal_linkage]] __attribute__((common)); // expected-error{{'common' and 'clang::internal_linkage' attributes are not compatible}} \
// expected-note{{conflicting attribute is here}}
__attribute__((common)) int var8 [[clang::internal_linkage]]; // expected-error{{'clang::internal_linkage' and 'common' attributes are not compatible}} \
// expected-note{{conflicting attribute is here}}