summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorMichael Kruse <llvm@meinersbur.de>2018-08-03 01:21:16 +0000
committerMichael Kruse <llvm@meinersbur.de>2018-08-03 01:21:16 +0000
commitdc5ce72afada30ba99a07157703b00b4ae063f40 (patch)
treea369be5fa866a27497ffd86da9c4edccb096c358 /clang/lib
parentb99281c9b89b9bfae88ca5b998685cfe1ff3641c (diff)
downloadbcm5719-llvm-dc5ce72afada30ba99a07157703b00b4ae063f40.tar.gz
bcm5719-llvm-dc5ce72afada30ba99a07157703b00b4ae063f40.zip
Append new attributes to the end of an AttributeList.
Recommit of r335084 after revert in r335516. ... instead of prepending it at the beginning (the original behavior since implemented in r122535 2010-12-23). This builds up an AttributeList in the the order in which the attributes appear in the source. The reverse order caused nodes for attributes in the AST (e.g. LoopHint) to be in the reverse order, and therefore printed in the wrong order in -ast-dump. Some TODO comments mention this. The order was explicitly reversed for enable_if attribute overload resolution and name mangling, which is not necessary anymore with this patch. The change unfortunately has some secondary effect, especially on diagnostic output. In the simplest cases, the CHECK lines or expected diagnostic were changed to the the new output. If the kind of error/warning changed, the attributes' order was changed instead. This unfortunately causes some 'previous occurrence here' hints to be textually after the main marker. This typically happens when attributes are merged, but are incompatible to each other. Interchanging the role of the the main and note SourceLocation will also cause the case where two different declaration's attributes (in contrast to multiple attributes of the same declaration) are merged to be reverse. There is no easy fix because sometimes previous attributes are merged into a new declaration's attribute list, sometimes new attributes are added to a previous declaration's attribute list. Since 'previous occurrence here' pointing to locations after the main marker is not rare, I left the markers as-is; it is only relevant when the attributes are declared in the same declaration anyway. Differential Revision: https://reviews.llvm.org/D48100 llvm-svn: 338800
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/ItaniumMangle.cpp6
-rw-r--r--clang/lib/Parse/ParseDeclCXX.cpp2
-rw-r--r--clang/lib/Parse/ParseObjc.cpp6
-rw-r--r--clang/lib/Sema/SemaAttr.cpp2
-rw-r--r--clang/lib/Sema/SemaOverload.cpp46
-rw-r--r--clang/lib/Sema/SemaType.cpp8
-rw-r--r--clang/lib/Serialization/ASTReaderDecl.cpp33
7 files changed, 34 insertions, 69 deletions
diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index 2dc04f2f3d8..b483187394a 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -721,10 +721,8 @@ void CXXNameMangler::mangleFunctionEncodingBareType(const FunctionDecl *FD) {
if (FD->hasAttr<EnableIfAttr>()) {
FunctionTypeDepthState Saved = FunctionTypeDepth.push();
Out << "Ua9enable_ifI";
- // FIXME: specific_attr_iterator iterates in reverse order. Fix that and use
- // it here.
- for (AttrVec::const_reverse_iterator I = FD->getAttrs().rbegin(),
- E = FD->getAttrs().rend();
+ for (AttrVec::const_iterator I = FD->getAttrs().begin(),
+ E = FD->getAttrs().end();
I != E; ++I) {
EnableIfAttr *EIA = dyn_cast<EnableIfAttr>(*I);
if (!EIA)
diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp
index 9ba44d07aba..17dd2461227 100644
--- a/clang/lib/Parse/ParseDeclCXX.cpp
+++ b/clang/lib/Parse/ParseDeclCXX.cpp
@@ -3875,7 +3875,7 @@ bool Parser::ParseCXX11AttributeArgs(IdentifierInfo *AttrName,
if (!Attrs.empty() &&
IsBuiltInOrStandardCXX11Attribute(AttrName, ScopeName)) {
- ParsedAttr &Attr = *Attrs.begin();
+ ParsedAttr &Attr = Attrs.back();
// If the attribute is a standard or built-in attribute and we are
// parsing an argument list, we need to determine whether this attribute
// was allowed to have an argument list (such as [[deprecated]]), and how
diff --git a/clang/lib/Parse/ParseObjc.cpp b/clang/lib/Parse/ParseObjc.cpp
index 99e5edb9d4a..655ae561593 100644
--- a/clang/lib/Parse/ParseObjc.cpp
+++ b/clang/lib/Parse/ParseObjc.cpp
@@ -384,12 +384,12 @@ static void addContextSensitiveTypeNullability(Parser &P,
if (D.getNumTypeObjects() > 0) {
// Add the attribute to the declarator chunk nearest the declarator.
- D.getTypeObject(0).getAttrs().addAtStart(
+ D.getTypeObject(0).getAttrs().addAtEnd(
getNullabilityAttr(D.getAttributePool()));
} else if (!addedToDeclSpec) {
// Otherwise, just put it on the declaration specifiers (if one
// isn't there already).
- D.getMutableDeclSpec().getAttributes().addAtStart(
+ D.getMutableDeclSpec().getAttributes().addAtEnd(
getNullabilityAttr(D.getMutableDeclSpec().getAttributes().getPool()));
addedToDeclSpec = true;
}
@@ -1198,7 +1198,7 @@ static void takeDeclAttributes(ParsedAttributesView &attrs,
for (auto &AL : llvm::reverse(from)) {
if (!AL.isUsedAsTypeAttr()) {
from.remove(&AL);
- attrs.addAtStart(&AL);
+ attrs.addAtEnd(&AL);
}
}
}
diff --git a/clang/lib/Sema/SemaAttr.cpp b/clang/lib/Sema/SemaAttr.cpp
index 1a8a0007530..f6f7afe757a 100644
--- a/clang/lib/Sema/SemaAttr.cpp
+++ b/clang/lib/Sema/SemaAttr.cpp
@@ -661,7 +661,7 @@ void Sema::AddPragmaAttributes(Scope *S, Decl *D) {
Entry.IsUsed = true;
PragmaAttributeCurrentTargetDecl = D;
ParsedAttributesView Attrs;
- Attrs.addAtStart(Attribute);
+ Attrs.addAtEnd(Attribute);
ProcessDeclAttributeList(S, D, Attrs);
PragmaAttributeCurrentTargetDecl = nullptr;
}
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 08af485ef4c..6b0837849b9 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -6215,24 +6215,6 @@ Sema::SelectBestMethod(Selector Sel, MultiExprArg Args, bool IsInstance,
return nullptr;
}
-// specific_attr_iterator iterates over enable_if attributes in reverse, and
-// enable_if is order-sensitive. As a result, we need to reverse things
-// sometimes. Size of 4 elements is arbitrary.
-static SmallVector<EnableIfAttr *, 4>
-getOrderedEnableIfAttrs(const FunctionDecl *Function) {
- SmallVector<EnableIfAttr *, 4> Result;
- if (!Function->hasAttrs())
- return Result;
-
- const auto &FuncAttrs = Function->getAttrs();
- for (Attr *Attr : FuncAttrs)
- if (auto *EnableIf = dyn_cast<EnableIfAttr>(Attr))
- Result.push_back(EnableIf);
-
- std::reverse(Result.begin(), Result.end());
- return Result;
-}
-
static bool
convertArgsForAvailabilityChecks(Sema &S, FunctionDecl *Function, Expr *ThisArg,
ArrayRef<Expr *> Args, Sema::SFINAETrap &Trap,
@@ -6306,9 +6288,8 @@ convertArgsForAvailabilityChecks(Sema &S, FunctionDecl *Function, Expr *ThisArg,
EnableIfAttr *Sema::CheckEnableIf(FunctionDecl *Function, ArrayRef<Expr *> Args,
bool MissingImplicitThis) {
- SmallVector<EnableIfAttr *, 4> EnableIfAttrs =
- getOrderedEnableIfAttrs(Function);
- if (EnableIfAttrs.empty())
+ auto EnableIfAttrs = Function->specific_attrs<EnableIfAttr>();
+ if (EnableIfAttrs.begin() == EnableIfAttrs.end())
return nullptr;
SFINAETrap Trap(*this);
@@ -6318,7 +6299,7 @@ EnableIfAttr *Sema::CheckEnableIf(FunctionDecl *Function, ArrayRef<Expr *> Args,
if (!convertArgsForAvailabilityChecks(
*this, Function, /*ThisArg=*/nullptr, Args, Trap,
/*MissingImplicitThis=*/true, DiscardedThis, ConvertedArgs))
- return EnableIfAttrs[0];
+ return *EnableIfAttrs.begin();
for (auto *EIA : EnableIfAttrs) {
APValue Result;
@@ -8967,24 +8948,21 @@ static Comparison compareEnableIfAttrs(const Sema &S, const FunctionDecl *Cand1,
return Cand1Attr ? Comparison::Better : Comparison::Worse;
}
- // FIXME: The next several lines are just
- // specific_attr_iterator<EnableIfAttr> but going in declaration order,
- // instead of reverse order which is how they're stored in the AST.
- auto Cand1Attrs = getOrderedEnableIfAttrs(Cand1);
- auto Cand2Attrs = getOrderedEnableIfAttrs(Cand2);
-
- // It's impossible for Cand1 to be better than (or equal to) Cand2 if Cand1
- // has fewer enable_if attributes than Cand2.
- if (Cand1Attrs.size() < Cand2Attrs.size())
- return Comparison::Worse;
+ auto Cand1Attrs = Cand1->specific_attrs<EnableIfAttr>();
+ auto Cand2Attrs = Cand2->specific_attrs<EnableIfAttr>();
auto Cand1I = Cand1Attrs.begin();
llvm::FoldingSetNodeID Cand1ID, Cand2ID;
- for (auto &Cand2A : Cand2Attrs) {
+ for (EnableIfAttr *Cand2A : Cand2Attrs) {
Cand1ID.clear();
Cand2ID.clear();
- auto &Cand1A = *Cand1I++;
+ // It's impossible for Cand1 to be better than (or equal to) Cand2 if Cand1
+ // has fewer enable_if attributes than Cand2.
+ auto Cand1A = Cand1I++;
+ if (Cand1A == Cand1Attrs.end())
+ return Comparison::Worse;
+
Cand1A->getCond()->Profile(Cand1ID, S.getASTContext(), true);
Cand2A->getCond()->Profile(Cand2ID, S.getASTContext(), true);
if (Cand1ID != Cand2ID)
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index 284d34b22c0..7bd9c8f315b 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -246,7 +246,7 @@ namespace {
getMutableDeclSpec().getAttributes().clearListOnly();
for (ParsedAttr *AL : savedAttrs)
- getMutableDeclSpec().getAttributes().addAtStart(AL);
+ getMutableDeclSpec().getAttributes().addAtEnd(AL);
}
};
} // end anonymous namespace
@@ -255,7 +255,7 @@ static void moveAttrFromListToList(ParsedAttr &attr,
ParsedAttributesView &fromList,
ParsedAttributesView &toList) {
fromList.remove(&attr);
- toList.addAtStart(&attr);
+ toList.addAtEnd(&attr);
}
/// The location of a type attribute.
@@ -4128,7 +4128,7 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
SourceRange(pointerLoc), nullptr, SourceLocation(), nullptr, 0,
syntax);
- attrs.addAtStart(nullabilityAttr);
+ attrs.addAtEnd(nullabilityAttr);
if (inferNullabilityCS) {
state.getDeclarator().getMutableDeclSpec().getObjCQualifiers()
@@ -5093,7 +5093,7 @@ static void transferARCOwnershipToDeclaratorChunk(TypeProcessingState &state,
&S.Context.Idents.get("objc_ownership"), SourceLocation(),
/*scope*/ nullptr, SourceLocation(),
/*args*/ &Args, 1, ParsedAttr::AS_GNU);
- chunk.getAttrs().addAtStart(attr);
+ chunk.getAttrs().addAtEnd(attr);
// TODO: mark whether we did this inference?
}
diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp
index 613579d9079..c8ce1a1fcdd 100644
--- a/clang/lib/Serialization/ASTReaderDecl.cpp
+++ b/clang/lib/Serialization/ASTReaderDecl.cpp
@@ -2832,36 +2832,25 @@ static bool hasSameOverloadableAttrs(const FunctionDecl *A,
// Note that pass_object_size attributes are represented in the function's
// ExtParameterInfo, so we don't need to check them here.
- SmallVector<const EnableIfAttr *, 4> AEnableIfs;
- // Since this is an equality check, we can ignore that enable_if attrs show up
- // in reverse order.
- for (const auto *EIA : A->specific_attrs<EnableIfAttr>())
- AEnableIfs.push_back(EIA);
-
- SmallVector<const EnableIfAttr *, 4> BEnableIfs;
- for (const auto *EIA : B->specific_attrs<EnableIfAttr>())
- BEnableIfs.push_back(EIA);
-
- // Two very common cases: either we have 0 enable_if attrs, or we have an
- // unequal number of enable_if attrs.
- if (AEnableIfs.empty() && BEnableIfs.empty())
- return true;
-
- if (AEnableIfs.size() != BEnableIfs.size())
- return false;
-
+ // Return false if any of the enable_if expressions of A and B are different.
llvm::FoldingSetNodeID Cand1ID, Cand2ID;
- for (unsigned I = 0, E = AEnableIfs.size(); I != E; ++I) {
+ auto AEnableIfAttrs = A->specific_attrs<EnableIfAttr>();
+ auto BEnableIfAttrs = B->specific_attrs<EnableIfAttr>();
+ auto AEnableIf = AEnableIfAttrs.begin();
+ auto BEnableIf = BEnableIfAttrs.begin();
+ for (; AEnableIf != AEnableIfAttrs.end() && BEnableIf != BEnableIfAttrs.end();
+ ++BEnableIf, ++AEnableIf) {
Cand1ID.clear();
Cand2ID.clear();
- AEnableIfs[I]->getCond()->Profile(Cand1ID, A->getASTContext(), true);
- BEnableIfs[I]->getCond()->Profile(Cand2ID, B->getASTContext(), true);
+ AEnableIf->getCond()->Profile(Cand1ID, A->getASTContext(), true);
+ BEnableIf->getCond()->Profile(Cand2ID, B->getASTContext(), true);
if (Cand1ID != Cand2ID)
return false;
}
- return true;
+ // Return false if the number of enable_if attributes was different.
+ return AEnableIf == AEnableIfAttrs.end() && BEnableIf == BEnableIfAttrs.end();
}
/// Determine whether the two declarations refer to the same entity.
OpenPOWER on IntegriCloud