summaryrefslogtreecommitdiffstats
path: root/clang/lib/Serialization
diff options
context:
space:
mode:
authorGeorge Burgess IV <george.burgess.iv@gmail.com>2017-02-15 22:43:27 +0000
committerGeorge Burgess IV <george.burgess.iv@gmail.com>2017-02-15 22:43:27 +0000
commit9584508d5c4eb4ca57fd457d914bb9866ce13d18 (patch)
tree89c4946ac14cf9e270ac48f70332e5d0987900d5 /clang/lib/Serialization
parentc6ce73b114204e25dcca7326165fedda829e7f01 (diff)
downloadbcm5719-llvm-9584508d5c4eb4ca57fd457d914bb9866ce13d18.tar.gz
bcm5719-llvm-9584508d5c4eb4ca57fd457d914bb9866ce13d18.zip
[Modules] Consider enable_if attrs in isSameEntity.
Two functions that differ only in their enable_if attributes are considered overloads, so we should check for those when we're trying to figure out if two functions are mergeable. We need to do the same thing for pass_object_size, as well. Looks like that'll be a bit less trivial, since we sometimes do these merging checks before we have pass_object_size attributes available (see the merge checks in ASTDeclReader::VisitFunctionDecl that happen before we read parameters, and merge checks in calls to ReadDeclAs<>()). llvm-svn: 295252
Diffstat (limited to 'clang/lib/Serialization')
-rw-r--r--clang/lib/Serialization/ASTReaderDecl.cpp44
1 files changed, 42 insertions, 2 deletions
diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp
index 8b14c2d8254..9be3981329a 100644
--- a/clang/lib/Serialization/ASTReaderDecl.cpp
+++ b/clang/lib/Serialization/ASTReaderDecl.cpp
@@ -2656,6 +2656,44 @@ static bool isSameTemplateParameterList(const TemplateParameterList *X,
return true;
}
+/// Determine whether the attributes we can overload on are identical for A and
+/// B. Expects A and B to (otherwise) have the same type.
+static bool hasSameOverloadableAttrs(const FunctionDecl *A,
+ const FunctionDecl *B) {
+ 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;
+ for (unsigned I = 0, E = AEnableIfs.size(); I != E; ++I) {
+ Cand1ID.clear();
+ Cand2ID.clear();
+
+ AEnableIfs[I]->getCond()->Profile(Cand1ID, A->getASTContext(), true);
+ BEnableIfs[I]->getCond()->Profile(Cand2ID, B->getASTContext(), true);
+ if (Cand1ID != Cand2ID)
+ return false;
+ }
+
+ // FIXME: This doesn't currently consider pass_object_size attributes, since
+ // we aren't guaranteed that A and B have valid parameter lists yet.
+ return true;
+}
+
/// \brief Determine whether the two declarations refer to the same entity.
static bool isSameEntity(NamedDecl *X, NamedDecl *Y) {
assert(X->getDeclName() == Y->getDeclName() && "Declaration name mismatch!");
@@ -2711,8 +2749,10 @@ static bool isSameEntity(NamedDecl *X, NamedDecl *Y) {
CtorY->getInheritedConstructor().getConstructor()))
return false;
}
- return (FuncX->getLinkageInternal() == FuncY->getLinkageInternal()) &&
- FuncX->getASTContext().hasSameType(FuncX->getType(), FuncY->getType());
+ return FuncX->getLinkageInternal() == FuncY->getLinkageInternal() &&
+ FuncX->getASTContext().hasSameType(FuncX->getType(),
+ FuncY->getType()) &&
+ hasSameOverloadableAttrs(FuncX, FuncY);
}
// Variables with the same type and linkage match.
OpenPOWER on IntegriCloud