1 //===- SemaTemplate.h - C++ Templates ---------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //===----------------------------------------------------------------------===//
7 //
8 // This file provides types used in the semantic analysis of C++ templates.
9 //
10 //===----------------------------------------------------------------------===//
11 
12 #ifndef LLVM_CLANG_SEMA_TEMPLATE_H
13 #define LLVM_CLANG_SEMA_TEMPLATE_H
14 
15 #include "clang/AST/DeclTemplate.h"
16 #include "clang/AST/DeclVisitor.h"
17 #include "clang/AST/TemplateBase.h"
18 #include "clang/AST/Type.h"
19 #include "clang/Basic/LLVM.h"
20 #include "clang/Sema/Sema.h"
21 #include "llvm/ADT/ArrayRef.h"
22 #include "llvm/ADT/DenseMap.h"
23 #include "llvm/ADT/PointerUnion.h"
24 #include "llvm/ADT/SmallVector.h"
25 #include <cassert>
26 #include <utility>
27 
28 namespace clang {
29 
30 class ASTContext;
31 class BindingDecl;
32 class CXXMethodDecl;
33 class Decl;
34 class DeclaratorDecl;
35 class DeclContext;
36 class EnumDecl;
37 class FunctionDecl;
38 class NamedDecl;
39 class ParmVarDecl;
40 class TagDecl;
41 class TypedefNameDecl;
42 class TypeSourceInfo;
43 class VarDecl;
44 
45 /// The kind of template substitution being performed.
46 enum class TemplateSubstitutionKind : char {
47   /// We are substituting template parameters for template arguments in order
48   /// to form a template specialization.
49   Specialization,
50   /// We are substituting template parameters for (typically) other template
51   /// parameters in order to rewrite a declaration as a different declaration
52   /// (for example, when forming a deduction guide from a constructor).
53   Rewrite,
54 };
55 
56   /// Data structure that captures multiple levels of template argument
57   /// lists for use in template instantiation.
58   ///
59   /// Multiple levels of template arguments occur when instantiating the
60   /// definitions of member templates. For example:
61   ///
62   /// \code
63   /// template<typename T>
64   /// struct X {
65   ///   template<T Value>
66   ///   struct Y {
67   ///     void f();
68   ///   };
69   /// };
70   /// \endcode
71   ///
72   /// When instantiating X<int>::Y<17>::f, the multi-level template argument
73   /// list will contain a template argument list (int) at depth 0 and a
74   /// template argument list (17) at depth 1.
75   class MultiLevelTemplateArgumentList {
76     /// The template argument list at a certain template depth
77     using ArgList = ArrayRef<TemplateArgument>;
78     using ArgListsIterator = SmallVector<ArgList, 4>::iterator;
79     using ConstArgListsIterator = SmallVector<ArgList, 4>::const_iterator;
80 
81     /// The template argument lists, stored from the innermost template
82     /// argument list (first) to the outermost template argument list (last).
83     SmallVector<ArgList, 4> TemplateArgumentLists;
84 
85     /// The number of outer levels of template arguments that are not
86     /// being substituted.
87     unsigned NumRetainedOuterLevels = 0;
88 
89     /// The kind of substitution described by this argument list.
90     TemplateSubstitutionKind Kind = TemplateSubstitutionKind::Specialization;
91 
92   public:
93     /// Construct an empty set of template argument lists.
94     MultiLevelTemplateArgumentList() = default;
95 
96     /// Construct a single-level template argument list.
97     explicit
98     MultiLevelTemplateArgumentList(const TemplateArgumentList &TemplateArgs) {
99       addOuterTemplateArguments(&TemplateArgs);
100     }
101 
102     void setKind(TemplateSubstitutionKind K) { Kind = K; }
103 
104     /// Determine the kind of template substitution being performed.
105     TemplateSubstitutionKind getKind() const { return Kind; }
106 
107     /// Determine whether we are rewriting template parameters rather than
108     /// substituting for them. If so, we should not leave references to the
109     /// original template parameters behind.
110     bool isRewrite() const {
111       return Kind == TemplateSubstitutionKind::Rewrite;
112     }
113 
114     /// Determine the number of levels in this template argument
115     /// list.
116     unsigned getNumLevels() const {
117       return TemplateArgumentLists.size() + NumRetainedOuterLevels;
118     }
119 
120     /// Determine the number of substituted levels in this template
121     /// argument list.
122     unsigned getNumSubstitutedLevels() const {
123       return TemplateArgumentLists.size();
124     }
125 
126     // Determine the number of substituted args at 'Depth'.
127     unsigned getNumSubsitutedArgs(unsigned Depth) const {
128       assert(NumRetainedOuterLevels <= Depth && Depth < getNumLevels());
129       return TemplateArgumentLists[getNumLevels() - Depth - 1].size();
130     }
131 
132     unsigned getNumRetainedOuterLevels() const {
133       return NumRetainedOuterLevels;
134     }
135 
136     /// Determine how many of the \p OldDepth outermost template parameter
137     /// lists would be removed by substituting these arguments.
138     unsigned getNewDepth(unsigned OldDepth) const {
139       if (OldDepth < NumRetainedOuterLevels)
140         return OldDepth;
141       if (OldDepth < getNumLevels())
142         return NumRetainedOuterLevels;
143       return OldDepth - TemplateArgumentLists.size();
144     }
145 
146     /// Retrieve the template argument at a given depth and index.
147     const TemplateArgument &operator()(unsigned Depth, unsigned Index) const {
148       assert(NumRetainedOuterLevels <= Depth && Depth < getNumLevels());
149       assert(Index < TemplateArgumentLists[getNumLevels() - Depth - 1].size());
150       return TemplateArgumentLists[getNumLevels() - Depth - 1][Index];
151     }
152 
153     /// Determine whether there is a non-NULL template argument at the
154     /// given depth and index.
155     ///
156     /// There must exist a template argument list at the given depth.
157     bool hasTemplateArgument(unsigned Depth, unsigned Index) const {
158       assert(Depth < getNumLevels());
159 
160       if (Depth < NumRetainedOuterLevels)
161         return false;
162 
163       if (Index >= TemplateArgumentLists[getNumLevels() - Depth - 1].size())
164         return false;
165 
166       return !(*this)(Depth, Index).isNull();
167     }
168 
169     bool isAnyArgInstantiationDependent() const {
170       for (ArgList List : TemplateArgumentLists)
171         for (const TemplateArgument &TA : List)
172           if (TA.isInstantiationDependent())
173             return true;
174       return false;
175     }
176 
177     /// Clear out a specific template argument.
178     void setArgument(unsigned Depth, unsigned Index,
179                      TemplateArgument Arg) {
180       assert(NumRetainedOuterLevels <= Depth && Depth < getNumLevels());
181       assert(Index < TemplateArgumentLists[getNumLevels() - Depth - 1].size());
182       const_cast<TemplateArgument&>(
183                 TemplateArgumentLists[getNumLevels() - Depth - 1][Index])
184         = Arg;
185     }
186 
187     /// Add a new outermost level to the multi-level template argument
188     /// list.
189     void addOuterTemplateArguments(const TemplateArgumentList *TemplateArgs) {
190       addOuterTemplateArguments(ArgList(TemplateArgs->data(),
191                                         TemplateArgs->size()));
192     }
193 
194     /// Add a new outmost level to the multi-level template argument
195     /// list.
196     void addOuterTemplateArguments(ArgList Args) {
197       assert(!NumRetainedOuterLevels &&
198              "substituted args outside retained args?");
199       TemplateArgumentLists.push_back(Args);
200     }
201 
202     /// Replaces the current 'innermost' level with the provided argument list.
203     /// This is useful for type deduction cases where we need to get the entire
204     /// list from the AST, but then add the deduced innermost list.
205     void replaceInnermostTemplateArguments(ArgList Args) {
206       assert(TemplateArgumentLists.size() > 0 && "Replacing in an empty list?");
207       TemplateArgumentLists[0] = Args;
208     }
209 
210     /// Add an outermost level that we are not substituting. We have no
211     /// arguments at this level, and do not remove it from the depth of inner
212     /// template parameters that we instantiate.
213     void addOuterRetainedLevel() {
214       ++NumRetainedOuterLevels;
215     }
216     void addOuterRetainedLevels(unsigned Num) {
217       NumRetainedOuterLevels += Num;
218     }
219 
220     /// Retrieve the innermost template argument list.
221     const ArgList &getInnermost() const {
222       return TemplateArgumentLists.front();
223     }
224     /// Retrieve the outermost template argument list.
225     const ArgList &getOutermost() const {
226       return TemplateArgumentLists.back();
227     }
228     ArgListsIterator begin() { return TemplateArgumentLists.begin(); }
229     ConstArgListsIterator begin() const {
230       return TemplateArgumentLists.begin();
231     }
232     ArgListsIterator end() { return TemplateArgumentLists.end(); }
233     ConstArgListsIterator end() const { return TemplateArgumentLists.end(); }
234   };
235 
236   /// The context in which partial ordering of function templates occurs.
237   enum TPOC {
238     /// Partial ordering of function templates for a function call.
239     TPOC_Call,
240 
241     /// Partial ordering of function templates for a call to a
242     /// conversion function.
243     TPOC_Conversion,
244 
245     /// Partial ordering of function templates in other contexts, e.g.,
246     /// taking the address of a function template or matching a function
247     /// template specialization to a function template.
248     TPOC_Other
249   };
250 
251   // This is lame but unavoidable in a world without forward
252   // declarations of enums.  The alternatives are to either pollute
253   // Sema.h (by including this file) or sacrifice type safety (by
254   // making Sema.h declare things as enums).
255   class TemplatePartialOrderingContext {
256     TPOC Value;
257 
258   public:
259     TemplatePartialOrderingContext(TPOC Value) : Value(Value) {}
260 
261     operator TPOC() const { return Value; }
262   };
263 
264   /// Captures a template argument whose value has been deduced
265   /// via c++ template argument deduction.
266   class DeducedTemplateArgument : public TemplateArgument {
267     /// For a non-type template argument, whether the value was
268     /// deduced from an array bound.
269     bool DeducedFromArrayBound = false;
270 
271   public:
272     DeducedTemplateArgument() = default;
273 
274     DeducedTemplateArgument(const TemplateArgument &Arg,
275                             bool DeducedFromArrayBound = false)
276         : TemplateArgument(Arg), DeducedFromArrayBound(DeducedFromArrayBound) {}
277 
278     /// Construct an integral non-type template argument that
279     /// has been deduced, possibly from an array bound.
280     DeducedTemplateArgument(ASTContext &Ctx,
281                             const llvm::APSInt &Value,
282                             QualType ValueType,
283                             bool DeducedFromArrayBound)
284         : TemplateArgument(Ctx, Value, ValueType),
285           DeducedFromArrayBound(DeducedFromArrayBound) {}
286 
287     /// For a non-type template argument, determine whether the
288     /// template argument was deduced from an array bound.
289     bool wasDeducedFromArrayBound() const { return DeducedFromArrayBound; }
290 
291     /// Specify whether the given non-type template argument
292     /// was deduced from an array bound.
293     void setDeducedFromArrayBound(bool Deduced) {
294       DeducedFromArrayBound = Deduced;
295     }
296   };
297 
298   /// A stack-allocated class that identifies which local
299   /// variable declaration instantiations are present in this scope.
300   ///
301   /// A new instance of this class type will be created whenever we
302   /// instantiate a new function declaration, which will have its own
303   /// set of parameter declarations.
304   class LocalInstantiationScope {
305   public:
306     /// A set of declarations.
307     using DeclArgumentPack = SmallVector<VarDecl *, 4>;
308 
309   private:
310     /// Reference to the semantic analysis that is performing
311     /// this template instantiation.
312     Sema &SemaRef;
313 
314     using LocalDeclsMap =
315         llvm::SmallDenseMap<const Decl *,
316                             llvm::PointerUnion<Decl *, DeclArgumentPack *>, 4>;
317 
318     /// A mapping from local declarations that occur
319     /// within a template to their instantiations.
320     ///
321     /// This mapping is used during instantiation to keep track of,
322     /// e.g., function parameter and variable declarations. For example,
323     /// given:
324     ///
325     /// \code
326     ///   template<typename T> T add(T x, T y) { return x + y; }
327     /// \endcode
328     ///
329     /// when we instantiate add<int>, we will introduce a mapping from
330     /// the ParmVarDecl for 'x' that occurs in the template to the
331     /// instantiated ParmVarDecl for 'x'.
332     ///
333     /// For a parameter pack, the local instantiation scope may contain a
334     /// set of instantiated parameters. This is stored as a DeclArgumentPack
335     /// pointer.
336     LocalDeclsMap LocalDecls;
337 
338     /// The set of argument packs we've allocated.
339     SmallVector<DeclArgumentPack *, 1> ArgumentPacks;
340 
341     /// The outer scope, which contains local variable
342     /// definitions from some other instantiation (that may not be
343     /// relevant to this particular scope).
344     LocalInstantiationScope *Outer;
345 
346     /// Whether we have already exited this scope.
347     bool Exited = false;
348 
349     /// Whether to combine this scope with the outer scope, such that
350     /// lookup will search our outer scope.
351     bool CombineWithOuterScope;
352 
353     /// If non-NULL, the template parameter pack that has been
354     /// partially substituted per C++0x [temp.arg.explicit]p9.
355     NamedDecl *PartiallySubstitutedPack = nullptr;
356 
357     /// If \c PartiallySubstitutedPack is non-null, the set of
358     /// explicitly-specified template arguments in that pack.
359     const TemplateArgument *ArgsInPartiallySubstitutedPack;
360 
361     /// If \c PartiallySubstitutedPack, the number of
362     /// explicitly-specified template arguments in
363     /// ArgsInPartiallySubstitutedPack.
364     unsigned NumArgsInPartiallySubstitutedPack;
365 
366   public:
367     LocalInstantiationScope(Sema &SemaRef, bool CombineWithOuterScope = false)
368         : SemaRef(SemaRef), Outer(SemaRef.CurrentInstantiationScope),
369           CombineWithOuterScope(CombineWithOuterScope) {
370       SemaRef.CurrentInstantiationScope = this;
371     }
372 
373     LocalInstantiationScope(const LocalInstantiationScope &) = delete;
374     LocalInstantiationScope &
375     operator=(const LocalInstantiationScope &) = delete;
376 
377     ~LocalInstantiationScope() {
378       Exit();
379     }
380 
381     const Sema &getSema() const { return SemaRef; }
382 
383     /// Exit this local instantiation scope early.
384     void Exit() {
385       if (Exited)
386         return;
387 
388       for (unsigned I = 0, N = ArgumentPacks.size(); I != N; ++I)
389         delete ArgumentPacks[I];
390 
391       SemaRef.CurrentInstantiationScope = Outer;
392       Exited = true;
393     }
394 
395     /// Clone this scope, and all outer scopes, down to the given
396     /// outermost scope.
397     LocalInstantiationScope *cloneScopes(LocalInstantiationScope *Outermost) {
398       if (this == Outermost) return this;
399 
400       // Save the current scope from SemaRef since the LocalInstantiationScope
401       // will overwrite it on construction
402       LocalInstantiationScope *oldScope = SemaRef.CurrentInstantiationScope;
403 
404       LocalInstantiationScope *newScope =
405         new LocalInstantiationScope(SemaRef, CombineWithOuterScope);
406 
407       newScope->Outer = nullptr;
408       if (Outer)
409         newScope->Outer = Outer->cloneScopes(Outermost);
410 
411       newScope->PartiallySubstitutedPack = PartiallySubstitutedPack;
412       newScope->ArgsInPartiallySubstitutedPack = ArgsInPartiallySubstitutedPack;
413       newScope->NumArgsInPartiallySubstitutedPack =
414         NumArgsInPartiallySubstitutedPack;
415 
416       for (LocalDeclsMap::iterator I = LocalDecls.begin(), E = LocalDecls.end();
417            I != E; ++I) {
418         const Decl *D = I->first;
419         llvm::PointerUnion<Decl *, DeclArgumentPack *> &Stored =
420           newScope->LocalDecls[D];
421         if (I->second.is<Decl *>()) {
422           Stored = I->second.get<Decl *>();
423         } else {
424           DeclArgumentPack *OldPack = I->second.get<DeclArgumentPack *>();
425           DeclArgumentPack *NewPack = new DeclArgumentPack(*OldPack);
426           Stored = NewPack;
427           newScope->ArgumentPacks.push_back(NewPack);
428         }
429       }
430       // Restore the saved scope to SemaRef
431       SemaRef.CurrentInstantiationScope = oldScope;
432       return newScope;
433     }
434 
435     /// deletes the given scope, and all outer scopes, down to the
436     /// given outermost scope.
437     static void deleteScopes(LocalInstantiationScope *Scope,
438                              LocalInstantiationScope *Outermost) {
439       while (Scope && Scope != Outermost) {
440         LocalInstantiationScope *Out = Scope->Outer;
441         delete Scope;
442         Scope = Out;
443       }
444     }
445 
446     /// Find the instantiation of the declaration D within the current
447     /// instantiation scope.
448     ///
449     /// \param D The declaration whose instantiation we are searching for.
450     ///
451     /// \returns A pointer to the declaration or argument pack of declarations
452     /// to which the declaration \c D is instantiated, if found. Otherwise,
453     /// returns NULL.
454     llvm::PointerUnion<Decl *, DeclArgumentPack *> *
455     findInstantiationOf(const Decl *D);
456 
457     void InstantiatedLocal(const Decl *D, Decl *Inst);
458     void InstantiatedLocalPackArg(const Decl *D, VarDecl *Inst);
459     void MakeInstantiatedLocalArgPack(const Decl *D);
460 
461     /// Note that the given parameter pack has been partially substituted
462     /// via explicit specification of template arguments
463     /// (C++0x [temp.arg.explicit]p9).
464     ///
465     /// \param Pack The parameter pack, which will always be a template
466     /// parameter pack.
467     ///
468     /// \param ExplicitArgs The explicitly-specified template arguments provided
469     /// for this parameter pack.
470     ///
471     /// \param NumExplicitArgs The number of explicitly-specified template
472     /// arguments provided for this parameter pack.
473     void SetPartiallySubstitutedPack(NamedDecl *Pack,
474                                      const TemplateArgument *ExplicitArgs,
475                                      unsigned NumExplicitArgs);
476 
477     /// Reset the partially-substituted pack when it is no longer of
478     /// interest.
479     void ResetPartiallySubstitutedPack() {
480       assert(PartiallySubstitutedPack && "No partially-substituted pack");
481       PartiallySubstitutedPack = nullptr;
482       ArgsInPartiallySubstitutedPack = nullptr;
483       NumArgsInPartiallySubstitutedPack = 0;
484     }
485 
486     /// Retrieve the partially-substitued template parameter pack.
487     ///
488     /// If there is no partially-substituted parameter pack, returns NULL.
489     NamedDecl *
490     getPartiallySubstitutedPack(const TemplateArgument **ExplicitArgs = nullptr,
491                                 unsigned *NumExplicitArgs = nullptr) const;
492 
493     /// Determine whether D is a pack expansion created in this scope.
494     bool isLocalPackExpansion(const Decl *D);
495   };
496 
497   class TemplateDeclInstantiator
498     : public DeclVisitor<TemplateDeclInstantiator, Decl *>
499   {
500     Sema &SemaRef;
501     Sema::ArgumentPackSubstitutionIndexRAII SubstIndex;
502     DeclContext *Owner;
503     const MultiLevelTemplateArgumentList &TemplateArgs;
504     Sema::LateInstantiatedAttrVec* LateAttrs = nullptr;
505     LocalInstantiationScope *StartingScope = nullptr;
506 
507     /// A list of out-of-line class template partial
508     /// specializations that will need to be instantiated after the
509     /// enclosing class's instantiation is complete.
510     SmallVector<std::pair<ClassTemplateDecl *,
511                                 ClassTemplatePartialSpecializationDecl *>, 4>
512       OutOfLinePartialSpecs;
513 
514     /// A list of out-of-line variable template partial
515     /// specializations that will need to be instantiated after the
516     /// enclosing variable's instantiation is complete.
517     /// FIXME: Verify that this is needed.
518     SmallVector<
519         std::pair<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>, 4>
520     OutOfLineVarPartialSpecs;
521 
522   public:
523     TemplateDeclInstantiator(Sema &SemaRef, DeclContext *Owner,
524                              const MultiLevelTemplateArgumentList &TemplateArgs)
525         : SemaRef(SemaRef),
526           SubstIndex(SemaRef, SemaRef.ArgumentPackSubstitutionIndex),
527           Owner(Owner), TemplateArgs(TemplateArgs) {}
528 
529 // Define all the decl visitors using DeclNodes.inc
530 #define DECL(DERIVED, BASE) \
531     Decl *Visit ## DERIVED ## Decl(DERIVED ## Decl *D);
532 #define ABSTRACT_DECL(DECL)
533 
534 // Decls which never appear inside a class or function.
535 #define OBJCCONTAINER(DERIVED, BASE)
536 #define FILESCOPEASM(DERIVED, BASE)
537 #define IMPORT(DERIVED, BASE)
538 #define EXPORT(DERIVED, BASE)
539 #define LINKAGESPEC(DERIVED, BASE)
540 #define OBJCCOMPATIBLEALIAS(DERIVED, BASE)
541 #define OBJCMETHOD(DERIVED, BASE)
542 #define OBJCTYPEPARAM(DERIVED, BASE)
543 #define OBJCIVAR(DERIVED, BASE)
544 #define OBJCPROPERTY(DERIVED, BASE)
545 #define OBJCPROPERTYIMPL(DERIVED, BASE)
546 #define EMPTY(DERIVED, BASE)
547 #define LIFETIMEEXTENDEDTEMPORARY(DERIVED, BASE)
548 
549     // Decls which use special-case instantiation code.
550 #define BLOCK(DERIVED, BASE)
551 #define CAPTURED(DERIVED, BASE)
552 #define IMPLICITPARAM(DERIVED, BASE)
553 
554 #include "clang/AST/DeclNodes.inc"
555 
556     enum class RewriteKind { None, RewriteSpaceshipAsEqualEqual };
557 
558     void adjustForRewrite(RewriteKind RK, FunctionDecl *Orig, QualType &T,
559                           TypeSourceInfo *&TInfo,
560                           DeclarationNameInfo &NameInfo);
561 
562     // A few supplemental visitor functions.
563     Decl *VisitCXXMethodDecl(CXXMethodDecl *D,
564                              TemplateParameterList *TemplateParams,
565                              Optional<const ASTTemplateArgumentListInfo *>
566                                  ClassScopeSpecializationArgs = llvm::None,
567                              RewriteKind RK = RewriteKind::None);
568     Decl *VisitFunctionDecl(FunctionDecl *D,
569                             TemplateParameterList *TemplateParams,
570                             RewriteKind RK = RewriteKind::None);
571     Decl *VisitDecl(Decl *D);
572     Decl *VisitVarDecl(VarDecl *D, bool InstantiatingVarTemplate,
573                        ArrayRef<BindingDecl *> *Bindings = nullptr);
574     Decl *VisitBaseUsingDecls(BaseUsingDecl *D, BaseUsingDecl *Inst,
575                               LookupResult *Lookup);
576 
577     // Enable late instantiation of attributes.  Late instantiated attributes
578     // will be stored in LA.
579     void enableLateAttributeInstantiation(Sema::LateInstantiatedAttrVec *LA) {
580       LateAttrs = LA;
581       StartingScope = SemaRef.CurrentInstantiationScope;
582     }
583 
584     // Disable late instantiation of attributes.
585     void disableLateAttributeInstantiation() {
586       LateAttrs = nullptr;
587       StartingScope = nullptr;
588     }
589 
590     LocalInstantiationScope *getStartingScope() const { return StartingScope; }
591 
592     using delayed_partial_spec_iterator = SmallVectorImpl<std::pair<
593       ClassTemplateDecl *, ClassTemplatePartialSpecializationDecl *>>::iterator;
594 
595     using delayed_var_partial_spec_iterator = SmallVectorImpl<std::pair<
596         VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>>::iterator;
597 
598     /// Return an iterator to the beginning of the set of
599     /// "delayed" partial specializations, which must be passed to
600     /// InstantiateClassTemplatePartialSpecialization once the class
601     /// definition has been completed.
602     delayed_partial_spec_iterator delayed_partial_spec_begin() {
603       return OutOfLinePartialSpecs.begin();
604     }
605 
606     delayed_var_partial_spec_iterator delayed_var_partial_spec_begin() {
607       return OutOfLineVarPartialSpecs.begin();
608     }
609 
610     /// Return an iterator to the end of the set of
611     /// "delayed" partial specializations, which must be passed to
612     /// InstantiateClassTemplatePartialSpecialization once the class
613     /// definition has been completed.
614     delayed_partial_spec_iterator delayed_partial_spec_end() {
615       return OutOfLinePartialSpecs.end();
616     }
617 
618     delayed_var_partial_spec_iterator delayed_var_partial_spec_end() {
619       return OutOfLineVarPartialSpecs.end();
620     }
621 
622     // Helper functions for instantiating methods.
623     TypeSourceInfo *SubstFunctionType(FunctionDecl *D,
624                              SmallVectorImpl<ParmVarDecl *> &Params);
625     bool InitFunctionInstantiation(FunctionDecl *New, FunctionDecl *Tmpl);
626     bool InitMethodInstantiation(CXXMethodDecl *New, CXXMethodDecl *Tmpl);
627 
628     bool SubstDefaultedFunction(FunctionDecl *New, FunctionDecl *Tmpl);
629 
630     TemplateParameterList *
631       SubstTemplateParams(TemplateParameterList *List);
632 
633     bool SubstQualifier(const DeclaratorDecl *OldDecl,
634                         DeclaratorDecl *NewDecl);
635     bool SubstQualifier(const TagDecl *OldDecl,
636                         TagDecl *NewDecl);
637 
638     Decl *VisitVarTemplateSpecializationDecl(
639         VarTemplateDecl *VarTemplate, VarDecl *FromVar,
640         const TemplateArgumentListInfo &TemplateArgsInfo,
641         ArrayRef<TemplateArgument> Converted,
642         VarTemplateSpecializationDecl *PrevDecl = nullptr);
643 
644     Decl *InstantiateTypedefNameDecl(TypedefNameDecl *D, bool IsTypeAlias);
645     ClassTemplatePartialSpecializationDecl *
646     InstantiateClassTemplatePartialSpecialization(
647                                               ClassTemplateDecl *ClassTemplate,
648                            ClassTemplatePartialSpecializationDecl *PartialSpec);
649     VarTemplatePartialSpecializationDecl *
650     InstantiateVarTemplatePartialSpecialization(
651         VarTemplateDecl *VarTemplate,
652         VarTemplatePartialSpecializationDecl *PartialSpec);
653     void InstantiateEnumDefinition(EnumDecl *Enum, EnumDecl *Pattern);
654 
655   private:
656     template<typename T>
657     Decl *instantiateUnresolvedUsingDecl(T *D,
658                                          bool InstantiatingPackElement = false);
659   };
660 
661 } // namespace clang
662 
663 #endif // LLVM_CLANG_SEMA_TEMPLATE_H
664