summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaOverload.cpp
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/Sema/SemaOverload.cpp
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/Sema/SemaOverload.cpp')
-rw-r--r--clang/lib/Sema/SemaOverload.cpp47
1 files changed, 34 insertions, 13 deletions
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)
OpenPOWER on IntegriCloud