summaryrefslogtreecommitdiffstats
path: root/clang/lib/Serialization
diff options
context:
space:
mode:
authorMichael Kruse <llvm@meinersbur.de>2018-06-19 23:46:52 +0000
committerMichael Kruse <llvm@meinersbur.de>2018-06-19 23:46:52 +0000
commitea31f0e4b883c502d094a3e334966753fa277a4e (patch)
treec63a4b9a7bac4d14f758e585b7768e76d543610a /clang/lib/Serialization
parentf01827f2d1bdaff14cf1cf176e8a69e308d5371e (diff)
downloadbcm5719-llvm-ea31f0e4b883c502d094a3e334966753fa277a4e.tar.gz
bcm5719-llvm-ea31f0e4b883c502d094a3e334966753fa277a4e.zip
Append new attributes to the end of an AttributeList.
... instead of prepending it at the beginning (the original behavior since implemented in r122535 2010-12-23). This builds up an AttributeList in the the order in which the attributes appear in the source. The reverse order caused nodes for attributes in the AST (e.g. LoopHint) to be in the reverse, and therefore printed in the wrong order by -ast-dump. Some TODO comments mention this. The order was explicitly reversed for enable_if attribute overload resolution and name mangling, which is not necessary anymore with this patch. The change unfortunately has some secondary effects, especially for diagnostic output. In the simplest cases, the CHECK lines or expected diagnostic were changed to the the new output. If the kind of error/warning changed, the attribute's order was changed instead. It also causes some 'previous occurrence here' hints to be textually after the main marker. This typically happens when attributes are merged, but are incompatible. Interchanging the role of the the main and note SourceLocation will also cause the case where two different declaration's attributes (in contrast to multiple attributes of the same declaration) are merged to be reversed. There is no easy fix because sometimes previous attributes are merged into a new declaration's attribute list, sometimes new attributes are added to a previous declaration's attribute list. Since 'previous occurrence here' pointing to locations after the main marker is not rare, I left the markers as-is; it is only relevant when the attributes are declared in the same declaration anyway, which often is on the same line. Differential Revision: https://reviews.llvm.org/D48100 llvm-svn: 335084
Diffstat (limited to 'clang/lib/Serialization')
-rw-r--r--clang/lib/Serialization/ASTReaderDecl.cpp33
1 files changed, 11 insertions, 22 deletions
diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp
index a1ce26d27ca..0daf1b3bdb7 100644
--- a/clang/lib/Serialization/ASTReaderDecl.cpp
+++ b/clang/lib/Serialization/ASTReaderDecl.cpp
@@ -2804,36 +2804,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.
OpenPOWER on IntegriCloud