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