summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorMichael Kruse <llvm@meinersbur.de>2018-06-25 20:06:13 +0000
committerMichael Kruse <llvm@meinersbur.de>2018-06-25 20:06:13 +0000
commit41dd6ced2c8323aa804c3aed57f120746ab7f3fc (patch)
treebafdc35a26910c8a213596380a4bc25559485804 /clang/lib
parent05f6626fc48b40c332c0f4d082284b39d38e23c7 (diff)
downloadbcm5719-llvm-41dd6ced2c8323aa804c3aed57f120746ab7f3fc.tar.gz
bcm5719-llvm-41dd6ced2c8323aa804c3aed57f120746ab7f3fc.zip
Revert "Append new attributes to the end of an AttributeList."
This reverts commit r335084 as requested by David Jones and Eric Christopher because of differences of emitted warnings. llvm-svn: 335516
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/ItaniumMangle.cpp6
-rw-r--r--clang/lib/Parse/ParseDecl.cpp4
-rw-r--r--clang/lib/Sema/SemaOverload.cpp47
-rw-r--r--clang/lib/Serialization/ASTReaderDecl.cpp33
4 files changed, 63 insertions, 27 deletions
diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index 86b9fb5d6ab..d8c435991ec 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -707,8 +707,10 @@ void CXXNameMangler::mangleFunctionEncodingBareType(const FunctionDecl *FD) {
if (FD->hasAttr<EnableIfAttr>()) {
FunctionTypeDepthState Saved = FunctionTypeDepth.push();
Out << "Ua9enable_ifI";
- for (AttrVec::const_iterator I = FD->getAttrs().begin(),
- E = FD->getAttrs().end();
+ // 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();
I != E; ++I) {
EnableIfAttr *EIA = dyn_cast<EnableIfAttr>(*I);
if (!EIA)
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index e3691565480..d1f87c9df07 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -1649,7 +1649,9 @@ void Parser::stripTypeAttributesOffDeclSpec(ParsedAttributesWithRange &Attrs,
}
// Find end of type attributes Attrs and add NewTypeAttributes in the same
- // order they were in originally.
+ // order they were in originally. (Remember, in AttributeList things earlier
+ // in source order are later in the list, since new attributes are added to
+ // the front of the list.)
Attrs.addAllAtEnd(TypeAttrHead);
}
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 34ac5c16470..d730bb27a1f 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -6189,6 +6189,24 @@ 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,
@@ -6262,9 +6280,9 @@ convertArgsForAvailabilityChecks(Sema &S, FunctionDecl *Function, Expr *ThisArg,
EnableIfAttr *Sema::CheckEnableIf(FunctionDecl *Function, ArrayRef<Expr *> Args,
bool MissingImplicitThis) {
- auto EnableIfAttrs = Function->specific_attrs<EnableIfAttr>();
-
- if (EnableIfAttrs.begin() == EnableIfAttrs.end())
+ SmallVector<EnableIfAttr *, 4> EnableIfAttrs =
+ getOrderedEnableIfAttrs(Function);
+ if (EnableIfAttrs.empty())
return nullptr;
SFINAETrap Trap(*this);
@@ -6274,7 +6292,7 @@ EnableIfAttr *Sema::CheckEnableIf(FunctionDecl *Function, ArrayRef<Expr *> Args,
if (!convertArgsForAvailabilityChecks(
*this, Function, /*ThisArg=*/nullptr, Args, Trap,
/*MissingImplicitThis=*/true, DiscardedThis, ConvertedArgs))
- return *EnableIfAttrs.begin();
+ return EnableIfAttrs[0];
for (auto *EIA : EnableIfAttrs) {
APValue Result;
@@ -8923,21 +8941,24 @@ static Comparison compareEnableIfAttrs(const Sema &S, const FunctionDecl *Cand1,
return Cand1Attr ? Comparison::Better : Comparison::Worse;
}
- auto Cand1Attrs = Cand1->specific_attrs<EnableIfAttr>();
- auto Cand2Attrs = Cand2->specific_attrs<EnableIfAttr>();
+ // 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 Cand1I = Cand1Attrs.begin();
llvm::FoldingSetNodeID Cand1ID, Cand2ID;
- for (auto Cand2A : Cand2Attrs) {
+ for (auto &Cand2A : Cand2Attrs) {
Cand1ID.clear();
Cand2ID.clear();
- // It's impossible for Cand1 to be better than (or equal to) Cand2 if Cand1
- // has fewer enable_if attributes than Cand2.
- if (Cand1I == Cand1Attrs.end())
- return Comparison::Worse;
- auto Cand1A = Cand1I++;
-
+ auto &Cand1A = *Cand1I++;
Cand1A->getCond()->Profile(Cand1ID, S.getASTContext(), true);
Cand2A->getCond()->Profile(Cand2ID, S.getASTContext(), true);
if (Cand1ID != Cand2ID)
diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp
index 0daf1b3bdb7..a1ce26d27ca 100644
--- a/clang/lib/Serialization/ASTReaderDecl.cpp
+++ b/clang/lib/Serialization/ASTReaderDecl.cpp
@@ -2804,25 +2804,36 @@ 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.
- // Return false if any of the enable_if expressions of A and B are different.
+ 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;
+
llvm::FoldingSetNodeID Cand1ID, Cand2ID;
- 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) {
+ for (unsigned I = 0, E = AEnableIfs.size(); I != E; ++I) {
Cand1ID.clear();
Cand2ID.clear();
- AEnableIf->getCond()->Profile(Cand1ID, A->getASTContext(), true);
- BEnableIf->getCond()->Profile(Cand2ID, B->getASTContext(), true);
+ AEnableIfs[I]->getCond()->Profile(Cand1ID, A->getASTContext(), true);
+ BEnableIfs[I]->getCond()->Profile(Cand2ID, B->getASTContext(), true);
if (Cand1ID != Cand2ID)
return false;
}
- // Return false if the number of enable_if attributes was different.
- return AEnableIf == AEnableIfAttrs.end() && BEnableIf == BEnableIfAttrs.end();
+ return true;
}
/// Determine whether the two declarations refer to the same entity.
OpenPOWER on IntegriCloud