llvm/clang/lib/Sema/SemaTemplateInstantiate.cpp

//===------- SemaTemplateInstantiate.cpp - C++ Template Instantiation ------===/
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//===----------------------------------------------------------------------===/
//
//  This file implements C++ template instantiation.
//
//===----------------------------------------------------------------------===/

#include "TreeTransform.h"
#include "clang/AST/ASTConcept.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTLambda.h"
#include "clang/AST/ASTMutationListener.h"
#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprConcepts.h"
#include "clang/AST/PrettyDeclStackTrace.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/AST/Type.h"
#include "clang/AST/TypeLoc.h"
#include "clang/AST/TypeVisitor.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/Stack.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Sema/DeclSpec.h"
#include "clang/Sema/EnterExpressionEvaluationContext.h"
#include "clang/Sema/Initialization.h"
#include "clang/Sema/Lookup.h"
#include "clang/Sema/Sema.h"
#include "clang/Sema/SemaConcept.h"
#include "clang/Sema/SemaInternal.h"
#include "clang/Sema/Template.h"
#include "clang/Sema/TemplateDeduction.h"
#include "clang/Sema/TemplateInstCallback.h"
#include "llvm/ADT/STLForwardCompat.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/SaveAndRestore.h"
#include "llvm/Support/TimeProfiler.h"
#include <optional>

usingnamespaceclang;
usingnamespacesema;

//===----------------------------------------------------------------------===/
// Template Instantiation Support
//===----------------------------------------------------------------------===/

namespace {
namespace TemplateInstArgsHelpers {
struct Response {};

// Retrieve the primary template for a lambda call operator. It's
// unfortunate that we only have the mappings of call operators rather
// than lambda classes.
const FunctionDecl *
getPrimaryTemplateOfGenericLambda(const FunctionDecl *LambdaCallOperator) {}

struct EnclosingTypeAliasTemplateDetails {};

// Find the enclosing type alias template Decl from CodeSynthesisContexts, as
// well as its primary template and instantiating template arguments.
EnclosingTypeAliasTemplateDetails
getEnclosingTypeAliasTemplateDecl(Sema &SemaRef) {}

// Check if we are currently inside of a lambda expression that is
// surrounded by a using alias declaration. e.g.
//   template <class> using type = decltype([](auto) { ^ }());
// We have to do so since a TypeAliasTemplateDecl (or a TypeAliasDecl) is never
// a DeclContext, nor does it have an associated specialization Decl from which
// we could collect these template arguments.
bool isLambdaEnclosedByTypeAliasDecl(
    const FunctionDecl *LambdaCallOperator,
    const TypeAliasTemplateDecl *PrimaryTypeAliasDecl) {}

// Add template arguments from a variable template instantiation.
Response
HandleVarTemplateSpec(const VarTemplateSpecializationDecl *VarTemplSpec,
                      MultiLevelTemplateArgumentList &Result,
                      bool SkipForSpecialization) {}

// If we have a template template parameter with translation unit context,
// then we're performing substitution into a default template argument of
// this template template parameter before we've constructed the template
// that will own this template template parameter. In this case, we
// use empty template parameter lists for all of the outer templates
// to avoid performing any substitutions.
Response
HandleDefaultTempArgIntoTempTempParam(const TemplateTemplateParmDecl *TTP,
                                      MultiLevelTemplateArgumentList &Result) {}

Response HandlePartialClassTemplateSpec(
    const ClassTemplatePartialSpecializationDecl *PartialClassTemplSpec,
    MultiLevelTemplateArgumentList &Result, bool SkipForSpecialization) {}

// Add template arguments from a class template instantiation.
Response
HandleClassTemplateSpec(const ClassTemplateSpecializationDecl *ClassTemplSpec,
                        MultiLevelTemplateArgumentList &Result,
                        bool SkipForSpecialization) {}

Response HandleFunction(Sema &SemaRef, const FunctionDecl *Function,
                        MultiLevelTemplateArgumentList &Result,
                        const FunctionDecl *Pattern, bool RelativeToPrimary,
                        bool ForConstraintInstantiation,
                        bool ForDefaultArgumentSubstitution) {}

Response HandleFunctionTemplateDecl(const FunctionTemplateDecl *FTD,
                                    MultiLevelTemplateArgumentList &Result) {}

Response HandleRecordDecl(Sema &SemaRef, const CXXRecordDecl *Rec,
                          MultiLevelTemplateArgumentList &Result,
                          ASTContext &Context,
                          bool ForConstraintInstantiation) {}

Response HandleImplicitConceptSpecializationDecl(
    const ImplicitConceptSpecializationDecl *CSD,
    MultiLevelTemplateArgumentList &Result) {}

Response HandleGenericDeclContext(const Decl *CurDecl) {}
} // namespace TemplateInstArgsHelpers
} // namespace

MultiLevelTemplateArgumentList Sema::getTemplateInstantiationArgs(
    const NamedDecl *ND, const DeclContext *DC, bool Final,
    std::optional<ArrayRef<TemplateArgument>> Innermost, bool RelativeToPrimary,
    const FunctionDecl *Pattern, bool ForConstraintInstantiation,
    bool SkipForSpecialization, bool ForDefaultArgumentSubstitution) {}

bool Sema::CodeSynthesisContext::isInstantiationRecord() const {}

Sema::InstantiatingTemplate::InstantiatingTemplate(
    Sema &SemaRef, CodeSynthesisContext::SynthesisKind Kind,
    SourceLocation PointOfInstantiation, SourceRange InstantiationRange,
    Decl *Entity, NamedDecl *Template, ArrayRef<TemplateArgument> TemplateArgs,
    sema::TemplateDeductionInfo *DeductionInfo)
    :{}

Sema::InstantiatingTemplate::InstantiatingTemplate(
    Sema &SemaRef, SourceLocation PointOfInstantiation, Decl *Entity,
    SourceRange InstantiationRange)
    :{}

Sema::InstantiatingTemplate::InstantiatingTemplate(
    Sema &SemaRef, SourceLocation PointOfInstantiation, FunctionDecl *Entity,
    ExceptionSpecification, SourceRange InstantiationRange)
    :{}

Sema::InstantiatingTemplate::InstantiatingTemplate(
    Sema &SemaRef, SourceLocation PointOfInstantiation, TemplateParameter Param,
    TemplateDecl *Template, ArrayRef<TemplateArgument> TemplateArgs,
    SourceRange InstantiationRange)
    :{}

Sema::InstantiatingTemplate::InstantiatingTemplate(
    Sema &SemaRef, SourceLocation PointOfInstantiation,
    FunctionTemplateDecl *FunctionTemplate,
    ArrayRef<TemplateArgument> TemplateArgs,
    CodeSynthesisContext::SynthesisKind Kind,
    sema::TemplateDeductionInfo &DeductionInfo, SourceRange InstantiationRange)
    :{}

Sema::InstantiatingTemplate::InstantiatingTemplate(
    Sema &SemaRef, SourceLocation PointOfInstantiation,
    TemplateDecl *Template,
    ArrayRef<TemplateArgument> TemplateArgs,
    sema::TemplateDeductionInfo &DeductionInfo, SourceRange InstantiationRange)
    :{}

Sema::InstantiatingTemplate::InstantiatingTemplate(
    Sema &SemaRef, SourceLocation PointOfInstantiation,
    ClassTemplatePartialSpecializationDecl *PartialSpec,
    ArrayRef<TemplateArgument> TemplateArgs,
    sema::TemplateDeductionInfo &DeductionInfo, SourceRange InstantiationRange)
    :{}

Sema::InstantiatingTemplate::InstantiatingTemplate(
    Sema &SemaRef, SourceLocation PointOfInstantiation,
    VarTemplatePartialSpecializationDecl *PartialSpec,
    ArrayRef<TemplateArgument> TemplateArgs,
    sema::TemplateDeductionInfo &DeductionInfo, SourceRange InstantiationRange)
    :{}

Sema::InstantiatingTemplate::InstantiatingTemplate(
    Sema &SemaRef, SourceLocation PointOfInstantiation, ParmVarDecl *Param,
    ArrayRef<TemplateArgument> TemplateArgs, SourceRange InstantiationRange)
    :{}

Sema::InstantiatingTemplate::InstantiatingTemplate(
    Sema &SemaRef, SourceLocation PointOfInstantiation, NamedDecl *Template,
    NonTypeTemplateParmDecl *Param, ArrayRef<TemplateArgument> TemplateArgs,
    SourceRange InstantiationRange)
    :{}

Sema::InstantiatingTemplate::InstantiatingTemplate(
    Sema &SemaRef, SourceLocation PointOfInstantiation, NamedDecl *Template,
    TemplateTemplateParmDecl *Param, ArrayRef<TemplateArgument> TemplateArgs,
    SourceRange InstantiationRange)
    :{}

Sema::InstantiatingTemplate::InstantiatingTemplate(
    Sema &SemaRef, SourceLocation PointOfInstantiation,
    TypeAliasTemplateDecl *Entity, ArrayRef<TemplateArgument> TemplateArgs,
    SourceRange InstantiationRange)
    :{}

Sema::InstantiatingTemplate::InstantiatingTemplate(
    Sema &SemaRef, SourceLocation PointOfInstantiation, TemplateDecl *Template,
    NamedDecl *Param, ArrayRef<TemplateArgument> TemplateArgs,
    SourceRange InstantiationRange)
    :{}

Sema::InstantiatingTemplate::InstantiatingTemplate(
    Sema &SemaRef, SourceLocation PointOfInstantiation,
    concepts::Requirement *Req, sema::TemplateDeductionInfo &DeductionInfo,
    SourceRange InstantiationRange)
    :{}

Sema::InstantiatingTemplate::InstantiatingTemplate(
    Sema &SemaRef, SourceLocation PointOfInstantiation,
    concepts::NestedRequirement *Req, ConstraintsCheck,
    SourceRange InstantiationRange)
    :{}

Sema::InstantiatingTemplate::InstantiatingTemplate(
    Sema &SemaRef, SourceLocation PointOfInstantiation, const RequiresExpr *RE,
    sema::TemplateDeductionInfo &DeductionInfo, SourceRange InstantiationRange)
    :{}

Sema::InstantiatingTemplate::InstantiatingTemplate(
    Sema &SemaRef, SourceLocation PointOfInstantiation,
    ConstraintsCheck, NamedDecl *Template,
    ArrayRef<TemplateArgument> TemplateArgs, SourceRange InstantiationRange)
    :{}

Sema::InstantiatingTemplate::InstantiatingTemplate(
    Sema &SemaRef, SourceLocation PointOfInstantiation,
    ConstraintSubstitution, NamedDecl *Template,
    sema::TemplateDeductionInfo &DeductionInfo, SourceRange InstantiationRange)
    :{}

Sema::InstantiatingTemplate::InstantiatingTemplate(
    Sema &SemaRef, SourceLocation PointOfInstantiation,
    ConstraintNormalization, NamedDecl *Template,
    SourceRange InstantiationRange)
    :{}

Sema::InstantiatingTemplate::InstantiatingTemplate(
    Sema &SemaRef, SourceLocation PointOfInstantiation,
    ParameterMappingSubstitution, NamedDecl *Template,
    SourceRange InstantiationRange)
    :{}

Sema::InstantiatingTemplate::InstantiatingTemplate(
    Sema &SemaRef, SourceLocation PointOfInstantiation, TemplateDecl *Entity,
    BuildingDeductionGuidesTag, SourceRange InstantiationRange)
    :{}

Sema::InstantiatingTemplate::InstantiatingTemplate(
    Sema &SemaRef, SourceLocation ArgLoc, PartialOrderingTTP,
    TemplateDecl *PArg, SourceRange InstantiationRange)
    :{}

void Sema::pushCodeSynthesisContext(CodeSynthesisContext Ctx) {}

void Sema::popCodeSynthesisContext() {}

void Sema::InstantiatingTemplate::Clear() {}

static std::string convertCallArgsToString(Sema &S,
                                           llvm::ArrayRef<const Expr *> Args) {}

bool Sema::InstantiatingTemplate::CheckInstantiationDepth(
                                        SourceLocation PointOfInstantiation,
                                           SourceRange InstantiationRange) {}

void Sema::PrintInstantiationStack() {}

std::optional<TemplateDeductionInfo *> Sema::isSFINAEContext() const {}

//===----------------------------------------------------------------------===/
// Template Instantiation for Types
//===----------------------------------------------------------------------===/
namespace {
  class TemplateInstantiator : public TreeTransform<TemplateInstantiator> {};
}

bool TemplateInstantiator::AlreadyTransformed(QualType T) {}

static TemplateArgument
getPackSubstitutedTemplateArgument(Sema &S, TemplateArgument Arg) {}

Decl *TemplateInstantiator::TransformDecl(SourceLocation Loc, Decl *D) {}

Decl *TemplateInstantiator::TransformDefinition(SourceLocation Loc, Decl *D) {}

bool TemplateInstantiator::TransformExceptionSpec(
    SourceLocation Loc, FunctionProtoType::ExceptionSpecInfo &ESI,
    SmallVectorImpl<QualType> &Exceptions, bool &Changed) {}

NamedDecl *
TemplateInstantiator::TransformFirstQualifierInScope(NamedDecl *D,
                                                     SourceLocation Loc) {}

VarDecl *
TemplateInstantiator::RebuildExceptionDecl(VarDecl *ExceptionDecl,
                                           TypeSourceInfo *Declarator,
                                           SourceLocation StartLoc,
                                           SourceLocation NameLoc,
                                           IdentifierInfo *Name) {}

VarDecl *TemplateInstantiator::RebuildObjCExceptionDecl(VarDecl *ExceptionDecl,
                                                        TypeSourceInfo *TSInfo,
                                                        QualType T) {}

QualType
TemplateInstantiator::RebuildElaboratedType(SourceLocation KeywordLoc,
                                            ElaboratedTypeKeyword Keyword,
                                            NestedNameSpecifierLoc QualifierLoc,
                                            QualType T) {}

TemplateName TemplateInstantiator::TransformTemplateName(
    CXXScopeSpec &SS, TemplateName Name, SourceLocation NameLoc,
    QualType ObjectType, NamedDecl *FirstQualifierInScope,
    bool AllowInjectedClassName) {}

ExprResult
TemplateInstantiator::TransformPredefinedExpr(PredefinedExpr *E) {}

ExprResult
TemplateInstantiator::TransformTemplateParmRefExpr(DeclRefExpr *E,
                                               NonTypeTemplateParmDecl *NTTP) {}

const CXXAssumeAttr *
TemplateInstantiator::TransformCXXAssumeAttr(const CXXAssumeAttr *AA) {}

const LoopHintAttr *
TemplateInstantiator::TransformLoopHintAttr(const LoopHintAttr *LH) {}
const NoInlineAttr *TemplateInstantiator::TransformStmtNoInlineAttr(
    const Stmt *OrigS, const Stmt *InstS, const NoInlineAttr *A) {}
const AlwaysInlineAttr *TemplateInstantiator::TransformStmtAlwaysInlineAttr(
    const Stmt *OrigS, const Stmt *InstS, const AlwaysInlineAttr *A) {}

const CodeAlignAttr *
TemplateInstantiator::TransformCodeAlignAttr(const CodeAlignAttr *CA) {}

ExprResult TemplateInstantiator::transformNonTypeTemplateParmRef(
    Decl *AssociatedDecl, const NonTypeTemplateParmDecl *parm,
    SourceLocation loc, TemplateArgument arg,
    std::optional<unsigned> PackIndex) {}

ExprResult
TemplateInstantiator::TransformSubstNonTypeTemplateParmPackExpr(
                                          SubstNonTypeTemplateParmPackExpr *E) {}

ExprResult
TemplateInstantiator::TransformSubstNonTypeTemplateParmExpr(
                                          SubstNonTypeTemplateParmExpr *E) {}

ExprResult TemplateInstantiator::RebuildVarDeclRefExpr(VarDecl *PD,
                                                       SourceLocation Loc) {}

ExprResult
TemplateInstantiator::TransformFunctionParmPackExpr(FunctionParmPackExpr *E) {}

ExprResult
TemplateInstantiator::TransformFunctionParmPackRefExpr(DeclRefExpr *E,
                                                       VarDecl *PD) {}

ExprResult
TemplateInstantiator::TransformDeclRefExpr(DeclRefExpr *E) {}

ExprResult TemplateInstantiator::TransformCXXDefaultArgExpr(
    CXXDefaultArgExpr *E) {}

template<typename Fn>
QualType TemplateInstantiator::TransformFunctionProtoType(TypeLocBuilder &TLB,
                                 FunctionProtoTypeLoc TL,
                                 CXXRecordDecl *ThisContext,
                                 Qualifiers ThisTypeQuals,
                                 Fn TransformExceptionSpec) {}

ParmVarDecl *TemplateInstantiator::TransformFunctionTypeParam(
    ParmVarDecl *OldParm, int indexAdjustment,
    std::optional<unsigned> NumExpansions, bool ExpectParameterPack) {}

QualType TemplateInstantiator::BuildSubstTemplateTypeParmType(
    TypeLocBuilder &TLB, bool SuppressObjCLifetime, bool Final,
    Decl *AssociatedDecl, unsigned Index, std::optional<unsigned> PackIndex,
    TemplateArgument Arg, SourceLocation NameLoc) {}

QualType
TemplateInstantiator::TransformTemplateTypeParmType(TypeLocBuilder &TLB,
                                                    TemplateTypeParmTypeLoc TL,
                                                    bool SuppressObjCLifetime) {}

QualType TemplateInstantiator::TransformSubstTemplateTypeParmPackType(
    TypeLocBuilder &TLB, SubstTemplateTypeParmPackTypeLoc TL,
    bool SuppressObjCLifetime) {}

static concepts::Requirement::SubstitutionDiagnostic *
createSubstDiag(Sema &S, TemplateDeductionInfo &Info,
                concepts::EntityPrinter Printer) {}

concepts::Requirement::SubstitutionDiagnostic *
concepts::createSubstDiagAt(Sema &S, SourceLocation Location,
                            EntityPrinter Printer) {}

ExprResult TemplateInstantiator::TransformRequiresTypeParams(
    SourceLocation KWLoc, SourceLocation RBraceLoc, const RequiresExpr *RE,
    RequiresExprBodyDecl *Body, ArrayRef<ParmVarDecl *> Params,
    SmallVectorImpl<QualType> &PTypes,
    SmallVectorImpl<ParmVarDecl *> &TransParams,
    Sema::ExtParameterInfoBuilder &PInfos) {}

concepts::TypeRequirement *
TemplateInstantiator::TransformTypeRequirement(concepts::TypeRequirement *Req) {}

concepts::ExprRequirement *
TemplateInstantiator::TransformExprRequirement(concepts::ExprRequirement *Req) {}

concepts::NestedRequirement *
TemplateInstantiator::TransformNestedRequirement(
    concepts::NestedRequirement *Req) {}

TypeSourceInfo *Sema::SubstType(TypeSourceInfo *T,
                                const MultiLevelTemplateArgumentList &Args,
                                SourceLocation Loc,
                                DeclarationName Entity,
                                bool AllowDeducedTST) {}

TypeSourceInfo *Sema::SubstType(TypeLoc TL,
                                const MultiLevelTemplateArgumentList &Args,
                                SourceLocation Loc,
                                DeclarationName Entity) {}

/// Deprecated form of the above.
QualType Sema::SubstType(QualType T,
                         const MultiLevelTemplateArgumentList &TemplateArgs,
                         SourceLocation Loc, DeclarationName Entity,
                         bool *IsIncompleteSubstitution) {}

static bool NeedsInstantiationAsFunctionType(TypeSourceInfo *T) {}

TypeSourceInfo *Sema::SubstFunctionDeclType(TypeSourceInfo *T,
                                const MultiLevelTemplateArgumentList &Args,
                                SourceLocation Loc,
                                DeclarationName Entity,
                                CXXRecordDecl *ThisContext,
                                Qualifiers ThisTypeQuals,
                                bool EvaluateConstraints) {}

bool Sema::SubstExceptionSpec(SourceLocation Loc,
                              FunctionProtoType::ExceptionSpecInfo &ESI,
                              SmallVectorImpl<QualType> &ExceptionStorage,
                              const MultiLevelTemplateArgumentList &Args) {}

void Sema::SubstExceptionSpec(FunctionDecl *New, const FunctionProtoType *Proto,
                              const MultiLevelTemplateArgumentList &Args) {}

namespace {

  struct GetContainedInventedTypeParmVisitor :
    public TypeVisitor<GetContainedInventedTypeParmVisitor,
                       TemplateTypeParmDecl *> {};

} // namespace

namespace {

struct ExpandPackedTypeConstraints
    : TreeTransform<ExpandPackedTypeConstraints> {};

} // namespace

bool Sema::SubstTypeConstraint(
    TemplateTypeParmDecl *Inst, const TypeConstraint *TC,
    const MultiLevelTemplateArgumentList &TemplateArgs,
    bool EvaluateConstraints) {}

ParmVarDecl *Sema::SubstParmVarDecl(
    ParmVarDecl *OldParm, const MultiLevelTemplateArgumentList &TemplateArgs,
    int indexAdjustment, std::optional<unsigned> NumExpansions,
    bool ExpectParameterPack, bool EvaluateConstraint) {}

bool Sema::SubstParmTypes(
    SourceLocation Loc, ArrayRef<ParmVarDecl *> Params,
    const FunctionProtoType::ExtParameterInfo *ExtParamInfos,
    const MultiLevelTemplateArgumentList &TemplateArgs,
    SmallVectorImpl<QualType> &ParamTypes,
    SmallVectorImpl<ParmVarDecl *> *OutParams,
    ExtParameterInfoBuilder &ParamInfos) {}

bool Sema::SubstDefaultArgument(
    SourceLocation Loc,
    ParmVarDecl *Param,
    const MultiLevelTemplateArgumentList &TemplateArgs,
    bool ForCallExpr) {}

bool
Sema::SubstBaseSpecifiers(CXXRecordDecl *Instantiation,
                          CXXRecordDecl *Pattern,
                          const MultiLevelTemplateArgumentList &TemplateArgs) {}

// Defined via #include from SemaTemplateInstantiateDecl.cpp
namespace clang {
  namespace sema {
    Attr *instantiateTemplateAttribute(const Attr *At, ASTContext &C, Sema &S,
                            const MultiLevelTemplateArgumentList &TemplateArgs);
    Attr *instantiateTemplateAttributeForDecl(
        const Attr *At, ASTContext &C, Sema &S,
        const MultiLevelTemplateArgumentList &TemplateArgs);
  }
}

bool
Sema::InstantiateClass(SourceLocation PointOfInstantiation,
                       CXXRecordDecl *Instantiation, CXXRecordDecl *Pattern,
                       const MultiLevelTemplateArgumentList &TemplateArgs,
                       TemplateSpecializationKind TSK,
                       bool Complain) {}

bool Sema::InstantiateEnum(SourceLocation PointOfInstantiation,
                           EnumDecl *Instantiation, EnumDecl *Pattern,
                           const MultiLevelTemplateArgumentList &TemplateArgs,
                           TemplateSpecializationKind TSK) {}

bool Sema::InstantiateInClassInitializer(
    SourceLocation PointOfInstantiation, FieldDecl *Instantiation,
    FieldDecl *Pattern, const MultiLevelTemplateArgumentList &TemplateArgs) {}

namespace {
  /// A partial specialization whose template arguments have matched
  /// a given template-id.
  struct PartialSpecMatchResult {};
}

bool Sema::usesPartialOrExplicitSpecialization(
    SourceLocation Loc, ClassTemplateSpecializationDecl *ClassTemplateSpec) {}

/// Get the instantiation pattern to use to instantiate the definition of a
/// given ClassTemplateSpecializationDecl (either the pattern of the primary
/// template or of a partial specialization).
static ActionResult<CXXRecordDecl *>
getPatternForClassTemplateSpecialization(
    Sema &S, SourceLocation PointOfInstantiation,
    ClassTemplateSpecializationDecl *ClassTemplateSpec,
    TemplateSpecializationKind TSK) {}

bool Sema::InstantiateClassTemplateSpecialization(
    SourceLocation PointOfInstantiation,
    ClassTemplateSpecializationDecl *ClassTemplateSpec,
    TemplateSpecializationKind TSK, bool Complain) {}

void
Sema::InstantiateClassMembers(SourceLocation PointOfInstantiation,
                              CXXRecordDecl *Instantiation,
                        const MultiLevelTemplateArgumentList &TemplateArgs,
                              TemplateSpecializationKind TSK) {}

void
Sema::InstantiateClassTemplateSpecializationMembers(
                                           SourceLocation PointOfInstantiation,
                            ClassTemplateSpecializationDecl *ClassTemplateSpec,
                                               TemplateSpecializationKind TSK) {}

StmtResult
Sema::SubstStmt(Stmt *S, const MultiLevelTemplateArgumentList &TemplateArgs) {}

bool Sema::SubstTemplateArgument(
    const TemplateArgumentLoc &Input,
    const MultiLevelTemplateArgumentList &TemplateArgs,
    TemplateArgumentLoc &Output, SourceLocation Loc,
    const DeclarationName &Entity) {}

bool Sema::SubstTemplateArguments(
    ArrayRef<TemplateArgumentLoc> Args,
    const MultiLevelTemplateArgumentList &TemplateArgs,
    TemplateArgumentListInfo &Out) {}

ExprResult
Sema::SubstExpr(Expr *E, const MultiLevelTemplateArgumentList &TemplateArgs) {}

ExprResult
Sema::SubstConstraintExpr(Expr *E,
                          const MultiLevelTemplateArgumentList &TemplateArgs) {}

ExprResult Sema::SubstConstraintExprWithoutSatisfaction(
    Expr *E, const MultiLevelTemplateArgumentList &TemplateArgs) {}

ExprResult Sema::SubstInitializer(Expr *Init,
                          const MultiLevelTemplateArgumentList &TemplateArgs,
                          bool CXXDirectInit) {}

bool Sema::SubstExprs(ArrayRef<Expr *> Exprs, bool IsCall,
                      const MultiLevelTemplateArgumentList &TemplateArgs,
                      SmallVectorImpl<Expr *> &Outputs) {}

NestedNameSpecifierLoc
Sema::SubstNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS,
                        const MultiLevelTemplateArgumentList &TemplateArgs) {}

DeclarationNameInfo
Sema::SubstDeclarationNameInfo(const DeclarationNameInfo &NameInfo,
                         const MultiLevelTemplateArgumentList &TemplateArgs) {}

TemplateName
Sema::SubstTemplateName(NestedNameSpecifierLoc QualifierLoc,
                        TemplateName Name, SourceLocation Loc,
                        const MultiLevelTemplateArgumentList &TemplateArgs) {}

static const Decl *getCanonicalParmVarDecl(const Decl *D) {}


llvm::PointerUnion<Decl *, LocalInstantiationScope::DeclArgumentPack *> *
LocalInstantiationScope::findInstantiationOf(const Decl *D) {}

void LocalInstantiationScope::InstantiatedLocal(const Decl *D, Decl *Inst) {}

void LocalInstantiationScope::InstantiatedLocalPackArg(const Decl *D,
                                                       VarDecl *Inst) {}

void LocalInstantiationScope::MakeInstantiatedLocalArgPack(const Decl *D) {}

bool LocalInstantiationScope::isLocalPackExpansion(const Decl *D) {}

void LocalInstantiationScope::SetPartiallySubstitutedPack(NamedDecl *Pack,
                                          const TemplateArgument *ExplicitArgs,
                                                    unsigned NumExplicitArgs) {}

NamedDecl *LocalInstantiationScope::getPartiallySubstitutedPack(
                                         const TemplateArgument **ExplicitArgs,
                                              unsigned *NumExplicitArgs) const {}