@@ -3809,17 +3809,6 @@ class Sema final {
3809
3809
// the purposes of [temp.friend] p9.
3810
3810
bool FriendConstraintsDependOnEnclosingTemplate(const FunctionDecl *FD);
3811
3811
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
-
3823
3812
enum class AllowedExplicit {
3824
3813
/// Allow no explicit functions to be used.
3825
3814
None,
@@ -8615,8 +8604,48 @@ class Sema final {
8615
8604
TPL_TemplateParamsEquivalent,
8616
8605
};
8617
8606
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
+
8618
8647
bool TemplateParameterListsAreEqual(
8619
- const NamedDecl * NewInstFrom, TemplateParameterList *New,
8648
+ const TemplateCompareNewDeclInfo & NewInstFrom, TemplateParameterList *New,
8620
8649
const NamedDecl *OldInstFrom, TemplateParameterList *Old, bool Complain,
8621
8650
TemplateParameterListEqualKind Kind,
8622
8651
SourceLocation TemplateArgLoc = SourceLocation());
@@ -8629,6 +8658,17 @@ class Sema final {
8629
8658
Kind, TemplateArgLoc);
8630
8659
}
8631
8660
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
+
8632
8672
bool CheckTemplateDeclScope(Scope *S, TemplateParameterList *TemplateParams);
8633
8673
8634
8674
/// Called when the parser has parsed a C++ typename
@@ -9368,13 +9408,12 @@ class Sema final {
9368
9408
// C++ Template Instantiation
9369
9409
//
9370
9410
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);
9378
9417
9379
9418
/// A context in which code is being synthesized (where a source location
9380
9419
/// alone is not sufficient to identify the context). This covers template
0 commit comments