return LocalOffset + M.GlobalBitOffset;
}
-static bool isSameTemplateParameterList(const TemplateParameterList *X,
+static bool isSameTemplateParameterList(const ASTContext &C,
+ const TemplateParameterList *X,
const TemplateParameterList *Y);
/// Determine whether two template parameters are similar enough
if (const auto *TX = dyn_cast<TemplateTypeParmDecl>(X)) {
const auto *TY = cast<TemplateTypeParmDecl>(Y);
- return TX->isParameterPack() == TY->isParameterPack();
+ if (TX->isParameterPack() != TY->isParameterPack())
+ return false;
+ if (TX->hasTypeConstraint() != TY->hasTypeConstraint())
+ return false;
+ if (TX->hasTypeConstraint()) {
+ const TypeConstraint *TXTC = TX->getTypeConstraint();
+ const TypeConstraint *TYTC = TY->getTypeConstraint();
+ if (TXTC->getNamedConcept() != TYTC->getNamedConcept())
+ return false;
+ if (TXTC->hasExplicitTemplateArgs() != TYTC->hasExplicitTemplateArgs())
+ return false;
+ if (TXTC->hasExplicitTemplateArgs()) {
+ const auto *TXTCArgs = TXTC->getTemplateArgsAsWritten();
+ const auto *TYTCArgs = TYTC->getTemplateArgsAsWritten();
+ if (TXTCArgs->NumTemplateArgs != TYTCArgs->NumTemplateArgs)
+ return false;
+ llvm::FoldingSetNodeID XID, YID;
+ for (const auto &ArgLoc : TXTCArgs->arguments())
+ ArgLoc.getArgument().Profile(XID, X->getASTContext());
+ for (const auto &ArgLoc : TYTCArgs->arguments())
+ ArgLoc.getArgument().Profile(YID, Y->getASTContext());
+ if (XID != YID)
+ return false;
+ }
+ }
+ return true;
}
if (const auto *TX = dyn_cast<NonTypeTemplateParmDecl>(X)) {
const auto *TX = cast<TemplateTemplateParmDecl>(X);
const auto *TY = cast<TemplateTemplateParmDecl>(Y);
return TX->isParameterPack() == TY->isParameterPack() &&
- isSameTemplateParameterList(TX->getTemplateParameters(),
+ isSameTemplateParameterList(TX->getASTContext(),
+ TX->getTemplateParameters(),
TY->getTemplateParameters());
}
/// Determine whether two template parameter lists are similar enough
/// that they may be used in declarations of the same template.
-static bool isSameTemplateParameterList(const TemplateParameterList *X,
+static bool isSameTemplateParameterList(const ASTContext &C,
+ const TemplateParameterList *X,
const TemplateParameterList *Y) {
if (X->size() != Y->size())
return false;
if (!isSameTemplateParameter(X->getParam(I), Y->getParam(I)))
return false;
+ const Expr *XRC = X->getRequiresClause();
+ const Expr *YRC = Y->getRequiresClause();
+ if (!XRC != !YRC)
+ return false;
+ if (XRC) {
+ llvm::FoldingSetNodeID XRCID, YRCID;
+ XRC->Profile(XRCID, C, /*Canonical=*/true);
+ YRC->Profile(YRCID, C, /*Canonical=*/true);
+ if (XRCID != YRCID)
+ return false;
+ }
+
return true;
}
return true;
}
-/// Determine whether the two declarations refer to the same entity.
+/// Determine whether the two declarations refer to the same entity.pr
static bool isSameEntity(NamedDecl *X, NamedDecl *Y) {
assert(X->getDeclName() == Y->getDeclName() && "Declaration name mismatch!");
}
ASTContext &C = FuncX->getASTContext();
+
+ const Expr *XRC = FuncX->getTrailingRequiresClause();
+ const Expr *YRC = FuncY->getTrailingRequiresClause();
+ if (!XRC != !YRC)
+ return false;
+ if (XRC) {
+ llvm::FoldingSetNodeID XRCID, YRCID;
+ XRC->Profile(XRCID, C, /*Canonical=*/true);
+ YRC->Profile(YRCID, C, /*Canonical=*/true);
+ if (XRCID != YRCID)
+ return false;
+ }
+
auto GetTypeAsWritten = [](const FunctionDecl *FD) {
// Map to the first declaration that we've already merged into this one.
// The TSI of redeclarations might not match (due to calling conventions
return true;
return false;
}
+
return FuncX->getLinkageInternal() == FuncY->getLinkageInternal() &&
hasSameOverloadableAttrs(FuncX, FuncY);
}
const auto *TemplateY = cast<TemplateDecl>(Y);
return isSameEntity(TemplateX->getTemplatedDecl(),
TemplateY->getTemplatedDecl()) &&
- isSameTemplateParameterList(TemplateX->getTemplateParameters(),
+ isSameTemplateParameterList(TemplateX->getASTContext(),
+ TemplateX->getTemplateParameters(),
TemplateY->getTemplateParameters());
}