[clang] [clang-tools-extra] [clang][NFC] Un-constify `MultiLevelTemplateArgumentList` (PR #104687)

Vlad Serebrennikov via cfe-commits cfe-commits at lists.llvm.org
Sun Aug 18 03:17:16 PDT 2024


https://github.com/Endilll updated https://github.com/llvm/llvm-project/pull/104687

>From 4c67e7d449f04914d2a93ec1c73559ceb4b6e716 Mon Sep 17 00:00:00 2001
From: Vlad Serebrennikov <serebrennikov.vladislav at gmail.com>
Date: Sat, 17 Aug 2024 16:53:48 +0300
Subject: [PATCH 01/14] Step 1

---
 clang/include/clang/AST/Decl.h                 |  1 +
 clang/include/clang/AST/DeclTemplate.h         | 10 ++++++++++
 clang/include/clang/Sema/Sema.h                |  6 +++---
 clang/include/clang/Sema/Template.h            |  2 +-
 clang/lib/AST/Decl.cpp                         |  5 +++++
 clang/lib/Sema/SemaConcept.cpp                 |  4 ++--
 clang/lib/Sema/SemaTemplate.cpp                | 10 +++++-----
 clang/lib/Sema/SemaTemplateDeduction.cpp       |  6 +++---
 clang/lib/Sema/SemaTemplateInstantiate.cpp     |  4 ++--
 clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 12 ++++++------
 10 files changed, 38 insertions(+), 22 deletions(-)

diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h
index 6d84bd03de810a..f79d62f225d9ec 100644
--- a/clang/include/clang/AST/Decl.h
+++ b/clang/include/clang/AST/Decl.h
@@ -2913,6 +2913,7 @@ class FunctionDecl : public DeclaratorDecl,
   /// If this function declaration is not a function template specialization,
   /// returns NULL.
   const TemplateArgumentList *getTemplateSpecializationArgs() const;
+  TemplateArgumentList *getTemplateSpecializationArgs();
 
   /// Retrieve the template argument list as written in the sources,
   /// if any.
diff --git a/clang/include/clang/AST/DeclTemplate.h b/clang/include/clang/AST/DeclTemplate.h
index 687715a22e9fd3..8915113ea85bd0 100644
--- a/clang/include/clang/AST/DeclTemplate.h
+++ b/clang/include/clang/AST/DeclTemplate.h
@@ -275,12 +275,22 @@ class TemplateArgumentList final
     return llvm::ArrayRef(data(), size());
   }
 
+  /// Produce this as a mutable array ref.
+  MutableArrayRef<TemplateArgument> asMutableArray() {
+    return llvm::MutableArrayRef(data(), size());
+  }
+
   /// Retrieve the number of template arguments in this
   /// template argument list.
   unsigned size() const { return NumArguments; }
 
   /// Retrieve a pointer to the template argument list.
   const TemplateArgument *data() const {
+    return const_cast<TemplateArgumentList *>(this)->data();
+  }
+
+  /// Retrieve a pointer to the template argument list.
+  TemplateArgument *data() {
     return getTrailingObjects<TemplateArgument>();
   }
 };
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 299a916b9abf8d..3dd6bd31c4e469 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -11638,7 +11638,7 @@ class Sema final : public SemaBase {
   TemplateArgumentLoc SubstDefaultTemplateArgumentIfAvailable(
       TemplateDecl *Template, SourceLocation TemplateLoc,
       SourceLocation RAngleLoc, Decl *Param,
-      ArrayRef<TemplateArgument> SugaredConverted,
+      MutableArrayRef<TemplateArgument> SugaredConverted,
       ArrayRef<TemplateArgument> CanonicalConverted, bool &HasDefaultArg);
 
   /// Returns the top most location responsible for the definition of \p N.
@@ -13676,7 +13676,7 @@ class Sema final : public SemaBase {
   /// Usually this should not be used, and template argument deduction should be
   /// used in its place.
   FunctionDecl *InstantiateFunctionDeclaration(
-      FunctionTemplateDecl *FTD, const TemplateArgumentList *Args,
+      FunctionTemplateDecl *FTD, TemplateArgumentList *Args,
       SourceLocation Loc,
       CodeSynthesisContext::SynthesisKind CSC =
           CodeSynthesisContext::ExplicitTemplateArgumentSubstitution);
@@ -13705,7 +13705,7 @@ class Sema final : public SemaBase {
                                      bool AtEndOfTU = false);
   VarTemplateSpecializationDecl *BuildVarTemplateInstantiation(
       VarTemplateDecl *VarTemplate, VarDecl *FromVar,
-      const TemplateArgumentList *PartialSpecArgs,
+      TemplateArgumentList *PartialSpecArgs,
       const TemplateArgumentListInfo &TemplateArgsInfo,
       SmallVectorImpl<TemplateArgument> &Converted,
       SourceLocation PointOfInstantiation,
diff --git a/clang/include/clang/Sema/Template.h b/clang/include/clang/Sema/Template.h
index 0340c23fd170d6..4890bb8a044efd 100644
--- a/clang/include/clang/Sema/Template.h
+++ b/clang/include/clang/Sema/Template.h
@@ -76,7 +76,7 @@ enum class TemplateSubstitutionKind : char {
   class MultiLevelTemplateArgumentList {
     /// The template argument list at a certain template depth
 
-    using ArgList = ArrayRef<TemplateArgument>;
+    using ArgList = MutableArrayRef<TemplateArgument>;
     struct ArgumentListLevel {
       llvm::PointerIntPair<Decl *, 1, bool> AssociatedDeclAndFinal;
       ArgList Args;
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index 90caf81757ac96..8c688218cee2be 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -4162,6 +4162,11 @@ FunctionDecl::getTemplateSpecializationInfo() const {
 
 const TemplateArgumentList *
 FunctionDecl::getTemplateSpecializationArgs() const {
+  return const_cast<FunctionDecl *>(this)->getTemplateSpecializationArgs();
+}
+
+TemplateArgumentList *
+FunctionDecl::getTemplateSpecializationArgs() {
   if (FunctionTemplateSpecializationInfo *Info
         = TemplateOrSpecialization
             .dyn_cast<FunctionTemplateSpecializationInfo*>()) {
diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp
index de24bbe7eb99ce..b051b5f2b9ae1d 100644
--- a/clang/lib/Sema/SemaConcept.cpp
+++ b/clang/lib/Sema/SemaConcept.cpp
@@ -586,7 +586,7 @@ static bool CheckConstraintSatisfaction(
   ArrayRef<TemplateArgument> TemplateArgs =
       TemplateArgsLists.getNumSubstitutedLevels() > 0
           ? TemplateArgsLists.getOutermost()
-          : ArrayRef<TemplateArgument> {};
+          : MutableArrayRef<TemplateArgument> {};
   Sema::InstantiatingTemplate Inst(S, TemplateIDRange.getBegin(),
       Sema::InstantiatingTemplate::ConstraintsCheck{},
       const_cast<NamedDecl *>(Template), TemplateArgs, TemplateIDRange);
@@ -769,7 +769,7 @@ bool Sema::SetupConstraintScope(
     // the list of current template arguments to the list so that they also can
     // be picked out of the map.
     if (auto *SpecArgs = FD->getTemplateSpecializationArgs()) {
-      MultiLevelTemplateArgumentList JustTemplArgs(FD, SpecArgs->asArray(),
+      MultiLevelTemplateArgumentList JustTemplArgs(FD, SpecArgs->asMutableArray(),
                                                    /*Final=*/false);
       if (addInstantiatedParametersToScope(
               FD, PrimaryTemplate->getTemplatedDecl(), Scope, JustTemplArgs))
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 25585f683752ac..9005fbcea6536f 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -4190,7 +4190,7 @@ Sema::CheckVarTemplateId(VarTemplateDecl *Template, SourceLocation TemplateLoc,
   // the set of specializations, based on the closest partial specialization
   // that it represents. That is,
   VarDecl *InstantiationPattern = Template->getTemplatedDecl();
-  const TemplateArgumentList *PartialSpecArgs = nullptr;
+  TemplateArgumentList *PartialSpecArgs = nullptr;
   bool AmbiguousPartialSpec = false;
   typedef PartialSpecMatchResult MatchResult;
   SmallVector<MatchResult, 4> Matched;
@@ -4764,7 +4764,7 @@ bool Sema::CheckTemplateTypeArgument(
 static bool SubstDefaultTemplateArgument(
     Sema &SemaRef, TemplateDecl *Template, SourceLocation TemplateLoc,
     SourceLocation RAngleLoc, TemplateTypeParmDecl *Param,
-    ArrayRef<TemplateArgument> SugaredConverted,
+    MutableArrayRef<TemplateArgument> SugaredConverted,
     ArrayRef<TemplateArgument> CanonicalConverted,
     TemplateArgumentLoc &Output) {
   Output = Param->getDefaultArgument();
@@ -4824,7 +4824,7 @@ static bool SubstDefaultTemplateArgument(
 static bool SubstDefaultTemplateArgument(
     Sema &SemaRef, TemplateDecl *Template, SourceLocation TemplateLoc,
     SourceLocation RAngleLoc, NonTypeTemplateParmDecl *Param,
-    ArrayRef<TemplateArgument> SugaredConverted,
+    MutableArrayRef<TemplateArgument> SugaredConverted,
     ArrayRef<TemplateArgument> CanonicalConverted,
     TemplateArgumentLoc &Output) {
   Sema::InstantiatingTemplate Inst(SemaRef, TemplateLoc, Param, Template,
@@ -4874,7 +4874,7 @@ static bool SubstDefaultTemplateArgument(
 static TemplateName SubstDefaultTemplateArgument(
     Sema &SemaRef, TemplateDecl *Template, SourceLocation TemplateLoc,
     SourceLocation RAngleLoc, TemplateTemplateParmDecl *Param,
-    ArrayRef<TemplateArgument> SugaredConverted,
+    MutableArrayRef<TemplateArgument> SugaredConverted,
     ArrayRef<TemplateArgument> CanonicalConverted,
     NestedNameSpecifierLoc &QualifierLoc) {
   Sema::InstantiatingTemplate Inst(
@@ -4909,7 +4909,7 @@ static TemplateName SubstDefaultTemplateArgument(
 TemplateArgumentLoc Sema::SubstDefaultTemplateArgumentIfAvailable(
     TemplateDecl *Template, SourceLocation TemplateLoc,
     SourceLocation RAngleLoc, Decl *Param,
-    ArrayRef<TemplateArgument> SugaredConverted,
+    MutableArrayRef<TemplateArgument> SugaredConverted,
     ArrayRef<TemplateArgument> CanonicalConverted, bool &HasDefaultArg) {
   HasDefaultArg = false;
 
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp
index 35bc8cd713f06c..6807a4162c2c2f 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -3070,7 +3070,7 @@ template <typename TemplateDeclT>
 static TemplateDeductionResult
 CheckDeducedArgumentConstraints(Sema &S, TemplateDeclT *Template,
                                 ArrayRef<TemplateArgument> SugaredDeducedArgs,
-                                ArrayRef<TemplateArgument> CanonicalDeducedArgs,
+                                MutableArrayRef<TemplateArgument> CanonicalDeducedArgs,
                                 TemplateDeductionInfo &Info) {
   llvm::SmallVector<const Expr *, 3> AssociatedConstraints;
   Template->getAssociatedConstraints(AssociatedConstraints);
@@ -3524,7 +3524,7 @@ TemplateDeductionResult Sema::SubstituteExplicitTemplateArguments(
   ExtParameterInfoBuilder ExtParamInfos;
 
   MultiLevelTemplateArgumentList MLTAL(FunctionTemplate,
-                                       SugaredExplicitArgumentList->asArray(),
+                                       SugaredExplicitArgumentList->asMutableArray(),
                                        /*Final=*/true);
 
   // Instantiate the types of each of the function parameters given the
@@ -3877,7 +3877,7 @@ TemplateDeductionResult Sema::FinishTemplateArgumentDeduction(
     Owner = FD->getLexicalDeclContext();
   }
   MultiLevelTemplateArgumentList SubstArgs(
-      FunctionTemplate, CanonicalDeducedArgumentList->asArray(),
+      FunctionTemplate, CanonicalDeducedArgumentList->asMutableArray(),
       /*Final=*/false);
   Specialization = cast_or_null<FunctionDecl>(
       SubstDecl(FD, Owner, SubstArgs));
diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index 9a6cd2cd0ab751..a7514fb386766a 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -181,7 +181,7 @@ HandleVarTemplateSpec(const VarTemplateSpecializationDecl *VarTemplSpec,
           Specialized.dyn_cast<VarTemplatePartialSpecializationDecl *>()) {
     if (!SkipForSpecialization)
       Result.addOuterTemplateArguments(
-          Partial, VarTemplSpec->getTemplateInstantiationArgs().asArray(),
+          Partial, VarTemplSpec->getTemplateInstantiationArgs().asMutableArray(),
           /*Final=*/false);
     if (Partial->isMemberSpecialization())
       return Response::Done();
@@ -189,7 +189,7 @@ HandleVarTemplateSpec(const VarTemplateSpecializationDecl *VarTemplSpec,
     VarTemplateDecl *Tmpl = Specialized.get<VarTemplateDecl *>();
     if (!SkipForSpecialization)
       Result.addOuterTemplateArguments(
-          Tmpl, VarTemplSpec->getTemplateInstantiationArgs().asArray(),
+          Tmpl, VarTemplSpec->getTemplateInstantiationArgs().asMutableArray(),
           /*Final=*/false);
     if (Tmpl->isMemberSpecialization())
       return Response::Done();
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index a58854acb21fa5..47ba9f2a07e69c 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -497,7 +497,7 @@ static void instantiateOMPDeclareVariantAttr(
         if (!VariantFTD->isThisDeclarationADefinition())
           return;
         Sema::TentativeAnalysisScope Trap(S);
-        const TemplateArgumentList *TAL = TemplateArgumentList::CreateCopy(
+        TemplateArgumentList *TAL = TemplateArgumentList::CreateCopy(
             S.Context, TemplateArgs.getInnermost());
 
         auto *SubstFD = S.InstantiateFunctionDeclaration(VariantFTD, TAL,
@@ -1112,7 +1112,7 @@ Decl *TemplateDeclInstantiator::InstantiateTypeAliasTemplateDecl(
   Sema::InstantiatingTemplate InstTemplate(
       SemaRef, D->getBeginLoc(), D,
       D->getTemplateDepth() >= TemplateArgs.getNumLevels()
-          ? ArrayRef<TemplateArgument>()
+          ? MutableArrayRef<TemplateArgument>()
           : (TemplateArgs.begin() + TemplateArgs.getNumLevels() - 1 -
              D->getTemplateDepth())
                 ->Args);
@@ -4901,7 +4901,7 @@ bool TemplateDeclInstantiator::SubstDefaultedFunction(FunctionDecl *New,
 }
 
 FunctionDecl *Sema::InstantiateFunctionDeclaration(
-    FunctionTemplateDecl *FTD, const TemplateArgumentList *Args,
+    FunctionTemplateDecl *FTD, TemplateArgumentList *Args,
     SourceLocation Loc, CodeSynthesisContext::SynthesisKind CSC) {
   FunctionDecl *FD = FTD->getTemplatedDecl();
 
@@ -4911,7 +4911,7 @@ FunctionDecl *Sema::InstantiateFunctionDeclaration(
     return nullptr;
 
   ContextRAII SavedContext(*this, FD);
-  MultiLevelTemplateArgumentList MArgs(FTD, Args->asArray(),
+  MultiLevelTemplateArgumentList MArgs(FTD, Args->asMutableArray(),
                                        /*Final=*/false);
 
   return cast_or_null<FunctionDecl>(SubstDecl(FD, FD->getParent(), MArgs));
@@ -5252,7 +5252,7 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
 
 VarTemplateSpecializationDecl *Sema::BuildVarTemplateInstantiation(
     VarTemplateDecl *VarTemplate, VarDecl *FromVar,
-    const TemplateArgumentList *PartialSpecArgs,
+    TemplateArgumentList *PartialSpecArgs,
     const TemplateArgumentListInfo &TemplateArgsInfo,
     SmallVectorImpl<TemplateArgument> &Converted,
     SourceLocation PointOfInstantiation, LateInstantiatedAttrVec *LateAttrs,
@@ -5280,7 +5280,7 @@ VarTemplateSpecializationDecl *Sema::BuildVarTemplateInstantiation(
     assert(PartialSpecArgs);
     IsMemberSpec = PartialSpec->isMemberSpecialization();
     MultiLevelList.addOuterTemplateArguments(
-        PartialSpec, PartialSpecArgs->asArray(), /*Final=*/false);
+        PartialSpec, PartialSpecArgs->asMutableArray(), /*Final=*/false);
   } else {
     assert(VarTemplate == FromVar->getDescribedVarTemplate());
     IsMemberSpec = VarTemplate->isMemberSpecialization();

>From 0dd4119df526ea11880dea8741d2dadbd08a739a Mon Sep 17 00:00:00 2001
From: Vlad Serebrennikov <serebrennikov.vladislav at gmail.com>
Date: Sat, 17 Aug 2024 16:53:55 +0300
Subject: [PATCH 02/14] Step 2

---
 clang/include/clang/AST/DeclTemplate.h     | 44 +++++++++++------
 clang/lib/AST/DeclTemplate.cpp             |  8 +++-
 clang/lib/Sema/SemaTemplateInstantiate.cpp | 55 ++++++++++------------
 3 files changed, 62 insertions(+), 45 deletions(-)

diff --git a/clang/include/clang/AST/DeclTemplate.h b/clang/include/clang/AST/DeclTemplate.h
index 8915113ea85bd0..adf3ec56b9bac8 100644
--- a/clang/include/clang/AST/DeclTemplate.h
+++ b/clang/include/clang/AST/DeclTemplate.h
@@ -929,7 +929,8 @@ class RedeclarableTemplateDecl : public TemplateDecl,
   /// Although the C++ standard has no notion of the "injected" template
   /// arguments for a template, the notion is convenient when
   /// we need to perform substitutions inside the definition of a template.
-  ArrayRef<TemplateArgument> getInjectedTemplateArgs();
+  MutableArrayRef<TemplateArgument> getInjectedTemplateArgs();
+  ArrayRef<TemplateArgument> getInjectedTemplateArgs() const;
 
   using redecl_range = redeclarable_base::redecl_range;
   using redecl_iterator = redeclarable_base::redecl_iterator;
@@ -1829,7 +1830,7 @@ class ClassTemplateSpecializationDecl : public CXXRecordDecl,
 
     /// The template argument list deduced for the class template
     /// partial specialization itself.
-    const TemplateArgumentList *TemplateArgs;
+    TemplateArgumentList *TemplateArgs;
   };
 
   /// The template that this specialization specializes
@@ -1841,7 +1842,7 @@ class ClassTemplateSpecializationDecl : public CXXRecordDecl,
   SpecializationOrInstantiationInfo ExplicitInfo = nullptr;
 
   /// The template arguments used to describe this specialization.
-  const TemplateArgumentList *TemplateArgs;
+  TemplateArgumentList *TemplateArgs;
 
   /// The point where this template was instantiated (if any)
   SourceLocation PointOfInstantiation;
@@ -1891,9 +1892,12 @@ class ClassTemplateSpecializationDecl : public CXXRecordDecl,
 
   /// Retrieve the template arguments of the class template
   /// specialization.
-  const TemplateArgumentList &getTemplateArgs() const {
+  TemplateArgumentList &getTemplateArgs() {
     return *TemplateArgs;
   }
+  const TemplateArgumentList &getTemplateArgs() const {
+    return const_cast<ClassTemplateSpecializationDecl *>(this)->getTemplateArgs();
+  }
 
   void setTemplateArgs(TemplateArgumentList *Args) {
     TemplateArgs = Args;
@@ -1986,19 +1990,22 @@ class ClassTemplateSpecializationDecl : public CXXRecordDecl,
   /// a class template partial specialization, this function will return the
   /// deduced template arguments for the class template partial specialization
   /// itself.
-  const TemplateArgumentList &getTemplateInstantiationArgs() const {
-    if (const auto *PartialSpec =
+  TemplateArgumentList &getTemplateInstantiationArgs() {
+    if (auto *PartialSpec =
             SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
       return *PartialSpec->TemplateArgs;
 
     return getTemplateArgs();
   }
+  const TemplateArgumentList &getTemplateInstantiationArgs() const {
+    return const_cast<ClassTemplateSpecializationDecl *>(this)->getTemplateInstantiationArgs();
+  }
 
   /// Note that this class template specialization is actually an
   /// instantiation of the given class template partial specialization whose
   /// template arguments have been deduced.
   void setInstantiationOf(ClassTemplatePartialSpecializationDecl *PartialSpec,
-                          const TemplateArgumentList *TemplateArgs) {
+                          TemplateArgumentList *TemplateArgs) {
     assert(!SpecializedTemplate.is<SpecializedPartialSpecialization*>() &&
            "Already set to a class template partial specialization!");
     auto *PS = new (getASTContext()) SpecializedPartialSpecialization();
@@ -2611,7 +2618,7 @@ class VarTemplateSpecializationDecl : public VarDecl,
 
     /// The template argument list deduced for the variable template
     /// partial specialization itself.
-    const TemplateArgumentList *TemplateArgs;
+    TemplateArgumentList *TemplateArgs;
   };
 
   /// The template that this specialization specializes.
@@ -2623,7 +2630,7 @@ class VarTemplateSpecializationDecl : public VarDecl,
   SpecializationOrInstantiationInfo ExplicitInfo = nullptr;
 
   /// The template arguments used to describe this specialization.
-  const TemplateArgumentList *TemplateArgs;
+  TemplateArgumentList *TemplateArgs;
 
   /// The point where this template was instantiated (if any).
   SourceLocation PointOfInstantiation;
@@ -2675,7 +2682,10 @@ class VarTemplateSpecializationDecl : public VarDecl,
 
   /// Retrieve the template arguments of the variable template
   /// specialization.
-  const TemplateArgumentList &getTemplateArgs() const { return *TemplateArgs; }
+  TemplateArgumentList &getTemplateArgs() { return *TemplateArgs; }
+  const TemplateArgumentList &getTemplateArgs() const {
+    return const_cast<VarTemplateSpecializationDecl *>(this)->getTemplateArgs();
+  }
 
   /// Determine the kind of specialization that this
   /// declaration represents.
@@ -2751,19 +2761,22 @@ class VarTemplateSpecializationDecl : public VarDecl,
   /// from a variable template partial specialization, this function will the
   /// return deduced template arguments for the variable template partial
   /// specialization itself.
-  const TemplateArgumentList &getTemplateInstantiationArgs() const {
+  TemplateArgumentList &getTemplateInstantiationArgs() {
     if (const auto *PartialSpec =
             SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
       return *PartialSpec->TemplateArgs;
 
     return getTemplateArgs();
   }
+  const TemplateArgumentList &getTemplateInstantiationArgs() const {
+    return const_cast<VarTemplateSpecializationDecl *>(this)->getTemplateArgs();
+  }
 
   /// Note that this variable template specialization is actually an
   /// instantiation of the given variable template partial specialization whose
   /// template arguments have been deduced.
   void setInstantiationOf(VarTemplatePartialSpecializationDecl *PartialSpec,
-                          const TemplateArgumentList *TemplateArgs) {
+                          TemplateArgumentList *TemplateArgs) {
     assert(!SpecializedTemplate.is<SpecializedPartialSpecialization *>() &&
            "Already set to a variable template partial specialization!");
     auto *PS = new (getASTContext()) SpecializedPartialSpecialization();
@@ -3217,10 +3230,13 @@ class ImplicitConceptSpecializationDecl final
   CreateDeserialized(const ASTContext &C, GlobalDeclID ID,
                      unsigned NumTemplateArgs);
 
-  ArrayRef<TemplateArgument> getTemplateArguments() const {
-    return ArrayRef<TemplateArgument>(getTrailingObjects<TemplateArgument>(),
+  MutableArrayRef<TemplateArgument> getTemplateArguments() {
+    return MutableArrayRef<TemplateArgument>(getTrailingObjects<TemplateArgument>(),
                                       NumTemplateArgs);
   }
+  ArrayRef<TemplateArgument> getTemplateArguments() const {
+    return const_cast<ImplicitConceptSpecializationDecl *>(this)->getTemplateArguments();
+  }
   void setTemplateArguments(ArrayRef<TemplateArgument> Converted);
 
   static bool classofKind(Kind K) { return K == ImplicitConceptSpecialization; }
diff --git a/clang/lib/AST/DeclTemplate.cpp b/clang/lib/AST/DeclTemplate.cpp
index 976b3a3e1ecedb..2a9f9d6e71645e 100644
--- a/clang/lib/AST/DeclTemplate.cpp
+++ b/clang/lib/AST/DeclTemplate.cpp
@@ -396,7 +396,7 @@ void RedeclarableTemplateDecl::addSpecializationImpl(
                                       SETraits::getDecl(Entry));
 }
 
-ArrayRef<TemplateArgument> RedeclarableTemplateDecl::getInjectedTemplateArgs() {
+MutableArrayRef<TemplateArgument> RedeclarableTemplateDecl::getInjectedTemplateArgs() {
   TemplateParameterList *Params = getTemplateParameters();
   auto *CommonPtr = getCommonPtr();
   if (!CommonPtr->InjectedArgs) {
@@ -409,7 +409,11 @@ ArrayRef<TemplateArgument> RedeclarableTemplateDecl::getInjectedTemplateArgs() {
               CommonPtr->InjectedArgs);
   }
 
-  return llvm::ArrayRef(CommonPtr->InjectedArgs, Params->size());
+  return llvm::MutableArrayRef(CommonPtr->InjectedArgs, Params->size());
+}
+
+ArrayRef<TemplateArgument> RedeclarableTemplateDecl::getInjectedTemplateArgs() const {
+  return const_cast<RedeclarableTemplateDecl *>(this)->getInjectedTemplateArgs();
 }
 
 //===----------------------------------------------------------------------===//
diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index a7514fb386766a..92a2d2d1c983c1 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -159,7 +159,7 @@ bool isLambdaEnclosedByTypeAliasDecl(
 
 // Add template arguments from a variable template instantiation.
 Response
-HandleVarTemplateSpec(const VarTemplateSpecializationDecl *VarTemplSpec,
+HandleVarTemplateSpec(VarTemplateSpecializationDecl *VarTemplSpec,
                       MultiLevelTemplateArgumentList &Result,
                       bool SkipForSpecialization) {
   // For a class-scope explicit specialization, there are no template arguments
@@ -221,7 +221,7 @@ Response HandlePartialClassTemplateSpec(
 
 // Add template arguments from a class template instantiation.
 Response
-HandleClassTemplateSpec(const ClassTemplateSpecializationDecl *ClassTemplSpec,
+HandleClassTemplateSpec(ClassTemplateSpecializationDecl *ClassTemplSpec,
                         MultiLevelTemplateArgumentList &Result,
                         bool SkipForSpecialization) {
   if (!ClassTemplSpec->isClassScopeExplicitSpecialization()) {
@@ -232,8 +232,8 @@ HandleClassTemplateSpec(const ClassTemplateSpecializationDecl *ClassTemplSpec,
 
     if (!SkipForSpecialization)
       Result.addOuterTemplateArguments(
-          const_cast<ClassTemplateSpecializationDecl *>(ClassTemplSpec),
-          ClassTemplSpec->getTemplateInstantiationArgs().asArray(),
+          ClassTemplSpec,
+          ClassTemplSpec->getTemplateInstantiationArgs().asMutableArray(),
           /*Final=*/false);
 
     // If this class template specialization was instantiated from a
@@ -253,7 +253,7 @@ HandleClassTemplateSpec(const ClassTemplateSpecializationDecl *ClassTemplSpec,
   return Response::UseNextDecl(ClassTemplSpec);
 }
 
-Response HandleFunction(Sema &SemaRef, const FunctionDecl *Function,
+Response HandleFunction(Sema &SemaRef, FunctionDecl *Function,
                         MultiLevelTemplateArgumentList &Result,
                         const FunctionDecl *Pattern, bool RelativeToPrimary,
                         bool ForConstraintInstantiation) {
@@ -269,11 +269,11 @@ Response HandleFunction(Sema &SemaRef, const FunctionDecl *Function,
     // don't get any template arguments from this function but might get
     // some from an enclosing template.
     return Response::UseNextDecl(Function);
-  } else if (const TemplateArgumentList *TemplateArgs =
+  } else if (TemplateArgumentList *TemplateArgs =
                  Function->getTemplateSpecializationArgs()) {
     // Add the template arguments for this specialization.
     Result.addOuterTemplateArguments(const_cast<FunctionDecl *>(Function),
-                                     TemplateArgs->asArray(),
+                                     TemplateArgs->asMutableArray(),
                                      /*Final=*/false);
 
     if (RelativeToPrimary &&
@@ -329,20 +329,20 @@ Response HandleFunction(Sema &SemaRef, const FunctionDecl *Function,
   return Response::UseNextDecl(Function);
 }
 
-Response HandleFunctionTemplateDecl(const FunctionTemplateDecl *FTD,
+Response HandleFunctionTemplateDecl(FunctionTemplateDecl *FTD,
                                     MultiLevelTemplateArgumentList &Result) {
   if (!isa<ClassTemplateSpecializationDecl>(FTD->getDeclContext())) {
     Result.addOuterTemplateArguments(
-        const_cast<FunctionTemplateDecl *>(FTD),
-        const_cast<FunctionTemplateDecl *>(FTD)->getInjectedTemplateArgs(),
+        FTD,
+        FTD->getInjectedTemplateArgs(),
         /*Final=*/false);
 
     NestedNameSpecifier *NNS = FTD->getTemplatedDecl()->getQualifier();
 
-    while (const Type *Ty = NNS ? NNS->getAsType() : nullptr) {
+    while (Type *Ty = NNS ? NNS->getAsType() : nullptr) {
       if (NNS->isInstantiationDependent()) {
-        if (const auto *TSTy = Ty->getAs<TemplateSpecializationType>()) {
-          ArrayRef<TemplateArgument> Arguments = TSTy->template_arguments();
+        if (auto *TSTy = Ty->getAs<TemplateSpecializationType>()) {
+          MutableArrayRef<TemplateArgument> Arguments = TSTy->template_arguments();
           // Prefer template arguments from the injected-class-type if possible.
           // For example,
           // ```cpp
@@ -367,11 +367,9 @@ Response HandleFunctionTemplateDecl(const FunctionTemplateDecl *FTD,
             else if (auto *Specialization =
                          dyn_cast<ClassTemplateSpecializationDecl>(RD))
               Arguments =
-                  Specialization->getTemplateInstantiationArgs().asArray();
+                  Specialization->getTemplateInstantiationArgs().asMutableArray();
           }
-          Result.addOuterTemplateArguments(
-              const_cast<FunctionTemplateDecl *>(FTD), Arguments,
-              /*Final=*/false);
+          Result.addOuterTemplateArguments(FTD, Arguments, /*Final=*/false);
         }
       }
 
@@ -449,10 +447,10 @@ Response HandleRecordDecl(Sema &SemaRef, const CXXRecordDecl *Rec,
 }
 
 Response HandleImplicitConceptSpecializationDecl(
-    const ImplicitConceptSpecializationDecl *CSD,
+    ImplicitConceptSpecializationDecl *CSD,
     MultiLevelTemplateArgumentList &Result) {
   Result.addOuterTemplateArguments(
-      const_cast<ImplicitConceptSpecializationDecl *>(CSD),
+      CSD,
       CSD->getTemplateArguments(),
       /*Final=*/false);
   return Response::UseNextDecl(CSD);
@@ -466,7 +464,7 @@ Response HandleGenericDeclContext(const Decl *CurDecl) {
 
 MultiLevelTemplateArgumentList Sema::getTemplateInstantiationArgs(
     const NamedDecl *ND, const DeclContext *DC, bool Final,
-    std::optional<ArrayRef<TemplateArgument>> Innermost, bool RelativeToPrimary,
+    std::optional<MutableArrayRef<TemplateArgument>> Innermost, bool RelativeToPrimary,
     const FunctionDecl *Pattern, bool ForConstraintInstantiation,
     bool SkipForSpecialization) {
   assert((ND || DC) && "Can't find arguments for a decl if one isn't provided");
@@ -474,14 +472,13 @@ MultiLevelTemplateArgumentList Sema::getTemplateInstantiationArgs(
   MultiLevelTemplateArgumentList Result;
 
   using namespace TemplateInstArgsHelpers;
-  const Decl *CurDecl = ND;
+  Decl *CurDecl = ND;
 
   if (!CurDecl)
     CurDecl = Decl::castFromDeclContext(DC);
 
   if (Innermost) {
-    Result.addOuterTemplateArguments(const_cast<NamedDecl *>(ND), *Innermost,
-                                     Final);
+    Result.addOuterTemplateArguments(ND, *Innermost, Final);
     // Populate placeholder template arguments for TemplateTemplateParmDecls.
     // This is essential for the case e.g.
     //
@@ -497,27 +494,27 @@ MultiLevelTemplateArgumentList Sema::getTemplateInstantiationArgs(
 
   while (!CurDecl->isFileContextDecl()) {
     Response R;
-    if (const auto *VarTemplSpec =
+    if (auto *VarTemplSpec =
             dyn_cast<VarTemplateSpecializationDecl>(CurDecl)) {
       R = HandleVarTemplateSpec(VarTemplSpec, Result, SkipForSpecialization);
     } else if (const auto *PartialClassTemplSpec =
                    dyn_cast<ClassTemplatePartialSpecializationDecl>(CurDecl)) {
       R = HandlePartialClassTemplateSpec(PartialClassTemplSpec, Result,
                                          SkipForSpecialization);
-    } else if (const auto *ClassTemplSpec =
+    } else if (auto *ClassTemplSpec =
                    dyn_cast<ClassTemplateSpecializationDecl>(CurDecl)) {
       R = HandleClassTemplateSpec(ClassTemplSpec, Result,
                                   SkipForSpecialization);
-    } else if (const auto *Function = dyn_cast<FunctionDecl>(CurDecl)) {
+    } else if (auto *Function = dyn_cast<FunctionDecl>(CurDecl)) {
       R = HandleFunction(*this, Function, Result, Pattern, RelativeToPrimary,
                          ForConstraintInstantiation);
     } else if (const auto *Rec = dyn_cast<CXXRecordDecl>(CurDecl)) {
       R = HandleRecordDecl(*this, Rec, Result, Context,
                            ForConstraintInstantiation);
-    } else if (const auto *CSD =
+    } else if (auto *CSD =
                    dyn_cast<ImplicitConceptSpecializationDecl>(CurDecl)) {
       R = HandleImplicitConceptSpecializationDecl(CSD, Result);
-    } else if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(CurDecl)) {
+    } else if (auto *FTD = dyn_cast<FunctionTemplateDecl>(CurDecl)) {
       R = HandleFunctionTemplateDecl(FTD, Result);
     } else if (const auto *CTD = dyn_cast<ClassTemplateDecl>(CurDecl)) {
       R = Response::ChangeDecl(CTD->getLexicalDeclContext());
@@ -3247,7 +3244,7 @@ bool Sema::SubstDefaultArgument(
                                              TemplateArgs.getInnermost());
         NewTemplateArgs = getTemplateInstantiationArgs(
             FD, FD->getDeclContext(), /*Final=*/false,
-            CurrentTemplateArgumentList->asArray(), /*RelativeToPrimary=*/true);
+            CurrentTemplateArgumentList->asMutableArray(), /*RelativeToPrimary=*/true);
       }
     }
 

>From 27275d5441cf3b37c6a033bd26093c020906656e Mon Sep 17 00:00:00 2001
From: Vlad Serebrennikov <serebrennikov.vladislav at gmail.com>
Date: Sat, 17 Aug 2024 17:03:34 +0300
Subject: [PATCH 03/14] Step 3

---
 clang/include/clang/AST/ExprConcepts.h   | 5 ++++-
 clang/include/clang/Sema/Sema.h          | 2 +-
 clang/lib/Sema/SemaConcept.cpp           | 4 ++--
 clang/lib/Sema/SemaTemplateDeduction.cpp | 2 +-
 4 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/clang/include/clang/AST/ExprConcepts.h b/clang/include/clang/AST/ExprConcepts.h
index 29913fd84c58b4..76ab0bbbccd46f 100644
--- a/clang/include/clang/AST/ExprConcepts.h
+++ b/clang/include/clang/AST/ExprConcepts.h
@@ -78,9 +78,12 @@ class ConceptSpecializationExpr final : public Expr {
          const ConstraintSatisfaction *Satisfaction, bool Dependent,
          bool ContainsUnexpandedParameterPack);
 
-  ArrayRef<TemplateArgument> getTemplateArguments() const {
+  MutableArrayRef<TemplateArgument> getTemplateArguments() {
     return SpecDecl->getTemplateArguments();
   }
+  ArrayRef<TemplateArgument> getTemplateArguments() const {
+    return const_cast<ConceptSpecializationExpr *>(this)->getTemplateArguments();
+  }
 
   ConceptReference *getConceptReference() const { return ConceptRef; }
 
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 3dd6bd31c4e469..1a54209e51c023 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -13073,7 +13073,7 @@ class Sema final : public SemaBase {
   /// arguments on an enclosing class template.
   MultiLevelTemplateArgumentList getTemplateInstantiationArgs(
       const NamedDecl *D, const DeclContext *DC = nullptr, bool Final = false,
-      std::optional<ArrayRef<TemplateArgument>> Innermost = std::nullopt,
+      std::optional<MutableArrayRef<TemplateArgument>> Innermost = std::nullopt,
       bool RelativeToPrimary = false, const FunctionDecl *Pattern = nullptr,
       bool ForConstraintInstantiation = false,
       bool SkipForSpecialization = false);
diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp
index b051b5f2b9ae1d..8f76691356cb70 100644
--- a/clang/lib/Sema/SemaConcept.cpp
+++ b/clang/lib/Sema/SemaConcept.cpp
@@ -1485,7 +1485,7 @@ substituteParameterMappings(Sema &S, NormalizedConstraint &N,
 }
 
 static bool substituteParameterMappings(Sema &S, NormalizedConstraint &N,
-                                        const ConceptSpecializationExpr *CSE) {
+                                        ConceptSpecializationExpr *CSE) {
   MultiLevelTemplateArgumentList MLTAL = S.getTemplateInstantiationArgs(
       CSE->getNamedConcept(), CSE->getNamedConcept()->getLexicalDeclContext(),
       /*Final=*/false, CSE->getTemplateArguments(),
@@ -1575,7 +1575,7 @@ NormalizedConstraint::fromConstraintExpr(Sema &S, NamedDecl *D, const Expr *E) {
 
     return NormalizedConstraint(S.Context, std::move(*LHS), std::move(*RHS),
                                 BO.isAnd() ? CCK_Conjunction : CCK_Disjunction);
-  } else if (auto *CSE = dyn_cast<const ConceptSpecializationExpr>(E)) {
+  } else if (auto *CSE = dyn_cast<ConceptSpecializationExpr>(const_cast<Expr *>(E))) {
     const NormalizedConstraint *SubNF;
     {
       Sema::InstantiatingTemplate Inst(
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp
index 6807a4162c2c2f..ef3b04c7ff4b09 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -3075,7 +3075,7 @@ CheckDeducedArgumentConstraints(Sema &S, TemplateDeclT *Template,
   llvm::SmallVector<const Expr *, 3> AssociatedConstraints;
   Template->getAssociatedConstraints(AssociatedConstraints);
 
-  std::optional<ArrayRef<TemplateArgument>> Innermost;
+  std::optional<MutableArrayRef<TemplateArgument>> Innermost;
   // If we don't need to replace the deduced template arguments,
   // we can add them immediately as the inner-most argument list.
   if (!DeducedArgsNeedReplacement(Template))

>From 08bf81f6900ca8f47452090ebe183efd222fcafc Mon Sep 17 00:00:00 2001
From: Vlad Serebrennikov <serebrennikov.vladislav at gmail.com>
Date: Sat, 17 Aug 2024 17:35:29 +0300
Subject: [PATCH 04/14] Step 4

---
 clang/include/clang/AST/NestedNameSpecifier.h |  7 +++-
 clang/include/clang/AST/Type.h                |  7 +++-
 clang/include/clang/Sema/Sema.h               | 37 ++++++++++---------
 clang/lib/Sema/SemaConcept.cpp                | 12 +++---
 clang/lib/Sema/SemaTemplateDeduction.cpp      |  2 +-
 clang/lib/Sema/SemaTemplateInstantiate.cpp    | 36 +++++++++---------
 .../lib/Sema/SemaTemplateInstantiateDecl.cpp  |  2 +-
 7 files changed, 56 insertions(+), 47 deletions(-)

diff --git a/clang/include/clang/AST/NestedNameSpecifier.h b/clang/include/clang/AST/NestedNameSpecifier.h
index a1d9e30e660d14..7a8611947c30cf 100644
--- a/clang/include/clang/AST/NestedNameSpecifier.h
+++ b/clang/include/clang/AST/NestedNameSpecifier.h
@@ -193,13 +193,16 @@ class NestedNameSpecifier : public llvm::FoldingSetNode {
   CXXRecordDecl *getAsRecordDecl() const;
 
   /// Retrieve the type stored in this nested name specifier.
-  const Type *getAsType() const {
+  Type *getAsType() {
     if (Prefix.getInt() == StoredTypeSpec ||
         Prefix.getInt() == StoredTypeSpecWithTemplate)
-      return (const Type *)Specifier;
+      return static_cast<Type *>(Specifier);
 
     return nullptr;
   }
+  const Type *getAsType() const {
+    return const_cast<NestedNameSpecifier *>(this)->getAsType();
+  }
 
   NestedNameSpecifierDependence getDependence() const;
 
diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index 27618604192c51..bacbdabf0e0242 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -6545,10 +6545,13 @@ class TemplateSpecializationType : public Type, public llvm::FoldingSetNode {
   /// Retrieve the name of the template that we are specializing.
   TemplateName getTemplateName() const { return Template; }
 
-  ArrayRef<TemplateArgument> template_arguments() const {
-    return {reinterpret_cast<const TemplateArgument *>(this + 1),
+  MutableArrayRef<TemplateArgument> template_arguments() {
+    return {reinterpret_cast<TemplateArgument *>(this + 1),
             TemplateSpecializationTypeBits.NumArgs};
   }
+  ArrayRef<TemplateArgument> template_arguments() const {
+    return const_cast<TemplateSpecializationType *>(this)->template_arguments();
+  }
 
   bool isSugared() const {
     return !isDependentType() || isCurrentInstantiation() || isTypeAlias();
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 1a54209e51c023..8a3d6a406bc1a9 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -12800,7 +12800,7 @@ class Sema final : public SemaBase {
     union {
       /// The list of template arguments we are substituting, if they
       /// are not part of the entity.
-      const TemplateArgument *TemplateArgs;
+      TemplateArgument *TemplateArgs;
 
       /// The list of argument expressions in a synthesized call.
       const Expr *const *CallArgs;
@@ -12819,10 +12819,13 @@ class Sema final : public SemaBase {
       CXXSpecialMemberKind SpecialMember;
     };
 
-    ArrayRef<TemplateArgument> template_arguments() const {
+    MutableArrayRef<TemplateArgument> template_arguments() {
       assert(Kind != DeclaringSpecialMember);
       return {TemplateArgs, NumTemplateArgs};
     }
+    ArrayRef<TemplateArgument> template_arguments() const {
+      return const_cast<CodeSynthesisContext *>(this)->template_arguments();
+    }
 
     /// The template deduction info object associated with the
     /// substitution or checking of explicit or deduced template arguments.
@@ -12873,21 +12876,21 @@ class Sema final : public SemaBase {
     /// Note that we are instantiating a type alias template declaration.
     InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
                           TypeAliasTemplateDecl *Entity,
-                          ArrayRef<TemplateArgument> TemplateArgs,
+                          MutableArrayRef<TemplateArgument> TemplateArgs,
                           SourceRange InstantiationRange = SourceRange());
 
     /// Note that we are instantiating a default argument in a
     /// template-id.
     InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
                           TemplateParameter Param, TemplateDecl *Template,
-                          ArrayRef<TemplateArgument> TemplateArgs,
+                          MutableArrayRef<TemplateArgument> TemplateArgs,
                           SourceRange InstantiationRange = SourceRange());
 
     /// Note that we are substituting either explicitly-specified or
     /// deduced template arguments during function template argument deduction.
     InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
                           FunctionTemplateDecl *FunctionTemplate,
-                          ArrayRef<TemplateArgument> TemplateArgs,
+                          MutableArrayRef<TemplateArgument> TemplateArgs,
                           CodeSynthesisContext::SynthesisKind Kind,
                           sema::TemplateDeductionInfo &DeductionInfo,
                           SourceRange InstantiationRange = SourceRange());
@@ -12896,7 +12899,7 @@ class Sema final : public SemaBase {
     /// argument deduction for a class template declaration.
     InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
                           TemplateDecl *Template,
-                          ArrayRef<TemplateArgument> TemplateArgs,
+                          MutableArrayRef<TemplateArgument> TemplateArgs,
                           sema::TemplateDeductionInfo &DeductionInfo,
                           SourceRange InstantiationRange = SourceRange());
 
@@ -12905,7 +12908,7 @@ class Sema final : public SemaBase {
     /// specialization.
     InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
                           ClassTemplatePartialSpecializationDecl *PartialSpec,
-                          ArrayRef<TemplateArgument> TemplateArgs,
+                          MutableArrayRef<TemplateArgument> TemplateArgs,
                           sema::TemplateDeductionInfo &DeductionInfo,
                           SourceRange InstantiationRange = SourceRange());
 
@@ -12914,7 +12917,7 @@ class Sema final : public SemaBase {
     /// specialization.
     InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
                           VarTemplatePartialSpecializationDecl *PartialSpec,
-                          ArrayRef<TemplateArgument> TemplateArgs,
+                          MutableArrayRef<TemplateArgument> TemplateArgs,
                           sema::TemplateDeductionInfo &DeductionInfo,
                           SourceRange InstantiationRange = SourceRange());
 
@@ -12922,28 +12925,28 @@ class Sema final : public SemaBase {
     /// parameter.
     InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
                           ParmVarDecl *Param,
-                          ArrayRef<TemplateArgument> TemplateArgs,
+                          MutableArrayRef<TemplateArgument> TemplateArgs,
                           SourceRange InstantiationRange = SourceRange());
 
     /// Note that we are substituting prior template arguments into a
     /// non-type parameter.
     InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
                           NamedDecl *Template, NonTypeTemplateParmDecl *Param,
-                          ArrayRef<TemplateArgument> TemplateArgs,
+                          MutableArrayRef<TemplateArgument> TemplateArgs,
                           SourceRange InstantiationRange);
 
     /// Note that we are substituting prior template arguments into a
     /// template template parameter.
     InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
                           NamedDecl *Template, TemplateTemplateParmDecl *Param,
-                          ArrayRef<TemplateArgument> TemplateArgs,
+                          MutableArrayRef<TemplateArgument> TemplateArgs,
                           SourceRange InstantiationRange);
 
     /// Note that we are checking the default template argument
     /// against the template parameter for a given template-id.
     InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
                           TemplateDecl *Template, NamedDecl *Param,
-                          ArrayRef<TemplateArgument> TemplateArgs,
+                          MutableArrayRef<TemplateArgument> TemplateArgs,
                           SourceRange InstantiationRange);
 
     struct ConstraintsCheck {};
@@ -12952,7 +12955,7 @@ class Sema final : public SemaBase {
     /// constraints).
     InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
                           ConstraintsCheck, NamedDecl *Template,
-                          ArrayRef<TemplateArgument> TemplateArgs,
+                          MutableArrayRef<TemplateArgument> TemplateArgs,
                           SourceRange InstantiationRange);
 
     struct ConstraintSubstitution {};
@@ -13026,7 +13029,7 @@ class Sema final : public SemaBase {
         Sema &SemaRef, CodeSynthesisContext::SynthesisKind Kind,
         SourceLocation PointOfInstantiation, SourceRange InstantiationRange,
         Decl *Entity, NamedDecl *Template = nullptr,
-        ArrayRef<TemplateArgument> TemplateArgs = std::nullopt,
+        MutableArrayRef<TemplateArgument> TemplateArgs = std::nullopt,
         sema::TemplateDeductionInfo *DeductionInfo = nullptr);
 
     InstantiatingTemplate(const InstantiatingTemplate &) = delete;
@@ -14458,7 +14461,7 @@ class Sema final : public SemaBase {
 
   bool CheckInstantiatedFunctionTemplateConstraints(
       SourceLocation PointOfInstantiation, FunctionDecl *Decl,
-      ArrayRef<TemplateArgument> TemplateArgs,
+      MutableArrayRef<TemplateArgument> TemplateArgs,
       ConstraintSatisfaction &Satisfaction);
 
   /// \brief Emit diagnostics explaining why a constraint expression was deemed
@@ -14526,7 +14529,7 @@ class Sema final : public SemaBase {
   /// function.
   bool
   SetupConstraintScope(FunctionDecl *FD,
-                       std::optional<ArrayRef<TemplateArgument>> TemplateArgs,
+                       std::optional<MutableArrayRef<TemplateArgument>> TemplateArgs,
                        const MultiLevelTemplateArgumentList &MLTAL,
                        LocalInstantiationScope &Scope);
 
@@ -14535,7 +14538,7 @@ class Sema final : public SemaBase {
   /// LocalInstantiationScope to have the proper set of ParVarDecls configured.
   std::optional<MultiLevelTemplateArgumentList>
   SetupConstraintCheckingTemplateArgumentsAndScope(
-      FunctionDecl *FD, std::optional<ArrayRef<TemplateArgument>> TemplateArgs,
+      FunctionDecl *FD, std::optional<MutableArrayRef<TemplateArgument>> TemplateArgs,
       LocalInstantiationScope &Scope);
 
   ///@}
diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp
index 8f76691356cb70..48319354ca2b9f 100644
--- a/clang/lib/Sema/SemaConcept.cpp
+++ b/clang/lib/Sema/SemaConcept.cpp
@@ -583,7 +583,7 @@ static bool CheckConstraintSatisfaction(
     return false;
   }
 
-  ArrayRef<TemplateArgument> TemplateArgs =
+  MutableArrayRef<TemplateArgument> TemplateArgs =
       TemplateArgsLists.getNumSubstitutedLevels() > 0
           ? TemplateArgsLists.getOutermost()
           : MutableArrayRef<TemplateArgument> {};
@@ -750,7 +750,7 @@ bool Sema::addInstantiatedCapturesToScope(
 }
 
 bool Sema::SetupConstraintScope(
-    FunctionDecl *FD, std::optional<ArrayRef<TemplateArgument>> TemplateArgs,
+    FunctionDecl *FD, std::optional<MutableArrayRef<TemplateArgument>> TemplateArgs,
     const MultiLevelTemplateArgumentList &MLTAL,
     LocalInstantiationScope &Scope) {
   if (FD->isTemplateInstantiation() && FD->getPrimaryTemplate()) {
@@ -758,7 +758,7 @@ bool Sema::SetupConstraintScope(
     InstantiatingTemplate Inst(
         *this, FD->getPointOfInstantiation(),
         Sema::InstantiatingTemplate::ConstraintsCheck{}, PrimaryTemplate,
-        TemplateArgs ? *TemplateArgs : ArrayRef<TemplateArgument>{},
+        TemplateArgs ? *TemplateArgs : MutableArrayRef<TemplateArgument>{},
         SourceRange());
     if (Inst.isInvalid())
       return true;
@@ -804,7 +804,7 @@ bool Sema::SetupConstraintScope(
     InstantiatingTemplate Inst(
         *this, FD->getPointOfInstantiation(),
         Sema::InstantiatingTemplate::ConstraintsCheck{}, InstantiatedFrom,
-        TemplateArgs ? *TemplateArgs : ArrayRef<TemplateArgument>{},
+        TemplateArgs ? *TemplateArgs : MutableArrayRef<TemplateArgument>{},
         SourceRange());
     if (Inst.isInvalid())
       return true;
@@ -822,7 +822,7 @@ bool Sema::SetupConstraintScope(
 // constraint-instantiation and checking.
 std::optional<MultiLevelTemplateArgumentList>
 Sema::SetupConstraintCheckingTemplateArgumentsAndScope(
-    FunctionDecl *FD, std::optional<ArrayRef<TemplateArgument>> TemplateArgs,
+    FunctionDecl *FD, std::optional<MutableArrayRef<TemplateArgument>> TemplateArgs,
     LocalInstantiationScope &Scope) {
   MultiLevelTemplateArgumentList MLTAL;
 
@@ -1081,7 +1081,7 @@ bool Sema::EnsureTemplateArgumentListConstraints(
 
 bool Sema::CheckInstantiatedFunctionTemplateConstraints(
     SourceLocation PointOfInstantiation, FunctionDecl *Decl,
-    ArrayRef<TemplateArgument> TemplateArgs,
+    MutableArrayRef<TemplateArgument> TemplateArgs,
     ConstraintSatisfaction &Satisfaction) {
   // In most cases we're not going to have constraints, so check for that first.
   FunctionTemplateDecl *Template = Decl->getPrimaryTemplate();
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp
index ef3b04c7ff4b09..e7cacedb079793 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -3766,7 +3766,7 @@ static TemplateDeductionResult instantiateExplicitSpecifierDeferred(
     Sema &S, FunctionDecl *Specialization,
     const MultiLevelTemplateArgumentList &SubstArgs,
     TemplateDeductionInfo &Info, FunctionTemplateDecl *FunctionTemplate,
-    ArrayRef<TemplateArgument> DeducedArgs) {
+    MutableArrayRef<TemplateArgument> DeducedArgs) {
   auto GetExplicitSpecifier = [](FunctionDecl *D) {
     return isa<CXXConstructorDecl>(D)
                ? cast<CXXConstructorDecl>(D)->getExplicitSpecifier()
diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index 92a2d2d1c983c1..61c4891f4abcf1 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -106,7 +106,7 @@ getPrimaryTemplateOfGenericLambda(const FunctionDecl *LambdaCallOperator) {
 struct EnclosingTypeAliasTemplateDetails {
   TypeAliasTemplateDecl *Template = nullptr;
   TypeAliasTemplateDecl *PrimaryTypeAliasDecl = nullptr;
-  ArrayRef<TemplateArgument> AssociatedTemplateArguments;
+  MutableArrayRef<TemplateArgument> AssociatedTemplateArguments;
 
   explicit operator bool() noexcept { return Template; }
 };
@@ -341,7 +341,7 @@ Response HandleFunctionTemplateDecl(FunctionTemplateDecl *FTD,
 
     while (Type *Ty = NNS ? NNS->getAsType() : nullptr) {
       if (NNS->isInstantiationDependent()) {
-        if (auto *TSTy = Ty->getAs<TemplateSpecializationType>()) {
+        if (auto *TSTy = const_cast<TemplateSpecializationType *>(Ty->getAs<TemplateSpecializationType>())) {
           MutableArrayRef<TemplateArgument> Arguments = TSTy->template_arguments();
           // Prefer template arguments from the injected-class-type if possible.
           // For example,
@@ -472,13 +472,13 @@ MultiLevelTemplateArgumentList Sema::getTemplateInstantiationArgs(
   MultiLevelTemplateArgumentList Result;
 
   using namespace TemplateInstArgsHelpers;
-  Decl *CurDecl = ND;
+  Decl *CurDecl = const_cast<NamedDecl *>(ND);
 
   if (!CurDecl)
     CurDecl = Decl::castFromDeclContext(DC);
 
   if (Innermost) {
-    Result.addOuterTemplateArguments(ND, *Innermost, Final);
+    Result.addOuterTemplateArguments(const_cast<NamedDecl *>(ND), *Innermost, Final);
     // Populate placeholder template arguments for TemplateTemplateParmDecls.
     // This is essential for the case e.g.
     //
@@ -489,7 +489,7 @@ MultiLevelTemplateArgumentList Sema::getTemplateInstantiationArgs(
     // has a depth of 0.
     if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(CurDecl))
       HandleDefaultTempArgIntoTempTempParam(TTP, Result);
-    CurDecl = Response::UseNextDecl(CurDecl).NextDecl;
+    CurDecl = const_cast<Decl *>(Response::UseNextDecl(CurDecl).NextDecl);
   }
 
   while (!CurDecl->isFileContextDecl()) {
@@ -532,7 +532,7 @@ MultiLevelTemplateArgumentList Sema::getTemplateInstantiationArgs(
     if (R.ClearRelativeToPrimary)
       RelativeToPrimary = false;
     assert(R.NextDecl);
-    CurDecl = R.NextDecl;
+    CurDecl = const_cast<Decl *>(R.NextDecl);
   }
 
   return Result;
@@ -581,7 +581,7 @@ bool Sema::CodeSynthesisContext::isInstantiationRecord() const {
 Sema::InstantiatingTemplate::InstantiatingTemplate(
     Sema &SemaRef, CodeSynthesisContext::SynthesisKind Kind,
     SourceLocation PointOfInstantiation, SourceRange InstantiationRange,
-    Decl *Entity, NamedDecl *Template, ArrayRef<TemplateArgument> TemplateArgs,
+    Decl *Entity, NamedDecl *Template, MutableArrayRef<TemplateArgument> TemplateArgs,
     sema::TemplateDeductionInfo *DeductionInfo)
     : SemaRef(SemaRef) {
   // Don't allow further instantiation if a fatal error and an uncompilable
@@ -629,7 +629,7 @@ Sema::InstantiatingTemplate::InstantiatingTemplate(
 
 Sema::InstantiatingTemplate::InstantiatingTemplate(
     Sema &SemaRef, SourceLocation PointOfInstantiation, TemplateParameter Param,
-    TemplateDecl *Template, ArrayRef<TemplateArgument> TemplateArgs,
+    TemplateDecl *Template, MutableArrayRef<TemplateArgument> TemplateArgs,
     SourceRange InstantiationRange)
     : InstantiatingTemplate(
           SemaRef,
@@ -640,7 +640,7 @@ Sema::InstantiatingTemplate::InstantiatingTemplate(
 Sema::InstantiatingTemplate::InstantiatingTemplate(
     Sema &SemaRef, SourceLocation PointOfInstantiation,
     FunctionTemplateDecl *FunctionTemplate,
-    ArrayRef<TemplateArgument> TemplateArgs,
+    MutableArrayRef<TemplateArgument> TemplateArgs,
     CodeSynthesisContext::SynthesisKind Kind,
     sema::TemplateDeductionInfo &DeductionInfo, SourceRange InstantiationRange)
     : InstantiatingTemplate(SemaRef, Kind, PointOfInstantiation,
@@ -654,7 +654,7 @@ Sema::InstantiatingTemplate::InstantiatingTemplate(
 Sema::InstantiatingTemplate::InstantiatingTemplate(
     Sema &SemaRef, SourceLocation PointOfInstantiation,
     TemplateDecl *Template,
-    ArrayRef<TemplateArgument> TemplateArgs,
+    MutableArrayRef<TemplateArgument> TemplateArgs,
     sema::TemplateDeductionInfo &DeductionInfo, SourceRange InstantiationRange)
     : InstantiatingTemplate(
           SemaRef,
@@ -665,7 +665,7 @@ Sema::InstantiatingTemplate::InstantiatingTemplate(
 Sema::InstantiatingTemplate::InstantiatingTemplate(
     Sema &SemaRef, SourceLocation PointOfInstantiation,
     ClassTemplatePartialSpecializationDecl *PartialSpec,
-    ArrayRef<TemplateArgument> TemplateArgs,
+    MutableArrayRef<TemplateArgument> TemplateArgs,
     sema::TemplateDeductionInfo &DeductionInfo, SourceRange InstantiationRange)
     : InstantiatingTemplate(
           SemaRef,
@@ -676,7 +676,7 @@ Sema::InstantiatingTemplate::InstantiatingTemplate(
 Sema::InstantiatingTemplate::InstantiatingTemplate(
     Sema &SemaRef, SourceLocation PointOfInstantiation,
     VarTemplatePartialSpecializationDecl *PartialSpec,
-    ArrayRef<TemplateArgument> TemplateArgs,
+    MutableArrayRef<TemplateArgument> TemplateArgs,
     sema::TemplateDeductionInfo &DeductionInfo, SourceRange InstantiationRange)
     : InstantiatingTemplate(
           SemaRef,
@@ -686,7 +686,7 @@ Sema::InstantiatingTemplate::InstantiatingTemplate(
 
 Sema::InstantiatingTemplate::InstantiatingTemplate(
     Sema &SemaRef, SourceLocation PointOfInstantiation, ParmVarDecl *Param,
-    ArrayRef<TemplateArgument> TemplateArgs, SourceRange InstantiationRange)
+    MutableArrayRef<TemplateArgument> TemplateArgs, SourceRange InstantiationRange)
     : InstantiatingTemplate(
           SemaRef,
           CodeSynthesisContext::DefaultFunctionArgumentInstantiation,
@@ -695,7 +695,7 @@ Sema::InstantiatingTemplate::InstantiatingTemplate(
 
 Sema::InstantiatingTemplate::InstantiatingTemplate(
     Sema &SemaRef, SourceLocation PointOfInstantiation, NamedDecl *Template,
-    NonTypeTemplateParmDecl *Param, ArrayRef<TemplateArgument> TemplateArgs,
+    NonTypeTemplateParmDecl *Param, MutableArrayRef<TemplateArgument> TemplateArgs,
     SourceRange InstantiationRange)
     : InstantiatingTemplate(
           SemaRef,
@@ -705,7 +705,7 @@ Sema::InstantiatingTemplate::InstantiatingTemplate(
 
 Sema::InstantiatingTemplate::InstantiatingTemplate(
     Sema &SemaRef, SourceLocation PointOfInstantiation, NamedDecl *Template,
-    TemplateTemplateParmDecl *Param, ArrayRef<TemplateArgument> TemplateArgs,
+    TemplateTemplateParmDecl *Param, MutableArrayRef<TemplateArgument> TemplateArgs,
     SourceRange InstantiationRange)
     : InstantiatingTemplate(
           SemaRef,
@@ -715,7 +715,7 @@ Sema::InstantiatingTemplate::InstantiatingTemplate(
 
 Sema::InstantiatingTemplate::InstantiatingTemplate(
     Sema &SemaRef, SourceLocation PointOfInstantiation,
-    TypeAliasTemplateDecl *Entity, ArrayRef<TemplateArgument> TemplateArgs,
+    TypeAliasTemplateDecl *Entity, MutableArrayRef<TemplateArgument> TemplateArgs,
     SourceRange InstantiationRange)
     : InstantiatingTemplate(
           SemaRef, CodeSynthesisContext::TypeAliasTemplateInstantiation,
@@ -724,7 +724,7 @@ Sema::InstantiatingTemplate::InstantiatingTemplate(
 
 Sema::InstantiatingTemplate::InstantiatingTemplate(
     Sema &SemaRef, SourceLocation PointOfInstantiation, TemplateDecl *Template,
-    NamedDecl *Param, ArrayRef<TemplateArgument> TemplateArgs,
+    NamedDecl *Param, MutableArrayRef<TemplateArgument> TemplateArgs,
     SourceRange InstantiationRange)
     : InstantiatingTemplate(
           SemaRef, CodeSynthesisContext::DefaultTemplateArgumentChecking,
@@ -762,7 +762,7 @@ Sema::InstantiatingTemplate::InstantiatingTemplate(
 Sema::InstantiatingTemplate::InstantiatingTemplate(
     Sema &SemaRef, SourceLocation PointOfInstantiation,
     ConstraintsCheck, NamedDecl *Template,
-    ArrayRef<TemplateArgument> TemplateArgs, SourceRange InstantiationRange)
+    MutableArrayRef<TemplateArgument> TemplateArgs, SourceRange InstantiationRange)
     : InstantiatingTemplate(
           SemaRef, CodeSynthesisContext::ConstraintsCheck,
           PointOfInstantiation, InstantiationRange, Template, nullptr,
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 47ba9f2a07e69c..7234b50187b784 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -4906,7 +4906,7 @@ FunctionDecl *Sema::InstantiateFunctionDeclaration(
   FunctionDecl *FD = FTD->getTemplatedDecl();
 
   sema::TemplateDeductionInfo Info(Loc);
-  InstantiatingTemplate Inst(*this, Loc, FTD, Args->asArray(), CSC, Info);
+  InstantiatingTemplate Inst(*this, Loc, FTD, Args->asMutableArray(), CSC, Info);
   if (Inst.isInvalid())
     return nullptr;
 

>From 838f2fb86069d335a1a6c082d2e2953e1e8f48cc Mon Sep 17 00:00:00 2001
From: Vlad Serebrennikov <serebrennikov.vladislav at gmail.com>
Date: Sat, 17 Aug 2024 18:09:48 +0300
Subject: [PATCH 05/14] Step 5

---
 clang/include/clang/AST/Type.h             | 4 ++++
 clang/lib/AST/Type.cpp                     | 4 ++++
 clang/lib/Sema/SemaTemplateInstantiate.cpp | 2 +-
 3 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index bacbdabf0e0242..6f2bdeebc81315 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -2813,6 +2813,9 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase {
   /// There are some specializations of this member template listed
   /// immediately following this class.
   template <typename T> const T *getAs() const;
+  template <typename T> T *getAs() {
+    return const_cast<T *>(const_cast<const Type *>(this)->getAs<T>());
+  }
 
   /// Member-template getAsAdjusted<specific type>. Look through specific kinds
   /// of sugar (parens, attributes, etc) for an instance of \<specific type>.
@@ -2993,6 +2996,7 @@ template <> const UsingType *Type::getAs() const;
 /// existing sugar until it reaches a TemplateSpecializationType or a
 /// non-sugared type.
 template <> const TemplateSpecializationType *Type::getAs() const;
+template <> TemplateSpecializationType *Type::getAs();
 
 /// This will check for an AttributedType by removing any existing sugar
 /// until it reaches an AttributedType or a non-sugared type.
diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index e89ce2e4b38445..6d0a283b05a0bc 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -587,6 +587,10 @@ template <> const TemplateSpecializationType *Type::getAs() const {
   return getAsSugar<TemplateSpecializationType>(this);
 }
 
+template <> TemplateSpecializationType *Type::getAs() {
+  return const_cast<TemplateSpecializationType *>(getAsSugar<TemplateSpecializationType>(this));
+}
+
 template <> const AttributedType *Type::getAs() const {
   return getAsSugar<AttributedType>(this);
 }
diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index 61c4891f4abcf1..73b33a6500e70f 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -341,7 +341,7 @@ Response HandleFunctionTemplateDecl(FunctionTemplateDecl *FTD,
 
     while (Type *Ty = NNS ? NNS->getAsType() : nullptr) {
       if (NNS->isInstantiationDependent()) {
-        if (auto *TSTy = const_cast<TemplateSpecializationType *>(Ty->getAs<TemplateSpecializationType>())) {
+        if (auto *TSTy = Ty->getAs<TemplateSpecializationType>()) {
           MutableArrayRef<TemplateArgument> Arguments = TSTy->template_arguments();
           // Prefer template arguments from the injected-class-type if possible.
           // For example,

>From b3d2126bb986ab47c7603adbceda20deea95c7a8 Mon Sep 17 00:00:00 2001
From: Vlad Serebrennikov <serebrennikov.vladislav at gmail.com>
Date: Sat, 17 Aug 2024 18:54:47 +0300
Subject: [PATCH 06/14] Step 6

---
 clang/include/clang/Sema/Sema.h            | 4 ++--
 clang/lib/Sema/SemaConcept.cpp             | 4 ++--
 clang/lib/Sema/SemaTemplateInstantiate.cpp | 6 +++---
 3 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 8a3d6a406bc1a9..a6e79d22759ad0 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -13075,7 +13075,7 @@ class Sema final : public SemaBase {
   /// encountering a lambda generic call operator, and continue looking for
   /// arguments on an enclosing class template.
   MultiLevelTemplateArgumentList getTemplateInstantiationArgs(
-      const NamedDecl *D, const DeclContext *DC = nullptr, bool Final = false,
+      NamedDecl *D, const DeclContext *DC = nullptr, bool Final = false,
       std::optional<MutableArrayRef<TemplateArgument>> Innermost = std::nullopt,
       bool RelativeToPrimary = false, const FunctionDecl *Pattern = nullptr,
       bool ForConstraintInstantiation = false,
@@ -14439,7 +14439,7 @@ class Sema final : public SemaBase {
 
   // Calculates whether the friend function depends on an enclosing template for
   // the purposes of [temp.friend] p9.
-  bool FriendConstraintsDependOnEnclosingTemplate(const FunctionDecl *FD);
+  bool FriendConstraintsDependOnEnclosingTemplate(FunctionDecl *FD);
 
   /// \brief Ensure that the given template arguments satisfy the constraints
   /// associated with the given template, emitting a diagnostic if they do not.
diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp
index 48319354ca2b9f..f53ee433ab0b5b 100644
--- a/clang/lib/Sema/SemaConcept.cpp
+++ b/clang/lib/Sema/SemaConcept.cpp
@@ -910,7 +910,7 @@ bool Sema::CheckFunctionConstraints(const FunctionDecl *FD,
 // the purpose of seeing if they differ by constraints. This isn't the same as
 // getTemplateDepth, because it includes already instantiated parents.
 static unsigned
-CalculateTemplateDepthForConstraints(Sema &S, const NamedDecl *ND,
+CalculateTemplateDepthForConstraints(Sema &S, NamedDecl *ND,
                                      bool SkipForSpecialization = false) {
   MultiLevelTemplateArgumentList MLTAL = S.getTemplateInstantiationArgs(
       ND, ND->getLexicalDeclContext(), /*Final=*/false,
@@ -1031,7 +1031,7 @@ bool Sema::AreConstraintExpressionsEqual(const NamedDecl *Old,
   return ID1 == ID2;
 }
 
-bool Sema::FriendConstraintsDependOnEnclosingTemplate(const FunctionDecl *FD) {
+bool Sema::FriendConstraintsDependOnEnclosingTemplate(FunctionDecl *FD) {
   assert(FD->getFriendObjectKind() && "Must be a friend!");
 
   // The logic for non-templates is handled in ASTContext::isSameEntity, so we
diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index 73b33a6500e70f..b86f29ab08ccff 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -463,7 +463,7 @@ Response HandleGenericDeclContext(const Decl *CurDecl) {
 } // namespace
 
 MultiLevelTemplateArgumentList Sema::getTemplateInstantiationArgs(
-    const NamedDecl *ND, const DeclContext *DC, bool Final,
+    NamedDecl *ND, const DeclContext *DC, bool Final,
     std::optional<MutableArrayRef<TemplateArgument>> Innermost, bool RelativeToPrimary,
     const FunctionDecl *Pattern, bool ForConstraintInstantiation,
     bool SkipForSpecialization) {
@@ -472,13 +472,13 @@ MultiLevelTemplateArgumentList Sema::getTemplateInstantiationArgs(
   MultiLevelTemplateArgumentList Result;
 
   using namespace TemplateInstArgsHelpers;
-  Decl *CurDecl = const_cast<NamedDecl *>(ND);
+  Decl *CurDecl = ND;
 
   if (!CurDecl)
     CurDecl = Decl::castFromDeclContext(DC);
 
   if (Innermost) {
-    Result.addOuterTemplateArguments(const_cast<NamedDecl *>(ND), *Innermost, Final);
+    Result.addOuterTemplateArguments(ND, *Innermost, Final);
     // Populate placeholder template arguments for TemplateTemplateParmDecls.
     // This is essential for the case e.g.
     //

>From 4445cf2b9da181b17aaf1faf4e19fe88e39b149a Mon Sep 17 00:00:00 2001
From: Vlad Serebrennikov <serebrennikov.vladislav at gmail.com>
Date: Sat, 17 Aug 2024 20:02:47 +0300
Subject: [PATCH 07/14] Step 7

---
 clang/include/clang/Sema/Sema.h | 13 ++++++++-----
 clang/lib/Sema/SemaConcept.cpp  |  4 ++--
 clang/lib/Sema/SemaTemplate.cpp |  4 ++--
 3 files changed, 12 insertions(+), 9 deletions(-)

diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index a6e79d22759ad0..964d400ca9749d 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -11837,13 +11837,13 @@ class Sema final : public SemaBase {
   // the named decl, or the important information we need about it in order to
   // do constraint comparisons.
   class TemplateCompareNewDeclInfo {
-    const NamedDecl *ND = nullptr;
+    NamedDecl *ND = nullptr;
     const DeclContext *DC = nullptr;
     const DeclContext *LexicalDC = nullptr;
     SourceLocation Loc;
 
   public:
-    TemplateCompareNewDeclInfo(const NamedDecl *ND) : ND(ND) {}
+    TemplateCompareNewDeclInfo(NamedDecl *ND) : ND(ND) {}
     TemplateCompareNewDeclInfo(const DeclContext *DeclCtx,
                                const DeclContext *LexicalDeclCtx,
                                SourceLocation Loc)
@@ -11858,7 +11858,10 @@ class Sema final : public SemaBase {
     // for constraint comparison, so make sure we can check that.
     bool isInvalid() const { return !ND && !DC; }
 
-    const NamedDecl *getDecl() const { return ND; }
+    NamedDecl *getDecl() { return ND; }
+    const NamedDecl *getDecl() const { 
+      return const_cast<TemplateCompareNewDeclInfo *>(this)->getDecl();
+    }
 
     bool ContainsDecl(const NamedDecl *ND) const { return this->ND == ND; }
 
@@ -11898,7 +11901,7 @@ class Sema final : public SemaBase {
   /// otherwise.
   bool TemplateParameterListsAreEqual(
       const TemplateCompareNewDeclInfo &NewInstFrom, TemplateParameterList *New,
-      const NamedDecl *OldInstFrom, TemplateParameterList *Old, bool Complain,
+      NamedDecl *OldInstFrom, TemplateParameterList *Old, bool Complain,
       TemplateParameterListEqualKind Kind,
       SourceLocation TemplateArgLoc = SourceLocation());
 
@@ -14432,7 +14435,7 @@ class Sema final : public SemaBase {
   // for figuring out the relative 'depth' of the constraint. The depth of the
   // 'primary template' and the 'instantiated from' templates aren't necessarily
   // the same, such as a case when one is a 'friend' defined in a class.
-  bool AreConstraintExpressionsEqual(const NamedDecl *Old,
+  bool AreConstraintExpressionsEqual(NamedDecl *Old,
                                      const Expr *OldConstr,
                                      const TemplateCompareNewDeclInfo &New,
                                      const Expr *NewConstr);
diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp
index f53ee433ab0b5b..9ccda9e4528e28 100644
--- a/clang/lib/Sema/SemaConcept.cpp
+++ b/clang/lib/Sema/SemaConcept.cpp
@@ -950,7 +950,7 @@ namespace {
 } // namespace
 
 static const Expr *SubstituteConstraintExpressionWithoutSatisfaction(
-    Sema &S, const Sema::TemplateCompareNewDeclInfo &DeclInfo,
+    Sema &S, Sema::TemplateCompareNewDeclInfo DeclInfo,
     const Expr *ConstrExpr) {
   MultiLevelTemplateArgumentList MLTAL = S.getTemplateInstantiationArgs(
       DeclInfo.getDecl(), DeclInfo.getLexicalDeclContext(), /*Final=*/false,
@@ -1002,7 +1002,7 @@ static const Expr *SubstituteConstraintExpressionWithoutSatisfaction(
   return SubstConstr.get();
 }
 
-bool Sema::AreConstraintExpressionsEqual(const NamedDecl *Old,
+bool Sema::AreConstraintExpressionsEqual(NamedDecl *Old,
                                          const Expr *OldConstr,
                                          const TemplateCompareNewDeclInfo &New,
                                          const Expr *NewConstr) {
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 9005fbcea6536f..467f2b92fcacb7 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -7514,7 +7514,7 @@ Sema::BuildExpressionFromNonTypeTemplateArgument(const TemplateArgument &Arg,
 static bool MatchTemplateParameterKind(
     Sema &S, NamedDecl *New,
     const Sema::TemplateCompareNewDeclInfo &NewInstFrom, NamedDecl *Old,
-    const NamedDecl *OldInstFrom, bool Complain,
+    NamedDecl *OldInstFrom, bool Complain,
     Sema::TemplateParameterListEqualKind Kind, SourceLocation TemplateArgLoc) {
   // Check the actual kind (type, non-type, template).
   if (Old->getKind() != New->getKind()) {
@@ -7684,7 +7684,7 @@ void DiagnoseTemplateParameterListArityMismatch(Sema &S,
 
 bool Sema::TemplateParameterListsAreEqual(
     const TemplateCompareNewDeclInfo &NewInstFrom, TemplateParameterList *New,
-    const NamedDecl *OldInstFrom, TemplateParameterList *Old, bool Complain,
+    NamedDecl *OldInstFrom, TemplateParameterList *Old, bool Complain,
     TemplateParameterListEqualKind Kind, SourceLocation TemplateArgLoc) {
   if (Old->size() != New->size() && Kind != TPL_TemplateTemplateArgumentMatch) {
     if (Complain)

>From e0933e7a14652810c12d9929cb837684bd5124f9 Mon Sep 17 00:00:00 2001
From: Vlad Serebrennikov <serebrennikov.vladislav at gmail.com>
Date: Sat, 17 Aug 2024 20:51:08 +0300
Subject: [PATCH 08/14] Step 8

---
 clang/include/clang/AST/Decl.h           |  2 +-
 clang/include/clang/AST/DeclTemplate.h   |  8 ++---
 clang/include/clang/Sema/Sema.h          | 12 +++----
 clang/include/clang/Sema/SemaConcept.h   | 10 +++---
 clang/lib/AST/DeclTemplate.cpp           |  8 ++---
 clang/lib/Sema/SemaCodeComplete.cpp      | 10 +++---
 clang/lib/Sema/SemaConcept.cpp           | 44 ++++++++++++++----------
 clang/lib/Sema/SemaDecl.cpp              |  4 +--
 clang/lib/Sema/SemaOverload.cpp          |  4 +--
 clang/lib/Sema/SemaTemplate.cpp          |  4 +--
 clang/lib/Sema/SemaTemplateDeduction.cpp |  8 ++---
 11 files changed, 60 insertions(+), 54 deletions(-)

diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h
index f79d62f225d9ec..7bff07aeb44947 100644
--- a/clang/include/clang/AST/Decl.h
+++ b/clang/include/clang/AST/Decl.h
@@ -2621,7 +2621,7 @@ class FunctionDecl : public DeclaratorDecl,
   ///
   /// Use this instead of getTrailingRequiresClause for concepts APIs that
   /// accept an ArrayRef of constraint expressions.
-  void getAssociatedConstraints(SmallVectorImpl<const Expr *> &AC) const {
+  void getAssociatedConstraints(SmallVectorImpl<Expr *> &AC) {
     if (auto *TRC = getTrailingRequiresClause())
       AC.push_back(TRC);
   }
diff --git a/clang/include/clang/AST/DeclTemplate.h b/clang/include/clang/AST/DeclTemplate.h
index adf3ec56b9bac8..2ec49427e30bed 100644
--- a/clang/include/clang/AST/DeclTemplate.h
+++ b/clang/include/clang/AST/DeclTemplate.h
@@ -192,7 +192,7 @@ class TemplateParameterList final
   ///
   /// The constraints in the resulting list are to be treated as if in a
   /// conjunction ("and").
-  void getAssociatedConstraints(llvm::SmallVectorImpl<const Expr *> &AC) const;
+  void getAssociatedConstraints(llvm::SmallVectorImpl<Expr *> &AC);
 
   bool hasAssociatedConstraints() const;
 
@@ -428,7 +428,7 @@ class TemplateDecl : public NamedDecl {
   /// including constraint-expressions derived from the requires-clause,
   /// trailing requires-clause (for functions and methods) and constrained
   /// template parameters.
-  void getAssociatedConstraints(llvm::SmallVectorImpl<const Expr *> &AC) const;
+  void getAssociatedConstraints(llvm::SmallVectorImpl<Expr *> &AC);
 
   bool hasAssociatedConstraints() const;
 
@@ -2143,7 +2143,7 @@ class ClassTemplatePartialSpecializationDecl
   ///
   /// The constraints in the resulting list are to be treated as if in a
   /// conjunction ("and").
-  void getAssociatedConstraints(llvm::SmallVectorImpl<const Expr *> &AC) const {
+  void getAssociatedConstraints(llvm::SmallVectorImpl<Expr *> &AC) {
     TemplateParams->getAssociatedConstraints(AC);
   }
 
@@ -2915,7 +2915,7 @@ class VarTemplatePartialSpecializationDecl
   ///
   /// The constraints in the resulting list are to be treated as if in a
   /// conjunction ("and").
-  void getAssociatedConstraints(llvm::SmallVectorImpl<const Expr *> &AC) const {
+  void getAssociatedConstraints(llvm::SmallVectorImpl<Expr *> &AC) {
     TemplateParams->getAssociatedConstraints(AC);
   }
 
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 964d400ca9749d..4ce3f766e41d37 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -14352,7 +14352,7 @@ class Sema final : public SemaBase {
   /// A diagnostic is emitted if it is not, false is returned, and
   /// PossibleNonPrimary will be set to true if the failure might be due to a
   /// non-primary expression being used as an atomic constraint.
-  bool CheckConstraintExpression(const Expr *CE, Token NextToken = Token(),
+  bool CheckConstraintExpression(Expr *CE, Token NextToken = Token(),
                                  bool *PossibleNonPrimary = nullptr,
                                  bool IsTrailingRequiresClause = false);
 
@@ -14481,7 +14481,7 @@ class Sema final : public SemaBase {
                                 bool First = true);
 
   const NormalizedConstraint *getNormalizedAssociatedConstraints(
-      NamedDecl *ConstrainedDecl, ArrayRef<const Expr *> AssociatedConstraints);
+      NamedDecl *ConstrainedDecl, ArrayRef<Expr *> AssociatedConstraints);
 
   /// \brief Check whether the given declaration's associated constraints are
   /// at least as constrained than another declaration's according to the
@@ -14491,8 +14491,8 @@ class Sema final : public SemaBase {
   /// at least constrained than D2, and false otherwise.
   ///
   /// \returns true if an error occurred, false otherwise.
-  bool IsAtLeastAsConstrained(NamedDecl *D1, MutableArrayRef<const Expr *> AC1,
-                              NamedDecl *D2, MutableArrayRef<const Expr *> AC2,
+  bool IsAtLeastAsConstrained(NamedDecl *D1, MutableArrayRef<Expr *> AC1,
+                              NamedDecl *D2, MutableArrayRef<Expr *> AC2,
                               bool &Result);
 
   /// If D1 was not at least as constrained as D2, but would've been if a pair
@@ -14500,8 +14500,8 @@ class Sema final : public SemaBase {
   /// repeated in two separate places in code.
   /// \returns true if such a diagnostic was emitted, false otherwise.
   bool MaybeEmitAmbiguousAtomicConstraintsDiagnostic(
-      NamedDecl *D1, ArrayRef<const Expr *> AC1, NamedDecl *D2,
-      ArrayRef<const Expr *> AC2);
+      NamedDecl *D1, ArrayRef<Expr *> AC1, NamedDecl *D2,
+      ArrayRef<Expr *> AC2);
 
 private:
   /// Caches pairs of template-like decls whose associated constraints were
diff --git a/clang/include/clang/Sema/SemaConcept.h b/clang/include/clang/Sema/SemaConcept.h
index 4b1abccb7741a1..1079be3236e7e2 100644
--- a/clang/include/clang/Sema/SemaConcept.h
+++ b/clang/include/clang/Sema/SemaConcept.h
@@ -163,9 +163,9 @@ struct NormalizedConstraint {
 
 private:
   static std::optional<NormalizedConstraint>
-  fromConstraintExprs(Sema &S, NamedDecl *D, ArrayRef<const Expr *> E);
+  fromConstraintExprs(Sema &S, NamedDecl *D, ArrayRef<Expr *> E);
   static std::optional<NormalizedConstraint>
-  fromConstraintExpr(Sema &S, NamedDecl *D, const Expr *E);
+  fromConstraintExpr(Sema &S, NamedDecl *D, Expr *E);
 };
 
 struct alignas(ConstraintAlignment) NormalizedConstraintPair {
@@ -191,7 +191,7 @@ struct alignas(ConstraintAlignment) FoldExpandedConstraint {
 
 const NormalizedConstraint *getNormalizedAssociatedConstraints(
     Sema &S, NamedDecl *ConstrainedDecl,
-    ArrayRef<const Expr *> AssociatedConstraints);
+    ArrayRef<Expr *> AssociatedConstraints);
 
 template <typename AtomicSubsumptionEvaluator>
 bool subsumes(const NormalForm &PDNF, const NormalForm &QCNF,
@@ -237,8 +237,8 @@ bool subsumes(const NormalForm &PDNF, const NormalForm &QCNF,
 }
 
 template <typename AtomicSubsumptionEvaluator>
-bool subsumes(Sema &S, NamedDecl *DP, ArrayRef<const Expr *> P, NamedDecl *DQ,
-              ArrayRef<const Expr *> Q, bool &Subsumes,
+bool subsumes(Sema &S, NamedDecl *DP, ArrayRef<Expr *> P, NamedDecl *DQ,
+              ArrayRef<Expr *> Q, bool &Subsumes,
               const AtomicSubsumptionEvaluator &E) {
   // C++ [temp.constr.order] p2
   //   In order to determine if a constraint P subsumes a constraint Q, P is
diff --git a/clang/lib/AST/DeclTemplate.cpp b/clang/lib/AST/DeclTemplate.cpp
index 2a9f9d6e71645e..67afe600d1ef70 100644
--- a/clang/lib/AST/DeclTemplate.cpp
+++ b/clang/lib/AST/DeclTemplate.cpp
@@ -225,14 +225,14 @@ static bool AdoptTemplateParameterList(TemplateParameterList *Params,
 }
 
 void TemplateParameterList::
-getAssociatedConstraints(llvm::SmallVectorImpl<const Expr *> &AC) const {
+getAssociatedConstraints(llvm::SmallVectorImpl<Expr *> &AC) {
   if (HasConstrainedParameters)
     for (const NamedDecl *Param : *this) {
       if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) {
         if (const auto *TC = TTP->getTypeConstraint())
           AC.push_back(TC->getImmediatelyDeclaredConstraint());
       } else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
-        if (const Expr *E = NTTP->getPlaceholderTypeConstraint())
+        if (Expr *E = NTTP->getPlaceholderTypeConstraint())
           AC.push_back(E);
       }
     }
@@ -277,10 +277,10 @@ TemplateDecl::TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
 void TemplateDecl::anchor() {}
 
 void TemplateDecl::
-getAssociatedConstraints(llvm::SmallVectorImpl<const Expr *> &AC) const {
+getAssociatedConstraints(llvm::SmallVectorImpl<Expr *> &AC) {
   TemplateParams->getAssociatedConstraints(AC);
   if (auto *FD = dyn_cast_or_null<FunctionDecl>(getTemplatedDecl()))
-    if (const Expr *TRC = FD->getTrailingRequiresClause())
+    if (Expr *TRC = FD->getTrailingRequiresClause())
       AC.push_back(TRC);
 }
 
diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp
index 88d4732c7d5c6a..c6c4aaec4ffb51 100644
--- a/clang/lib/Sema/SemaCodeComplete.cpp
+++ b/clang/lib/Sema/SemaCodeComplete.cpp
@@ -5569,19 +5569,19 @@ class ConceptInfo {
 
   // Gets all the type constraint expressions that might apply to the type
   // variables associated with DC (as returned by getTemplatedEntity()).
-  static SmallVector<const Expr *, 1>
+  static SmallVector<Expr *, 1>
   constraintsForTemplatedEntity(DeclContext *DC) {
-    SmallVector<const Expr *, 1> Result;
+    SmallVector<Expr *, 1> Result;
     if (DC == nullptr)
       return Result;
     // Primary templates can have constraints.
-    if (const auto *TD = cast<Decl>(DC)->getDescribedTemplate())
+    if (auto *TD = cast<Decl>(DC)->getDescribedTemplate())
       TD->getAssociatedConstraints(Result);
     // Partial specializations may have constraints.
-    if (const auto *CTPSD =
+    if (auto *CTPSD =
             dyn_cast<ClassTemplatePartialSpecializationDecl>(DC))
       CTPSD->getAssociatedConstraints(Result);
-    if (const auto *VTPSD = dyn_cast<VarTemplatePartialSpecializationDecl>(DC))
+    if (auto *VTPSD = dyn_cast<VarTemplatePartialSpecializationDecl>(DC))
       VTPSD->getAssociatedConstraints(Result);
     return Result;
   }
diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp
index 9ccda9e4528e28..cbfc5a6e38dbc6 100644
--- a/clang/lib/Sema/SemaConcept.cpp
+++ b/clang/lib/Sema/SemaConcept.cpp
@@ -38,11 +38,11 @@ namespace {
 class LogicalBinOp {
   SourceLocation Loc;
   OverloadedOperatorKind Op = OO_None;
-  const Expr *LHS = nullptr;
-  const Expr *RHS = nullptr;
+  Expr *LHS = nullptr;
+  Expr *RHS = nullptr;
 
 public:
-  LogicalBinOp(const Expr *E) {
+  LogicalBinOp(Expr *E) {
     if (auto *BO = dyn_cast<BinaryOperator>(E)) {
       Op = BinaryOperator::getOverloadedOperator(BO->getOpcode());
       LHS = BO->getLHS();
@@ -63,8 +63,14 @@ class LogicalBinOp {
   bool isOr() const { return Op == OO_PipePipe; }
   explicit operator bool() const { return isAnd() || isOr(); }
 
-  const Expr *getLHS() const { return LHS; }
-  const Expr *getRHS() const { return RHS; }
+  Expr *getLHS() { return LHS; }
+  const Expr *getLHS() const {
+    return const_cast<LogicalBinOp *>(this)->getLHS();
+  }
+  Expr *getRHS() { return RHS; }
+  const Expr *getRHS() const {
+    return const_cast<LogicalBinOp *>(this)->getRHS();
+  }
   OverloadedOperatorKind getOp() const { return Op; }
 
   ExprResult recreateBinOp(Sema &SemaRef, ExprResult LHS) const {
@@ -89,7 +95,7 @@ class LogicalBinOp {
 };
 }
 
-bool Sema::CheckConstraintExpression(const Expr *ConstraintExpression,
+bool Sema::CheckConstraintExpression(Expr *ConstraintExpression,
                                      Token NextToken, bool *PossibleNonPrimary,
                                      bool IsTrailingRequiresClause) {
   // C++2a [temp.constr.atomic]p1
@@ -180,7 +186,7 @@ struct SatisfactionStackRAII {
 
 template <typename ConstraintEvaluator>
 static ExprResult
-calculateConstraintSatisfaction(Sema &S, const Expr *ConstraintExpr,
+calculateConstraintSatisfaction(Sema &S, Expr *ConstraintExpr,
                                 ConstraintSatisfaction &Satisfaction,
                                 const ConstraintEvaluator &Evaluator);
 
@@ -323,7 +329,7 @@ calculateConstraintSatisfaction(Sema &S, const CXXFoldExpr *FE,
 
 template <typename ConstraintEvaluator>
 static ExprResult
-calculateConstraintSatisfaction(Sema &S, const Expr *ConstraintExpr,
+calculateConstraintSatisfaction(Sema &S, Expr *ConstraintExpr,
                                 ConstraintSatisfaction &Satisfaction,
                                 const ConstraintEvaluator &Evaluator) {
   ConstraintExpr = ConstraintExpr->IgnoreParenImpCasts();
@@ -1040,7 +1046,7 @@ bool Sema::FriendConstraintsDependOnEnclosingTemplate(FunctionDecl *FD) {
   assert(FD->getDescribedFunctionTemplate() &&
          "Non-function templates don't need to be checked");
 
-  SmallVector<const Expr *, 3> ACs;
+  SmallVector<Expr *, 3> ACs;
   FD->getDescribedFunctionTemplate()->getAssociatedConstraints(ACs);
 
   unsigned OldTemplateDepth = CalculateTemplateDepthForConstraints(*this, FD);
@@ -1056,7 +1062,7 @@ bool Sema::EnsureTemplateArgumentListConstraints(
     TemplateDecl *TD, const MultiLevelTemplateArgumentList &TemplateArgsLists,
     SourceRange TemplateIDRange) {
   ConstraintSatisfaction Satisfaction;
-  llvm::SmallVector<const Expr *, 3> AssociatedConstraints;
+  llvm::SmallVector<Expr *, 3> AssociatedConstraints;
   TD->getAssociatedConstraints(AssociatedConstraints);
   if (CheckConstraintSatisfaction(TD, AssociatedConstraints, TemplateArgsLists,
                                   TemplateIDRange, Satisfaction))
@@ -1087,7 +1093,7 @@ bool Sema::CheckInstantiatedFunctionTemplateConstraints(
   FunctionTemplateDecl *Template = Decl->getPrimaryTemplate();
   // Note - code synthesis context for the constraints check is created
   // inside CheckConstraintsSatisfaction.
-  SmallVector<const Expr *, 3> TemplateAC;
+  SmallVector<Expr *, 3> TemplateAC;
   Template->getAssociatedConstraints(TemplateAC);
   if (TemplateAC.empty()) {
     Satisfaction.IsSatisfied = true;
@@ -1380,7 +1386,7 @@ void Sema::DiagnoseUnsatisfiedConstraint(
 
 const NormalizedConstraint *
 Sema::getNormalizedAssociatedConstraints(
-    NamedDecl *ConstrainedDecl, ArrayRef<const Expr *> AssociatedConstraints) {
+    NamedDecl *ConstrainedDecl, ArrayRef<Expr *> AssociatedConstraints) {
   // In case the ConstrainedDecl comes from modules, it is necessary to use
   // the canonical decl to avoid different atomic constraints with the 'same'
   // declarations.
@@ -1405,7 +1411,7 @@ Sema::getNormalizedAssociatedConstraints(
 
 const NormalizedConstraint *clang::getNormalizedAssociatedConstraints(
     Sema &S, NamedDecl *ConstrainedDecl,
-    ArrayRef<const Expr *> AssociatedConstraints) {
+    ArrayRef<Expr *> AssociatedConstraints) {
   return S.getNormalizedAssociatedConstraints(ConstrainedDecl,
                                               AssociatedConstraints);
 }
@@ -1535,7 +1541,7 @@ NormalizedConstraint &NormalizedConstraint::getRHS() const {
 
 std::optional<NormalizedConstraint>
 NormalizedConstraint::fromConstraintExprs(Sema &S, NamedDecl *D,
-                                          ArrayRef<const Expr *> E) {
+                                          ArrayRef<Expr *> E) {
   assert(E.size() != 0);
   auto Conjunction = fromConstraintExpr(S, D, E[0]);
   if (!Conjunction)
@@ -1551,7 +1557,7 @@ NormalizedConstraint::fromConstraintExprs(Sema &S, NamedDecl *D,
 }
 
 std::optional<NormalizedConstraint>
-NormalizedConstraint::fromConstraintExpr(Sema &S, NamedDecl *D, const Expr *E) {
+NormalizedConstraint::fromConstraintExpr(Sema &S, NamedDecl *D, Expr *E) {
   assert(E != nullptr);
 
   // C++ [temp.constr.normal]p1.1
@@ -1575,7 +1581,7 @@ NormalizedConstraint::fromConstraintExpr(Sema &S, NamedDecl *D, const Expr *E) {
 
     return NormalizedConstraint(S.Context, std::move(*LHS), std::move(*RHS),
                                 BO.isAnd() ? CCK_Conjunction : CCK_Disjunction);
-  } else if (auto *CSE = dyn_cast<ConceptSpecializationExpr>(const_cast<Expr *>(E))) {
+  } else if (auto *CSE = dyn_cast<ConceptSpecializationExpr>(E)) {
     const NormalizedConstraint *SubNF;
     {
       Sema::InstantiatingTemplate Inst(
@@ -1735,9 +1741,9 @@ NormalForm clang::makeDNF(const NormalizedConstraint &Normalized) {
 }
 
 bool Sema::IsAtLeastAsConstrained(NamedDecl *D1,
-                                  MutableArrayRef<const Expr *> AC1,
+                                  MutableArrayRef<Expr *> AC1,
                                   NamedDecl *D2,
-                                  MutableArrayRef<const Expr *> AC2,
+                                  MutableArrayRef<Expr *> AC2,
                                   bool &Result) {
   if (const auto *FD1 = dyn_cast<FunctionDecl>(D1)) {
     auto IsExpectedEntity = [](const FunctionDecl *FD) {
@@ -1797,7 +1803,7 @@ bool Sema::IsAtLeastAsConstrained(NamedDecl *D1,
 }
 
 bool Sema::MaybeEmitAmbiguousAtomicConstraintsDiagnostic(NamedDecl *D1,
-    ArrayRef<const Expr *> AC1, NamedDecl *D2, ArrayRef<const Expr *> AC2) {
+    ArrayRef<Expr *> AC1, NamedDecl *D2, ArrayRef<Expr *> AC2) {
   if (isSFINAEContext())
     // No need to work here because our notes would be discarded.
     return false;
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 9c15b5fa571a39..527bdaf9dfe834 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -18770,7 +18770,7 @@ static void SetEligibleMethods(Sema &S, CXXRecordDecl *Record,
     if (FunctionDecl *MF = OrigMethod->getInstantiatedFromMemberFunction())
       OrigMethod = cast<CXXMethodDecl>(MF);
 
-    const Expr *Constraints = OrigMethod->getTrailingRequiresClause();
+    Expr *Constraints = OrigMethod->getTrailingRequiresClause();
     bool AnotherMethodIsMoreConstrained = false;
     for (size_t j = 0; j < Methods.size(); j++) {
       if (i == j || !SatisfactionStatus[j])
@@ -18783,7 +18783,7 @@ static void SetEligibleMethods(Sema &S, CXXRecordDecl *Record,
                                              CSM))
         continue;
 
-      const Expr *OtherConstraints = OtherMethod->getTrailingRequiresClause();
+      Expr *OtherConstraints = OtherMethod->getTrailingRequiresClause();
       if (!OtherConstraints)
         continue;
       if (!Constraints) {
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 52f640eb96b73b..e45abdc45045bb 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -11088,12 +11088,12 @@ MaybeDiagnoseAmbiguousConstraints(Sema &S, ArrayRef<OverloadCandidate> Cands) {
   // source-level construct. This behavior is quite confusing and we should try
   // to help the user figure out what happened.
 
-  SmallVector<const Expr *, 3> FirstAC, SecondAC;
+  SmallVector<Expr *, 3> FirstAC, SecondAC;
   FunctionDecl *FirstCand = nullptr, *SecondCand = nullptr;
   for (auto I = Cands.begin(), E = Cands.end(); I != E; ++I) {
     if (!I->Function)
       continue;
-    SmallVector<const Expr *, 3> AC;
+    SmallVector<Expr *, 3> AC;
     if (auto *Template = I->Function->getPrimaryTemplate())
       Template->getAssociatedConstraints(AC);
     else
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 467f2b92fcacb7..9f3dffc031b7e2 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -3864,7 +3864,7 @@ static void checkMoreSpecializedThanPrimary(Sema &S, PartialSpecDecl *Partial) {
   }
 
   S.NoteTemplateLocation(*Template);
-  SmallVector<const Expr *, 3> PartialAC, TemplateAC;
+  SmallVector<Expr *, 3> PartialAC, TemplateAC;
   Template->getAssociatedConstraints(TemplateAC);
   Partial->getAssociatedConstraints(PartialAC);
   S.MaybeEmitAmbiguousAtomicConstraintsDiagnostic(Partial, PartialAC, Template,
@@ -7167,7 +7167,7 @@ bool Sema::CheckTemplateTemplateArgument(TemplateTemplateParmDecl *Param,
       // C++20[temp.func.order]p2
       //   [...] If both deductions succeed, the partial ordering selects the
       // more constrained template (if one exists) as determined below.
-      SmallVector<const Expr *, 3> ParamsAC, TemplateAC;
+      SmallVector<Expr *, 3> ParamsAC, TemplateAC;
       Params->getAssociatedConstraints(ParamsAC);
       // C++2a[temp.arg.template]p3
       //   [...] In this comparison, if P is unconstrained, the constraints on A
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp
index e7cacedb079793..7ac62d3e67717a 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -3072,7 +3072,7 @@ CheckDeducedArgumentConstraints(Sema &S, TemplateDeclT *Template,
                                 ArrayRef<TemplateArgument> SugaredDeducedArgs,
                                 MutableArrayRef<TemplateArgument> CanonicalDeducedArgs,
                                 TemplateDeductionInfo &Info) {
-  llvm::SmallVector<const Expr *, 3> AssociatedConstraints;
+  llvm::SmallVector<Expr *, 3> AssociatedConstraints;
   Template->getAssociatedConstraints(AssociatedConstraints);
 
   std::optional<MutableArrayRef<TemplateArgument>> Innermost;
@@ -5717,7 +5717,7 @@ FunctionTemplateDecl *Sema::getMoreSpecializedTemplate(
       !Context.hasSameType(FD1->getReturnType(), FD2->getReturnType()))
     return nullptr;
 
-  llvm::SmallVector<const Expr *, 3> AC1, AC2;
+  llvm::SmallVector<Expr *, 3> AC1, AC2;
   FT1->getAssociatedConstraints(AC1);
   FT2->getAssociatedConstraints(AC2);
   bool AtLeastAsConstrained1, AtLeastAsConstrained2;
@@ -5822,7 +5822,7 @@ FunctionDecl *Sema::getMoreConstrainedFunction(FunctionDecl *FD1,
   if (FunctionDecl *P = FD2->getTemplateInstantiationPattern(false))
     F2 = P;
 
-  llvm::SmallVector<const Expr *, 1> AC1, AC2;
+  llvm::SmallVector<Expr *, 1> AC1, AC2;
   F1->getAssociatedConstraints(AC1);
   F2->getAssociatedConstraints(AC2);
   bool AtLeastAsConstrained1, AtLeastAsConstrained2;
@@ -6057,7 +6057,7 @@ getMoreSpecialized(Sema &S, QualType T1, QualType T2, TemplateLikeDecl *P1,
   if (!TemplateArgumentListAreEqual(S.getASTContext())(P1, P2))
     return nullptr;
 
-  llvm::SmallVector<const Expr *, 3> AC1, AC2;
+  llvm::SmallVector<Expr *, 3> AC1, AC2;
   P1->getAssociatedConstraints(AC1);
   P2->getAssociatedConstraints(AC2);
   bool AtLeastAsConstrained1, AtLeastAsConstrained2;

>From 849d51fe51e712616f2456203898b6abb573f5a3 Mon Sep 17 00:00:00 2001
From: Vlad Serebrennikov <serebrennikov.vladislav at gmail.com>
Date: Sat, 17 Aug 2024 21:05:03 +0300
Subject: [PATCH 09/14] Step 9

---
 clang/include/clang/Sema/Sema.h |  8 ++++----
 clang/lib/Sema/SemaConcept.cpp  | 16 ++++++++--------
 clang/lib/Sema/SemaOverload.cpp |  2 +-
 3 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 4ce3f766e41d37..4747cfbb77a538 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -14372,7 +14372,7 @@ class Sema final : public SemaBase {
   /// \returns true if an error occurred and satisfaction could not be checked,
   /// false otherwise.
   bool CheckConstraintSatisfaction(
-      const NamedDecl *Template, ArrayRef<const Expr *> ConstraintExprs,
+      const NamedDecl *Template, ArrayRef<Expr *> ConstraintExprs,
       const MultiLevelTemplateArgumentList &TemplateArgLists,
       SourceRange TemplateIDRange, ConstraintSatisfaction &Satisfaction) {
     llvm::SmallVector<Expr *, 4> Converted;
@@ -14404,7 +14404,7 @@ class Sema final : public SemaBase {
   /// \returns true if an error occurred and satisfaction could not be checked,
   /// false otherwise.
   bool CheckConstraintSatisfaction(
-      const NamedDecl *Template, ArrayRef<const Expr *> ConstraintExprs,
+      const NamedDecl *Template, ArrayRef<Expr *> ConstraintExprs,
       llvm::SmallVectorImpl<Expr *> &ConvertedConstraints,
       const MultiLevelTemplateArgumentList &TemplateArgList,
       SourceRange TemplateIDRange, ConstraintSatisfaction &Satisfaction);
@@ -14415,7 +14415,7 @@ class Sema final : public SemaBase {
   /// occurred and satisfaction could not be determined.
   ///
   /// \returns true if an error occurred, false otherwise.
-  bool CheckConstraintSatisfaction(const Expr *ConstraintExpr,
+  bool CheckConstraintSatisfaction(Expr *ConstraintExpr,
                                    ConstraintSatisfaction &Satisfaction);
 
   /// Check whether the given function decl's trailing requires clause is
@@ -14424,7 +14424,7 @@ class Sema final : public SemaBase {
   /// an error occurred and satisfaction could not be determined.
   ///
   /// \returns true if an error occurred, false otherwise.
-  bool CheckFunctionConstraints(const FunctionDecl *FD,
+  bool CheckFunctionConstraints(FunctionDecl *FD,
                                 ConstraintSatisfaction &Satisfaction,
                                 SourceLocation UsageLoc = SourceLocation(),
                                 bool ForOverloadResolution = false);
diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp
index cbfc5a6e38dbc6..19d934b9dd16a4 100644
--- a/clang/lib/Sema/SemaConcept.cpp
+++ b/clang/lib/Sema/SemaConcept.cpp
@@ -192,8 +192,8 @@ calculateConstraintSatisfaction(Sema &S, Expr *ConstraintExpr,
 
 template <typename ConstraintEvaluator>
 static ExprResult
-calculateConstraintSatisfaction(Sema &S, const Expr *LHS,
-                                OverloadedOperatorKind Op, const Expr *RHS,
+calculateConstraintSatisfaction(Sema &S, Expr *LHS,
+                                OverloadedOperatorKind Op, Expr *RHS,
                                 ConstraintSatisfaction &Satisfaction,
                                 const ConstraintEvaluator &Evaluator) {
   size_t EffectiveDetailEndIndex = Satisfaction.Details.size();
@@ -439,7 +439,7 @@ DiagRecursiveConstraintEval(Sema &S, llvm::FoldingSetNodeID &ID,
 
 static ExprResult calculateConstraintSatisfaction(
     Sema &S, const NamedDecl *Template, SourceLocation TemplateNameLoc,
-    const MultiLevelTemplateArgumentList &MLTAL, const Expr *ConstraintExpr,
+    const MultiLevelTemplateArgumentList &MLTAL, Expr *ConstraintExpr,
     ConstraintSatisfaction &Satisfaction) {
 
   struct ConstraintEvaluator {
@@ -574,7 +574,7 @@ static ExprResult calculateConstraintSatisfaction(
 }
 
 static bool CheckConstraintSatisfaction(
-    Sema &S, const NamedDecl *Template, ArrayRef<const Expr *> ConstraintExprs,
+    Sema &S, const NamedDecl *Template, ArrayRef<Expr *> ConstraintExprs,
     llvm::SmallVectorImpl<Expr *> &Converted,
     const MultiLevelTemplateArgumentList &TemplateArgsLists,
     SourceRange TemplateIDRange, ConstraintSatisfaction &Satisfaction) {
@@ -599,7 +599,7 @@ static bool CheckConstraintSatisfaction(
   if (Inst.isInvalid())
     return true;
 
-  for (const Expr *ConstraintExpr : ConstraintExprs) {
+  for (Expr *ConstraintExpr : ConstraintExprs) {
     ExprResult Res = calculateConstraintSatisfaction(
         S, Template, TemplateIDRange.getBegin(), TemplateArgsLists,
         ConstraintExpr, Satisfaction);
@@ -622,7 +622,7 @@ static bool CheckConstraintSatisfaction(
 }
 
 bool Sema::CheckConstraintSatisfaction(
-    const NamedDecl *Template, ArrayRef<const Expr *> ConstraintExprs,
+    const NamedDecl *Template, ArrayRef<Expr *> ConstraintExprs,
     llvm::SmallVectorImpl<Expr *> &ConvertedConstraints,
     const MultiLevelTemplateArgumentList &TemplateArgsLists,
     SourceRange TemplateIDRange, ConstraintSatisfaction &OutSatisfaction) {
@@ -690,7 +690,7 @@ bool Sema::CheckConstraintSatisfaction(
   return false;
 }
 
-bool Sema::CheckConstraintSatisfaction(const Expr *ConstraintExpr,
+bool Sema::CheckConstraintSatisfaction(Expr *ConstraintExpr,
                                        ConstraintSatisfaction &Satisfaction) {
 
   struct ConstraintEvaluator {
@@ -847,7 +847,7 @@ Sema::SetupConstraintCheckingTemplateArgumentsAndScope(
   return MLTAL;
 }
 
-bool Sema::CheckFunctionConstraints(const FunctionDecl *FD,
+bool Sema::CheckFunctionConstraints(FunctionDecl *FD,
                                     ConstraintSatisfaction &Satisfaction,
                                     SourceLocation UsageLoc,
                                     bool ForOverloadResolution) {
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index e45abdc45045bb..f7183402e3f95b 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -10966,7 +10966,7 @@ static bool checkAddressOfFunctionIsAvailable(Sema &S, const FunctionDecl *FD,
 
   if (FD->getTrailingRequiresClause()) {
     ConstraintSatisfaction Satisfaction;
-    if (S.CheckFunctionConstraints(FD, Satisfaction, Loc))
+    if (S.CheckFunctionConstraints(const_cast<FunctionDecl *>(FD), Satisfaction, Loc))
       return false;
     if (!Satisfaction.IsSatisfied) {
       if (Complain) {

>From 78298953c506fd6b2477681772b75febea147103 Mon Sep 17 00:00:00 2001
From: Vlad Serebrennikov <serebrennikov.vladislav at gmail.com>
Date: Sat, 17 Aug 2024 21:27:53 +0300
Subject: [PATCH 10/14] Step 10

---
 clang/include/clang/Sema/Sema.h |  4 ++--
 clang/lib/Sema/SemaChecking.cpp |  2 +-
 clang/lib/Sema/SemaExpr.cpp     |  2 +-
 clang/lib/Sema/SemaInit.cpp     |  2 +-
 clang/lib/Sema/SemaLookup.cpp   |  2 +-
 clang/lib/Sema/SemaOverload.cpp | 12 ++++++------
 6 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 4747cfbb77a538..e46af5797abdc8 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -10391,7 +10391,7 @@ class Sema final : public SemaBase {
 
   // Emit as a 'note' the specific overload candidate
   void NoteOverloadCandidate(
-      const NamedDecl *Found, const FunctionDecl *Fn,
+      const NamedDecl *Found, FunctionDecl *Fn,
       OverloadCandidateRewriteKind RewriteKind = OverloadCandidateRewriteKind(),
       QualType DestType = QualType(), bool TakingAddress = false);
 
@@ -10404,7 +10404,7 @@ class Sema final : public SemaBase {
   /// optionally emitting a diagnostic if the address can't be taken.
   ///
   /// Returns false if taking the address of the function is illegal.
-  bool checkAddressOfFunctionIsAvailable(const FunctionDecl *Function,
+  bool checkAddressOfFunctionIsAvailable(FunctionDecl *Function,
                                          bool Complain = false,
                                          SourceLocation Loc = SourceLocation());
 
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index ee143381cf4f79..1947931194a0a6 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -300,7 +300,7 @@ static bool BuiltinFunctionStart(Sema &S, CallExpr *TheCall) {
     return true;
   }
 
-  return !S.checkAddressOfFunctionIsAvailable(FD, /*Complain=*/true,
+  return !S.checkAddressOfFunctionIsAvailable(const_cast<FunctionDecl *>(FD), /*Complain=*/true,
                                               TheCall->getBeginLoc());
 }
 
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index f495658fe58641..b2d2b105403bb6 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -16579,7 +16579,7 @@ ExprResult Sema::ActOnEmbedExpr(SourceLocation EmbedKeywordLoc,
 }
 
 static bool maybeDiagnoseAssignmentToFunction(Sema &S, QualType DstType,
-                                              const Expr *SrcExpr) {
+                                              Expr *SrcExpr) {
   if (!DstType->isFunctionPointerType() ||
       !SrcExpr->getType()->isFunctionType())
     return false;
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index 2666e60c0dd67c..d1ba3a8ea232d1 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -6271,7 +6271,7 @@ InitializationSequence::InitializationSequence(
 
 /// Tries to get a FunctionDecl out of `E`. If it succeeds and we can take the
 /// address of that function, this returns true. Otherwise, it returns false.
-static bool isExprAnUnaddressableFunction(Sema &S, const Expr *E) {
+static bool isExprAnUnaddressableFunction(Sema &S, Expr *E) {
   auto *DRE = dyn_cast<DeclRefExpr>(E);
   if (!DRE || !isa<FunctionDecl>(DRE->getDecl()))
     return false;
diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp
index 7a6a64529f52ec..93fabb31a99d56 100644
--- a/clang/lib/Sema/SemaLookup.cpp
+++ b/clang/lib/Sema/SemaLookup.cpp
@@ -3718,7 +3718,7 @@ Sema::LookupLiteralOperator(Scope *S, LookupResult &R,
   // operator template, but not both.
   if (FoundRaw && FoundTemplate) {
     Diag(R.getNameLoc(), diag::err_ovl_ambiguous_call) << R.getLookupName();
-    for (const NamedDecl *D : R)
+    for (NamedDecl *D : R)
       NoteOverloadCandidate(D, D->getUnderlyingDecl()->getAsFunction());
     return LOLR_Error;
   }
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index f7183402e3f95b..e9f7383439f7d1 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -10949,7 +10949,7 @@ static bool isFunctionAlwaysEnabled(const ASTContext &Ctx,
 ///   we in overload resolution?
 /// \param Loc - The location of the statement we're complaining about. Ignored
 ///   if we're not complaining, or if we're in overload resolution.
-static bool checkAddressOfFunctionIsAvailable(Sema &S, const FunctionDecl *FD,
+static bool checkAddressOfFunctionIsAvailable(Sema &S, FunctionDecl *FD,
                                               bool Complain,
                                               bool InOverloadResolution,
                                               SourceLocation Loc) {
@@ -10966,7 +10966,7 @@ static bool checkAddressOfFunctionIsAvailable(Sema &S, const FunctionDecl *FD,
 
   if (FD->getTrailingRequiresClause()) {
     ConstraintSatisfaction Satisfaction;
-    if (S.CheckFunctionConstraints(const_cast<FunctionDecl *>(FD), Satisfaction, Loc))
+    if (S.CheckFunctionConstraints(FD, Satisfaction, Loc))
       return false;
     if (!Satisfaction.IsSatisfied) {
       if (Complain) {
@@ -11012,13 +11012,13 @@ static bool checkAddressOfFunctionIsAvailable(Sema &S, const FunctionDecl *FD,
 }
 
 static bool checkAddressOfCandidateIsAvailable(Sema &S,
-                                               const FunctionDecl *FD) {
+                                               FunctionDecl *FD) {
   return checkAddressOfFunctionIsAvailable(S, FD, /*Complain=*/true,
                                            /*InOverloadResolution=*/true,
                                            /*Loc=*/SourceLocation());
 }
 
-bool Sema::checkAddressOfFunctionIsAvailable(const FunctionDecl *Function,
+bool Sema::checkAddressOfFunctionIsAvailable(FunctionDecl *Function,
                                              bool Complain,
                                              SourceLocation Loc) {
   return ::checkAddressOfFunctionIsAvailable(*this, Function, Complain,
@@ -11048,7 +11048,7 @@ static bool shouldSkipNotingLambdaConversionDecl(const FunctionDecl *Fn) {
 }
 
 // Notes the location of an overload candidate.
-void Sema::NoteOverloadCandidate(const NamedDecl *Found, const FunctionDecl *Fn,
+void Sema::NoteOverloadCandidate(const NamedDecl *Found, FunctionDecl *Fn,
                                  OverloadCandidateRewriteKind RewriteKind,
                                  QualType DestType, bool TakingAddress) {
   if (TakingAddress && !checkAddressOfCandidateIsAvailable(*this, Fn))
@@ -14024,7 +14024,7 @@ static ExprResult FinishOverloadedCallExpr(Sema &SemaRef, Scope *S, Expr *Fn,
     // If the user passes in a function that we can't take the address of, we
     // generally end up emitting really bad error messages. Here, we attempt to
     // emit better ones.
-    for (const Expr *Arg : Args) {
+    for (Expr *Arg : Args) {
       if (!Arg->getType()->isFunctionType())
         continue;
       if (auto *DRE = dyn_cast<DeclRefExpr>(Arg->IgnoreParenImpCasts())) {

>From f344e0e82a4bd30645aceb9f9eb596e8d3d16a9c Mon Sep 17 00:00:00 2001
From: Vlad Serebrennikov <serebrennikov.vladislav at gmail.com>
Date: Sun, 18 Aug 2024 00:22:15 +0300
Subject: [PATCH 11/14] Fix test

---
 clang/unittests/AST/SourceLocationTest.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/clang/unittests/AST/SourceLocationTest.cpp b/clang/unittests/AST/SourceLocationTest.cpp
index 66daa56aace28a..91964ffb77e567 100644
--- a/clang/unittests/AST/SourceLocationTest.cpp
+++ b/clang/unittests/AST/SourceLocationTest.cpp
@@ -1094,8 +1094,8 @@ class ConceptSpecializationExprConceptReferenceRangeVerifier
 protected:
   SourceRange getRange(const VarTemplateDecl &Node) override {
     assert(Node.hasAssociatedConstraints());
-    SmallVector<const Expr *, 3> ACs;
-    Node.getAssociatedConstraints(ACs);
+    SmallVector<Expr *, 3> ACs;
+    const_cast<VarTemplateDecl &>(Node).getAssociatedConstraints(ACs);
     for (const Expr *Constraint : ACs) {
       if (const ConceptSpecializationExpr *CSConstraint =
               dyn_cast<ConceptSpecializationExpr>(Constraint)) {

>From 8bda17233317c6e88215669055be8195db4af333 Mon Sep 17 00:00:00 2001
From: Vlad Serebrennikov <serebrennikov.vladislav at gmail.com>
Date: Sun, 18 Aug 2024 01:51:06 +0300
Subject: [PATCH 12/14] Remove a `const_cast` that is no longer needed

---
 clang/lib/Sema/SemaTemplateInstantiate.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index b86f29ab08ccff..15f5cac5dd893f 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -272,7 +272,7 @@ Response HandleFunction(Sema &SemaRef, FunctionDecl *Function,
   } else if (TemplateArgumentList *TemplateArgs =
                  Function->getTemplateSpecializationArgs()) {
     // Add the template arguments for this specialization.
-    Result.addOuterTemplateArguments(const_cast<FunctionDecl *>(Function),
+    Result.addOuterTemplateArguments(Function,
                                      TemplateArgs->asMutableArray(),
                                      /*Final=*/false);
 

>From 919da31d73a408f16e1c855cb658359b73ad1d28 Mon Sep 17 00:00:00 2001
From: Vlad Serebrennikov <serebrennikov.vladislav at gmail.com>
Date: Sun, 18 Aug 2024 01:51:25 +0300
Subject: [PATCH 13/14] Remove THE `const_cast`

---
 clang/include/clang/Sema/Template.h | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/clang/include/clang/Sema/Template.h b/clang/include/clang/Sema/Template.h
index 4890bb8a044efd..62ff8916e3305d 100644
--- a/clang/include/clang/Sema/Template.h
+++ b/clang/include/clang/Sema/Template.h
@@ -199,8 +199,7 @@ enum class TemplateSubstitutionKind : char {
       assert(NumRetainedOuterLevels <= Depth && Depth < getNumLevels());
       assert(Index <
              TemplateArgumentLists[getNumLevels() - Depth - 1].Args.size());
-      const_cast<TemplateArgument &>(
-          TemplateArgumentLists[getNumLevels() - Depth - 1].Args[Index]) = Arg;
+      TemplateArgumentLists[getNumLevels() - Depth - 1].Args[Index] = Arg;
     }
 
     /// Add a new outmost level to the multi-level template argument

>From 915ea1d3dc326a8e4da0fd35ff3027cbb339c886 Mon Sep 17 00:00:00 2001
From: Vlad Serebrennikov <serebrennikov.vladislav at gmail.com>
Date: Sun, 18 Aug 2024 13:16:43 +0300
Subject: [PATCH 14/14] Add couple of bad `const_cast` to clang-tidy

---
 .../clang-tidy/modernize/UseConstraintsCheck.cpp          | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp
index ea4d99586c7110..060a623ee7307e 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp
@@ -356,8 +356,8 @@ static std::vector<FixItHint> handleReturnType(const FunctionDecl *Function,
   if (!TypeText)
     return {};
 
-  SmallVector<const Expr *, 3> ExistingConstraints;
-  Function->getAssociatedConstraints(ExistingConstraints);
+  SmallVector<Expr *, 3> ExistingConstraints;
+  const_cast<FunctionDecl *>(Function)->getAssociatedConstraints(ExistingConstraints);
   if (!ExistingConstraints.empty()) {
     // FIXME - Support adding new constraints to existing ones. Do we need to
     // consider subsumption?
@@ -404,8 +404,8 @@ handleTrailingTemplateType(const FunctionTemplateDecl *FunctionTemplate,
   if (!ConditionText)
     return {};
 
-  SmallVector<const Expr *, 3> ExistingConstraints;
-  Function->getAssociatedConstraints(ExistingConstraints);
+  SmallVector<Expr *, 3> ExistingConstraints;
+  const_cast<FunctionDecl *>(Function)->getAssociatedConstraints(ExistingConstraints);
   if (!ExistingConstraints.empty()) {
     // FIXME - Support adding new constraints to existing ones. Do we need to
     // consider subsumption?



More information about the cfe-commits mailing list