diff options
author | Michael Kruse <llvm@meinersbur.de> | 2018-06-25 20:06:13 +0000 |
---|---|---|
committer | Michael Kruse <llvm@meinersbur.de> | 2018-06-25 20:06:13 +0000 |
commit | 41dd6ced2c8323aa804c3aed57f120746ab7f3fc (patch) | |
tree | bafdc35a26910c8a213596380a4bc25559485804 /clang/lib/Sema/SemaOverload.cpp | |
parent | 05f6626fc48b40c332c0f4d082284b39d38e23c7 (diff) | |
download | bcm5719-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.cpp | 47 |
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) |