@@ -3809,17 +3809,6 @@ class Sema final {
38093809 // the purposes of [temp.friend] p9.
38103810 bool FriendConstraintsDependOnEnclosingTemplate(const FunctionDecl *FD);
38113811
3812- // Calculates whether two constraint expressions are equal irrespective of a
3813- // difference in 'depth'. This takes a pair of optional 'NamedDecl's 'Old' and
3814- // 'New', which are the "source" of the constraint, since this is necessary
3815- // for figuring out the relative 'depth' of the constraint. The depth of the
3816- // 'primary template' and the 'instantiated from' templates aren't necessarily
3817- // the same, such as a case when one is a 'friend' defined in a class.
3818- bool AreConstraintExpressionsEqual(const NamedDecl *Old,
3819- const Expr *OldConstr,
3820- const NamedDecl *New,
3821- const Expr *NewConstr);
3822-
38233812 enum class AllowedExplicit {
38243813 /// Allow no explicit functions to be used.
38253814 None,
@@ -8615,8 +8604,48 @@ class Sema final {
86158604 TPL_TemplateParamsEquivalent,
86168605 };
86178606
8607+ // A struct to represent the 'new' declaration, which is either itself just
8608+ // the named decl, or the important information we need about it in order to
8609+ // do constraint comparisons.
8610+ class TemplateCompareNewDeclInfo {
8611+ const NamedDecl *ND = nullptr;
8612+ const DeclContext *DC = nullptr;
8613+ const DeclContext *LexicalDC = nullptr;
8614+ SourceLocation Loc;
8615+
8616+ public:
8617+ TemplateCompareNewDeclInfo(const NamedDecl *ND) : ND(ND) {}
8618+ TemplateCompareNewDeclInfo(const DeclContext *DeclCtx,
8619+ const DeclContext *LexicalDeclCtx,
8620+ SourceLocation Loc)
8621+
8622+ : DC(DeclCtx), LexicalDC(LexicalDeclCtx), Loc(Loc) {
8623+ assert(DC && LexicalDC &&
8624+ "Constructor only for cases where we have the information to put "
8625+ "in here");
8626+ }
8627+
8628+ // If this was constructed with no information, we cannot do substitution
8629+ // for constraint comparison, so make sure we can check that.
8630+ bool isInvalid() const { return !ND && !DC; }
8631+
8632+ const NamedDecl *getDecl() const { return ND; }
8633+
8634+ bool ContainsDecl(const NamedDecl *ND) const { return this->ND == ND; }
8635+
8636+ const DeclContext *getLexicalDeclContext() const {
8637+ return ND ? ND->getLexicalDeclContext() : LexicalDC;
8638+ }
8639+
8640+ const DeclContext *getDeclContext() const {
8641+ return ND ? ND->getDeclContext() : DC;
8642+ }
8643+
8644+ SourceLocation getLocation() const { return ND ? ND->getLocation() : Loc; }
8645+ };
8646+
86188647 bool TemplateParameterListsAreEqual(
8619- const NamedDecl * NewInstFrom, TemplateParameterList *New,
8648+ const TemplateCompareNewDeclInfo & NewInstFrom, TemplateParameterList *New,
86208649 const NamedDecl *OldInstFrom, TemplateParameterList *Old, bool Complain,
86218650 TemplateParameterListEqualKind Kind,
86228651 SourceLocation TemplateArgLoc = SourceLocation());
@@ -8629,6 +8658,17 @@ class Sema final {
86298658 Kind, TemplateArgLoc);
86308659 }
86318660
8661+ // Calculates whether two constraint expressions are equal irrespective of a
8662+ // difference in 'depth'. This takes a pair of optional 'NamedDecl's 'Old' and
8663+ // 'New', which are the "source" of the constraint, since this is necessary
8664+ // for figuring out the relative 'depth' of the constraint. The depth of the
8665+ // 'primary template' and the 'instantiated from' templates aren't necessarily
8666+ // the same, such as a case when one is a 'friend' defined in a class.
8667+ bool AreConstraintExpressionsEqual(const NamedDecl *Old,
8668+ const Expr *OldConstr,
8669+ const TemplateCompareNewDeclInfo &New,
8670+ const Expr *NewConstr);
8671+
86328672 bool CheckTemplateDeclScope(Scope *S, TemplateParameterList *TemplateParams);
86338673
86348674 /// Called when the parser has parsed a C++ typename
@@ -9368,13 +9408,12 @@ class Sema final {
93689408 // C++ Template Instantiation
93699409 //
93709410
9371- MultiLevelTemplateArgumentList
9372- getTemplateInstantiationArgs(const NamedDecl *D, bool Final = false,
9373- const TemplateArgumentList *Innermost = nullptr,
9374- bool RelativeToPrimary = false,
9375- const FunctionDecl *Pattern = nullptr,
9376- bool ForConstraintInstantiation = false,
9377- bool SkipForSpecialization = false);
9411+ MultiLevelTemplateArgumentList getTemplateInstantiationArgs(
9412+ const NamedDecl *D, const DeclContext *DC = nullptr, bool Final = false,
9413+ const TemplateArgumentList *Innermost = nullptr,
9414+ bool RelativeToPrimary = false, const FunctionDecl *Pattern = nullptr,
9415+ bool ForConstraintInstantiation = false,
9416+ bool SkipForSpecialization = false);
93789417
93799418 /// A context in which code is being synthesized (where a source location
93809419 /// alone is not sufficient to identify the context). This covers template
0 commit comments