mizvekov updated this revision to Diff 437905.
mizvekov added a comment.

rebase


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D127351/new/

https://reviews.llvm.org/D127351

Files:
  clang/include/clang/Sema/Template.h
  clang/lib/Sema/SemaTemplateInstantiate.cpp
  clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
  clang/test/AST/ast-dump-template-decls.cpp

Index: clang/test/AST/ast-dump-template-decls.cpp
===================================================================
--- clang/test/AST/ast-dump-template-decls.cpp
+++ clang/test/AST/ast-dump-template-decls.cpp
@@ -121,7 +121,7 @@
 // CHECK-NEXT: BuiltinType 0x{{[^ ]*}} 'void'
 // CHECK-NEXT: FunctionProtoType 0x{{[^ ]*}} 'void (int)' cdecl
 // CHECK-NEXT: SubstTemplateTypeParmType 0x{{[^ ]*}} 'void' sugar
-// CHECK-NEXT: TemplateTypeParmType 0x{{[^ ]*}} 'U' dependent depth 0 index 0
+// CHECK-NEXT: TemplateTypeParmType 0x{{[^ ]*}} 'U' dependent depth 1 index 0
 // CHECK-NEXT: TemplateTypeParm 0x{{[^ ]*}} 'U'
 // CHECK-NEXT: BuiltinType 0x{{[^ ]*}} 'void'
 // CHECK-NEXT: SubstTemplateTypeParmType 0x{{[^ ]*}} 'int' sugar
Index: clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
===================================================================
--- clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -1029,8 +1029,9 @@
   // will contain the instantiations of the template parameters.
   LocalInstantiationScope Scope(SemaRef);
 
-  TemplateParameterList *TempParams = D->getTemplateParameters();
-  TemplateParameterList *InstParams = SubstTemplateParams(TempParams);
+  auto EarlySubstitutionScope = TemplateArgs.getEarlySubstitutionRAII();
+  TemplateParameterList *InstParams =
+      SubstTemplateParams(D->getTemplateParameters());
   if (!InstParams)
     return nullptr;
 
@@ -2757,7 +2758,7 @@
 
   TemplateTypeParmDecl *Inst = TemplateTypeParmDecl::Create(
       SemaRef.Context, Owner, D->getBeginLoc(), D->getLocation(),
-      D->getDepth() - TemplateArgs.getNumSubstitutedLevels(), D->getIndex(),
+      TemplateArgs.getNewDepth(D->getDepth()), D->getIndex(),
       D->getIdentifier(), D->wasDeclaredWithTypename(), D->isParameterPack(),
       D->hasTypeConstraint(), NumExpanded);
 
@@ -2910,14 +2911,14 @@
   if (IsExpandedParameterPack)
     Param = NonTypeTemplateParmDecl::Create(
         SemaRef.Context, Owner, D->getInnerLocStart(), D->getLocation(),
-        D->getDepth() - TemplateArgs.getNumSubstitutedLevels(),
-        D->getPosition(), D->getIdentifier(), T, DI, ExpandedParameterPackTypes,
+        TemplateArgs.getNewDepth(D->getDepth()), D->getPosition(),
+        D->getIdentifier(), T, DI, ExpandedParameterPackTypes,
         ExpandedParameterPackTypesAsWritten);
   else
     Param = NonTypeTemplateParmDecl::Create(
         SemaRef.Context, Owner, D->getInnerLocStart(), D->getLocation(),
-        D->getDepth() - TemplateArgs.getNumSubstitutedLevels(),
-        D->getPosition(), D->getIdentifier(), T, D->isParameterPack(), DI);
+        TemplateArgs.getNewDepth(D->getDepth()), D->getPosition(),
+        D->getIdentifier(), T, D->isParameterPack(), DI);
 
   if (AutoTypeLoc AutoLoc = DI->getTypeLoc().getContainedAutoTypeLoc())
     if (AutoLoc.isConstrained())
@@ -3051,13 +3052,13 @@
   if (IsExpandedParameterPack)
     Param = TemplateTemplateParmDecl::Create(
         SemaRef.Context, Owner, D->getLocation(),
-        D->getDepth() - TemplateArgs.getNumSubstitutedLevels(),
-        D->getPosition(), D->getIdentifier(), InstParams, ExpandedParams);
+        TemplateArgs.getNewDepth(D->getDepth()), D->getPosition(),
+        D->getIdentifier(), InstParams, ExpandedParams);
   else
     Param = TemplateTemplateParmDecl::Create(
         SemaRef.Context, Owner, D->getLocation(),
-        D->getDepth() - TemplateArgs.getNumSubstitutedLevels(),
-        D->getPosition(), D->isParameterPack(), D->getIdentifier(), InstParams);
+        TemplateArgs.getNewDepth(D->getDepth()), D->getPosition(),
+        D->isParameterPack(), D->getIdentifier(), InstParams);
   if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited()) {
     NestedNameSpecifierLoc QualifierLoc =
         D->getDefaultArgument().getTemplateQualifierLoc();
@@ -4021,6 +4022,7 @@
   if (Expr *E = L->getRequiresClause()) {
     EnterExpressionEvaluationContext ConstantEvaluated(
         SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
+    auto LateSubstitutionScope = TemplateArgs.getLateSubstitutionRAII();
     ExprResult Res = SemaRef.SubstExpr(E, TemplateArgs);
     if (Res.isInvalid() || !Res.isUsable()) {
       return nullptr;
Index: clang/lib/Sema/SemaTemplateInstantiate.cpp
===================================================================
--- clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -959,8 +959,12 @@
       this->Entity = Entity;
     }
 
-    unsigned TransformTemplateDepth(unsigned Depth) {
-      return TemplateArgs.getNewDepth(Depth);
+    unsigned TransformTemplateDepth(unsigned OldDepth) {
+      if (OldDepth < TemplateArgs.getNumRetainedOuterLevels())
+        return OldDepth;
+      if (OldDepth < TemplateArgs.getNumLevels())
+        return TemplateArgs.getNumRetainedOuterLevels();
+      return OldDepth - TemplateArgs.getNumSubstitutedLevels();
     }
 
     bool TryExpandParameterPacks(SourceLocation EllipsisLoc,
@@ -1854,7 +1858,7 @@
                                   TransformDecl(TL.getNameLoc(), OldTTPDecl));
 
   QualType Result = getSema().Context.getTemplateTypeParmType(
-      T->getDepth() - TemplateArgs.getNumSubstitutedLevels(), T->getIndex(),
+      TemplateArgs.getNewDepth(T->getDepth()), T->getIndex(),
       T->isParameterPack(), NewTTPDecl);
   TemplateTypeParmTypeLoc NewTL = TLB.push<TemplateTypeParmTypeLoc>(Result);
   NewTL.setNameLoc(TL.getNameLoc());
Index: clang/include/clang/Sema/Template.h
===================================================================
--- clang/include/clang/Sema/Template.h
+++ clang/include/clang/Sema/Template.h
@@ -86,6 +86,26 @@
 
     /// The kind of substitution described by this argument list.
     TemplateSubstitutionKind Kind = TemplateSubstitutionKind::Specialization;
+    mutable bool EarlySubstitution = false;
+
+    class SubstitutionRAII {
+      bool *EarlySubstitution, OldEarlySubstitution;
+      friend class MultiLevelTemplateArgumentList;
+
+      SubstitutionRAII(bool &EarlySubstitution, bool NewEarlySubstitution)
+          : EarlySubstitution(&EarlySubstitution),
+            OldEarlySubstitution(
+                std::exchange(EarlySubstitution, NewEarlySubstitution)) {}
+
+    public:
+      SubstitutionRAII(SubstitutionRAII &&other)
+          : EarlySubstitution(std::exchange(other.EarlySubstitution,
+                                            &other.OldEarlySubstitution)),
+            OldEarlySubstitution(other.OldEarlySubstitution) {}
+      SubstitutionRAII(const SubstitutionRAII &) = delete;
+      SubstitutionRAII &operator=(const SubstitutionRAII &) = delete;
+      ~SubstitutionRAII() { *EarlySubstitution = OldEarlySubstitution; }
+    };
 
   public:
     /// Construct an empty set of template argument lists.
@@ -128,11 +148,8 @@
     /// Determine how many of the \p OldDepth outermost template parameter
     /// lists would be removed by substituting these arguments.
     unsigned getNewDepth(unsigned OldDepth) const {
-      if (OldDepth < NumRetainedOuterLevels)
-        return OldDepth;
-      if (OldDepth < getNumLevels())
-        return NumRetainedOuterLevels;
-      return OldDepth - TemplateArgumentLists.size();
+      return EarlySubstitution ? OldDepth
+                               : OldDepth - getNumSubstitutedLevels();
     }
 
     /// Retrieve the template argument at a given depth and index.
@@ -197,6 +214,16 @@
     const ArgList &getInnermost() const {
       return TemplateArgumentLists.front();
     }
+
+    /// Get a scope object to perform early substitution.
+    SubstitutionRAII getEarlySubstitutionRAII() const {
+      return SubstitutionRAII(EarlySubstitution, true);
+    }
+
+    /// Get a scope object to perform late substitution.
+    SubstitutionRAII getLateSubstitutionRAII() const {
+      return SubstitutionRAII(EarlySubstitution, false);
+    }
   };
 
   /// The context in which partial ordering of function templates occurs.
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to