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 | |
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')
-rw-r--r-- | clang/lib/AST/ItaniumMangle.cpp | 6 | ||||
-rw-r--r-- | clang/lib/Parse/ParseDecl.cpp | 4 | ||||
-rw-r--r-- | clang/lib/Sema/SemaOverload.cpp | 47 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTReaderDecl.cpp | 33 |
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. |