diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/AST/ItaniumMangle.cpp | 6 | ||||
-rw-r--r-- | clang/lib/Parse/ParseDeclCXX.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Parse/ParseObjc.cpp | 6 | ||||
-rw-r--r-- | clang/lib/Sema/SemaAttr.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Sema/SemaOverload.cpp | 46 | ||||
-rw-r--r-- | clang/lib/Sema/SemaType.cpp | 8 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTReaderDecl.cpp | 33 |
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. |