xref: /aosp_15_r20/external/clang/include/clang/Sema/Template.h (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li //===------- SemaTemplate.h - C++ Templates ---------------------*- C++ -*-===/
2*67e74705SXin Li //
3*67e74705SXin Li //                     The LLVM Compiler Infrastructure
4*67e74705SXin Li //
5*67e74705SXin Li // This file is distributed under the University of Illinois Open Source
6*67e74705SXin Li // License. See LICENSE.TXT for details.
7*67e74705SXin Li //===----------------------------------------------------------------------===/
8*67e74705SXin Li //
9*67e74705SXin Li //  This file provides types used in the semantic analysis of C++ templates.
10*67e74705SXin Li //
11*67e74705SXin Li //===----------------------------------------------------------------------===/
12*67e74705SXin Li #ifndef LLVM_CLANG_SEMA_TEMPLATE_H
13*67e74705SXin Li #define LLVM_CLANG_SEMA_TEMPLATE_H
14*67e74705SXin Li 
15*67e74705SXin Li #include "clang/AST/DeclTemplate.h"
16*67e74705SXin Li #include "clang/AST/DeclVisitor.h"
17*67e74705SXin Li #include "clang/Sema/Sema.h"
18*67e74705SXin Li #include "llvm/ADT/SmallVector.h"
19*67e74705SXin Li #include <cassert>
20*67e74705SXin Li #include <utility>
21*67e74705SXin Li 
22*67e74705SXin Li namespace clang {
23*67e74705SXin Li   /// \brief Data structure that captures multiple levels of template argument
24*67e74705SXin Li   /// lists for use in template instantiation.
25*67e74705SXin Li   ///
26*67e74705SXin Li   /// Multiple levels of template arguments occur when instantiating the
27*67e74705SXin Li   /// definitions of member templates. For example:
28*67e74705SXin Li   ///
29*67e74705SXin Li   /// \code
30*67e74705SXin Li   /// template<typename T>
31*67e74705SXin Li   /// struct X {
32*67e74705SXin Li   ///   template<T Value>
33*67e74705SXin Li   ///   struct Y {
34*67e74705SXin Li   ///     void f();
35*67e74705SXin Li   ///   };
36*67e74705SXin Li   /// };
37*67e74705SXin Li   /// \endcode
38*67e74705SXin Li   ///
39*67e74705SXin Li   /// When instantiating X<int>::Y<17>::f, the multi-level template argument
40*67e74705SXin Li   /// list will contain a template argument list (int) at depth 0 and a
41*67e74705SXin Li   /// template argument list (17) at depth 1.
42*67e74705SXin Li   class MultiLevelTemplateArgumentList {
43*67e74705SXin Li     /// \brief The template argument list at a certain template depth
44*67e74705SXin Li     typedef ArrayRef<TemplateArgument> ArgList;
45*67e74705SXin Li 
46*67e74705SXin Li     /// \brief The template argument lists, stored from the innermost template
47*67e74705SXin Li     /// argument list (first) to the outermost template argument list (last).
48*67e74705SXin Li     SmallVector<ArgList, 4> TemplateArgumentLists;
49*67e74705SXin Li 
50*67e74705SXin Li   public:
51*67e74705SXin Li     /// \brief Construct an empty set of template argument lists.
MultiLevelTemplateArgumentList()52*67e74705SXin Li     MultiLevelTemplateArgumentList() { }
53*67e74705SXin Li 
54*67e74705SXin Li     /// \brief Construct a single-level template argument list.
55*67e74705SXin Li     explicit
MultiLevelTemplateArgumentList(const TemplateArgumentList & TemplateArgs)56*67e74705SXin Li     MultiLevelTemplateArgumentList(const TemplateArgumentList &TemplateArgs) {
57*67e74705SXin Li       addOuterTemplateArguments(&TemplateArgs);
58*67e74705SXin Li     }
59*67e74705SXin Li 
60*67e74705SXin Li     /// \brief Determine the number of levels in this template argument
61*67e74705SXin Li     /// list.
getNumLevels()62*67e74705SXin Li     unsigned getNumLevels() const { return TemplateArgumentLists.size(); }
63*67e74705SXin Li 
64*67e74705SXin Li     /// \brief Retrieve the template argument at a given depth and index.
operator()65*67e74705SXin Li     const TemplateArgument &operator()(unsigned Depth, unsigned Index) const {
66*67e74705SXin Li       assert(Depth < TemplateArgumentLists.size());
67*67e74705SXin Li       assert(Index < TemplateArgumentLists[getNumLevels() - Depth - 1].size());
68*67e74705SXin Li       return TemplateArgumentLists[getNumLevels() - Depth - 1][Index];
69*67e74705SXin Li     }
70*67e74705SXin Li 
71*67e74705SXin Li     /// \brief Determine whether there is a non-NULL template argument at the
72*67e74705SXin Li     /// given depth and index.
73*67e74705SXin Li     ///
74*67e74705SXin Li     /// There must exist a template argument list at the given depth.
hasTemplateArgument(unsigned Depth,unsigned Index)75*67e74705SXin Li     bool hasTemplateArgument(unsigned Depth, unsigned Index) const {
76*67e74705SXin Li       assert(Depth < TemplateArgumentLists.size());
77*67e74705SXin Li 
78*67e74705SXin Li       if (Index >= TemplateArgumentLists[getNumLevels() - Depth - 1].size())
79*67e74705SXin Li         return false;
80*67e74705SXin Li 
81*67e74705SXin Li       return !(*this)(Depth, Index).isNull();
82*67e74705SXin Li     }
83*67e74705SXin Li 
84*67e74705SXin Li     /// \brief Clear out a specific template argument.
setArgument(unsigned Depth,unsigned Index,TemplateArgument Arg)85*67e74705SXin Li     void setArgument(unsigned Depth, unsigned Index,
86*67e74705SXin Li                      TemplateArgument Arg) {
87*67e74705SXin Li       assert(Depth < TemplateArgumentLists.size());
88*67e74705SXin Li       assert(Index < TemplateArgumentLists[getNumLevels() - Depth - 1].size());
89*67e74705SXin Li       const_cast<TemplateArgument&>(
90*67e74705SXin Li                 TemplateArgumentLists[getNumLevels() - Depth - 1][Index])
91*67e74705SXin Li         = Arg;
92*67e74705SXin Li     }
93*67e74705SXin Li 
94*67e74705SXin Li     /// \brief Add a new outermost level to the multi-level template argument
95*67e74705SXin Li     /// list.
addOuterTemplateArguments(const TemplateArgumentList * TemplateArgs)96*67e74705SXin Li     void addOuterTemplateArguments(const TemplateArgumentList *TemplateArgs) {
97*67e74705SXin Li       addOuterTemplateArguments(ArgList(TemplateArgs->data(),
98*67e74705SXin Li                                         TemplateArgs->size()));
99*67e74705SXin Li     }
100*67e74705SXin Li 
101*67e74705SXin Li     /// \brief Add a new outmost level to the multi-level template argument
102*67e74705SXin Li     /// list.
addOuterTemplateArguments(ArgList Args)103*67e74705SXin Li     void addOuterTemplateArguments(ArgList Args) {
104*67e74705SXin Li       TemplateArgumentLists.push_back(Args);
105*67e74705SXin Li     }
106*67e74705SXin Li 
107*67e74705SXin Li     /// \brief Retrieve the innermost template argument list.
getInnermost()108*67e74705SXin Li     const ArgList &getInnermost() const {
109*67e74705SXin Li       return TemplateArgumentLists.front();
110*67e74705SXin Li     }
111*67e74705SXin Li   };
112*67e74705SXin Li 
113*67e74705SXin Li   /// \brief The context in which partial ordering of function templates occurs.
114*67e74705SXin Li   enum TPOC {
115*67e74705SXin Li     /// \brief Partial ordering of function templates for a function call.
116*67e74705SXin Li     TPOC_Call,
117*67e74705SXin Li     /// \brief Partial ordering of function templates for a call to a
118*67e74705SXin Li     /// conversion function.
119*67e74705SXin Li     TPOC_Conversion,
120*67e74705SXin Li     /// \brief Partial ordering of function templates in other contexts, e.g.,
121*67e74705SXin Li     /// taking the address of a function template or matching a function
122*67e74705SXin Li     /// template specialization to a function template.
123*67e74705SXin Li     TPOC_Other
124*67e74705SXin Li   };
125*67e74705SXin Li 
126*67e74705SXin Li   // This is lame but unavoidable in a world without forward
127*67e74705SXin Li   // declarations of enums.  The alternatives are to either pollute
128*67e74705SXin Li   // Sema.h (by including this file) or sacrifice type safety (by
129*67e74705SXin Li   // making Sema.h declare things as enums).
130*67e74705SXin Li   class TemplatePartialOrderingContext {
131*67e74705SXin Li     TPOC Value;
132*67e74705SXin Li   public:
TemplatePartialOrderingContext(TPOC Value)133*67e74705SXin Li     TemplatePartialOrderingContext(TPOC Value) : Value(Value) {}
TPOC()134*67e74705SXin Li     operator TPOC() const { return Value; }
135*67e74705SXin Li   };
136*67e74705SXin Li 
137*67e74705SXin Li   /// \brief Captures a template argument whose value has been deduced
138*67e74705SXin Li   /// via c++ template argument deduction.
139*67e74705SXin Li   class DeducedTemplateArgument : public TemplateArgument {
140*67e74705SXin Li     /// \brief For a non-type template argument, whether the value was
141*67e74705SXin Li     /// deduced from an array bound.
142*67e74705SXin Li     bool DeducedFromArrayBound;
143*67e74705SXin Li 
144*67e74705SXin Li   public:
DeducedTemplateArgument()145*67e74705SXin Li     DeducedTemplateArgument()
146*67e74705SXin Li       : TemplateArgument(), DeducedFromArrayBound(false) { }
147*67e74705SXin Li 
148*67e74705SXin Li     DeducedTemplateArgument(const TemplateArgument &Arg,
149*67e74705SXin Li                             bool DeducedFromArrayBound = false)
TemplateArgument(Arg)150*67e74705SXin Li       : TemplateArgument(Arg), DeducedFromArrayBound(DeducedFromArrayBound) { }
151*67e74705SXin Li 
152*67e74705SXin Li     /// \brief Construct an integral non-type template argument that
153*67e74705SXin Li     /// has been deduced, possibly from an array bound.
DeducedTemplateArgument(ASTContext & Ctx,const llvm::APSInt & Value,QualType ValueType,bool DeducedFromArrayBound)154*67e74705SXin Li     DeducedTemplateArgument(ASTContext &Ctx,
155*67e74705SXin Li                             const llvm::APSInt &Value,
156*67e74705SXin Li                             QualType ValueType,
157*67e74705SXin Li                             bool DeducedFromArrayBound)
158*67e74705SXin Li       : TemplateArgument(Ctx, Value, ValueType),
159*67e74705SXin Li         DeducedFromArrayBound(DeducedFromArrayBound) { }
160*67e74705SXin Li 
161*67e74705SXin Li     /// \brief For a non-type template argument, determine whether the
162*67e74705SXin Li     /// template argument was deduced from an array bound.
wasDeducedFromArrayBound()163*67e74705SXin Li     bool wasDeducedFromArrayBound() const { return DeducedFromArrayBound; }
164*67e74705SXin Li 
165*67e74705SXin Li     /// \brief Specify whether the given non-type template argument
166*67e74705SXin Li     /// was deduced from an array bound.
setDeducedFromArrayBound(bool Deduced)167*67e74705SXin Li     void setDeducedFromArrayBound(bool Deduced) {
168*67e74705SXin Li       DeducedFromArrayBound = Deduced;
169*67e74705SXin Li     }
170*67e74705SXin Li   };
171*67e74705SXin Li 
172*67e74705SXin Li   /// \brief A stack-allocated class that identifies which local
173*67e74705SXin Li   /// variable declaration instantiations are present in this scope.
174*67e74705SXin Li   ///
175*67e74705SXin Li   /// A new instance of this class type will be created whenever we
176*67e74705SXin Li   /// instantiate a new function declaration, which will have its own
177*67e74705SXin Li   /// set of parameter declarations.
178*67e74705SXin Li   class LocalInstantiationScope {
179*67e74705SXin Li   public:
180*67e74705SXin Li     /// \brief A set of declarations.
181*67e74705SXin Li     typedef SmallVector<ParmVarDecl *, 4> DeclArgumentPack;
182*67e74705SXin Li 
183*67e74705SXin Li   private:
184*67e74705SXin Li     /// \brief Reference to the semantic analysis that is performing
185*67e74705SXin Li     /// this template instantiation.
186*67e74705SXin Li     Sema &SemaRef;
187*67e74705SXin Li 
188*67e74705SXin Li     typedef llvm::SmallDenseMap<
189*67e74705SXin Li         const Decl *, llvm::PointerUnion<Decl *, DeclArgumentPack *>, 4>
190*67e74705SXin Li     LocalDeclsMap;
191*67e74705SXin Li 
192*67e74705SXin Li     /// \brief A mapping from local declarations that occur
193*67e74705SXin Li     /// within a template to their instantiations.
194*67e74705SXin Li     ///
195*67e74705SXin Li     /// This mapping is used during instantiation to keep track of,
196*67e74705SXin Li     /// e.g., function parameter and variable declarations. For example,
197*67e74705SXin Li     /// given:
198*67e74705SXin Li     ///
199*67e74705SXin Li     /// \code
200*67e74705SXin Li     ///   template<typename T> T add(T x, T y) { return x + y; }
201*67e74705SXin Li     /// \endcode
202*67e74705SXin Li     ///
203*67e74705SXin Li     /// when we instantiate add<int>, we will introduce a mapping from
204*67e74705SXin Li     /// the ParmVarDecl for 'x' that occurs in the template to the
205*67e74705SXin Li     /// instantiated ParmVarDecl for 'x'.
206*67e74705SXin Li     ///
207*67e74705SXin Li     /// For a parameter pack, the local instantiation scope may contain a
208*67e74705SXin Li     /// set of instantiated parameters. This is stored as a DeclArgumentPack
209*67e74705SXin Li     /// pointer.
210*67e74705SXin Li     LocalDeclsMap LocalDecls;
211*67e74705SXin Li 
212*67e74705SXin Li     /// \brief The set of argument packs we've allocated.
213*67e74705SXin Li     SmallVector<DeclArgumentPack *, 1> ArgumentPacks;
214*67e74705SXin Li 
215*67e74705SXin Li     /// \brief The outer scope, which contains local variable
216*67e74705SXin Li     /// definitions from some other instantiation (that may not be
217*67e74705SXin Li     /// relevant to this particular scope).
218*67e74705SXin Li     LocalInstantiationScope *Outer;
219*67e74705SXin Li 
220*67e74705SXin Li     /// \brief Whether we have already exited this scope.
221*67e74705SXin Li     bool Exited;
222*67e74705SXin Li 
223*67e74705SXin Li     /// \brief Whether to combine this scope with the outer scope, such that
224*67e74705SXin Li     /// lookup will search our outer scope.
225*67e74705SXin Li     bool CombineWithOuterScope;
226*67e74705SXin Li 
227*67e74705SXin Li     /// \brief If non-NULL, the template parameter pack that has been
228*67e74705SXin Li     /// partially substituted per C++0x [temp.arg.explicit]p9.
229*67e74705SXin Li     NamedDecl *PartiallySubstitutedPack;
230*67e74705SXin Li 
231*67e74705SXin Li     /// \brief If \c PartiallySubstitutedPack is non-null, the set of
232*67e74705SXin Li     /// explicitly-specified template arguments in that pack.
233*67e74705SXin Li     const TemplateArgument *ArgsInPartiallySubstitutedPack;
234*67e74705SXin Li 
235*67e74705SXin Li     /// \brief If \c PartiallySubstitutedPack, the number of
236*67e74705SXin Li     /// explicitly-specified template arguments in
237*67e74705SXin Li     /// ArgsInPartiallySubstitutedPack.
238*67e74705SXin Li     unsigned NumArgsInPartiallySubstitutedPack;
239*67e74705SXin Li 
240*67e74705SXin Li     // This class is non-copyable
241*67e74705SXin Li     LocalInstantiationScope(
242*67e74705SXin Li       const LocalInstantiationScope &) = delete;
243*67e74705SXin Li     void operator=(const LocalInstantiationScope &) = delete;
244*67e74705SXin Li 
245*67e74705SXin Li   public:
246*67e74705SXin Li     LocalInstantiationScope(Sema &SemaRef, bool CombineWithOuterScope = false)
SemaRef(SemaRef)247*67e74705SXin Li       : SemaRef(SemaRef), Outer(SemaRef.CurrentInstantiationScope),
248*67e74705SXin Li         Exited(false), CombineWithOuterScope(CombineWithOuterScope),
249*67e74705SXin Li         PartiallySubstitutedPack(nullptr)
250*67e74705SXin Li     {
251*67e74705SXin Li       SemaRef.CurrentInstantiationScope = this;
252*67e74705SXin Li     }
253*67e74705SXin Li 
~LocalInstantiationScope()254*67e74705SXin Li     ~LocalInstantiationScope() {
255*67e74705SXin Li       Exit();
256*67e74705SXin Li     }
257*67e74705SXin Li 
getSema()258*67e74705SXin Li     const Sema &getSema() const { return SemaRef; }
259*67e74705SXin Li 
260*67e74705SXin Li     /// \brief Exit this local instantiation scope early.
Exit()261*67e74705SXin Li     void Exit() {
262*67e74705SXin Li       if (Exited)
263*67e74705SXin Li         return;
264*67e74705SXin Li 
265*67e74705SXin Li       for (unsigned I = 0, N = ArgumentPacks.size(); I != N; ++I)
266*67e74705SXin Li         delete ArgumentPacks[I];
267*67e74705SXin Li 
268*67e74705SXin Li       SemaRef.CurrentInstantiationScope = Outer;
269*67e74705SXin Li       Exited = true;
270*67e74705SXin Li     }
271*67e74705SXin Li 
272*67e74705SXin Li     /// \brief Clone this scope, and all outer scopes, down to the given
273*67e74705SXin Li     /// outermost scope.
cloneScopes(LocalInstantiationScope * Outermost)274*67e74705SXin Li     LocalInstantiationScope *cloneScopes(LocalInstantiationScope *Outermost) {
275*67e74705SXin Li       if (this == Outermost) return this;
276*67e74705SXin Li 
277*67e74705SXin Li       // Save the current scope from SemaRef since the LocalInstantiationScope
278*67e74705SXin Li       // will overwrite it on construction
279*67e74705SXin Li       LocalInstantiationScope *oldScope = SemaRef.CurrentInstantiationScope;
280*67e74705SXin Li 
281*67e74705SXin Li       LocalInstantiationScope *newScope =
282*67e74705SXin Li         new LocalInstantiationScope(SemaRef, CombineWithOuterScope);
283*67e74705SXin Li 
284*67e74705SXin Li       newScope->Outer = nullptr;
285*67e74705SXin Li       if (Outer)
286*67e74705SXin Li         newScope->Outer = Outer->cloneScopes(Outermost);
287*67e74705SXin Li 
288*67e74705SXin Li       newScope->PartiallySubstitutedPack = PartiallySubstitutedPack;
289*67e74705SXin Li       newScope->ArgsInPartiallySubstitutedPack = ArgsInPartiallySubstitutedPack;
290*67e74705SXin Li       newScope->NumArgsInPartiallySubstitutedPack =
291*67e74705SXin Li         NumArgsInPartiallySubstitutedPack;
292*67e74705SXin Li 
293*67e74705SXin Li       for (LocalDeclsMap::iterator I = LocalDecls.begin(), E = LocalDecls.end();
294*67e74705SXin Li            I != E; ++I) {
295*67e74705SXin Li         const Decl *D = I->first;
296*67e74705SXin Li         llvm::PointerUnion<Decl *, DeclArgumentPack *> &Stored =
297*67e74705SXin Li           newScope->LocalDecls[D];
298*67e74705SXin Li         if (I->second.is<Decl *>()) {
299*67e74705SXin Li           Stored = I->second.get<Decl *>();
300*67e74705SXin Li         } else {
301*67e74705SXin Li           DeclArgumentPack *OldPack = I->second.get<DeclArgumentPack *>();
302*67e74705SXin Li           DeclArgumentPack *NewPack = new DeclArgumentPack(*OldPack);
303*67e74705SXin Li           Stored = NewPack;
304*67e74705SXin Li           newScope->ArgumentPacks.push_back(NewPack);
305*67e74705SXin Li         }
306*67e74705SXin Li       }
307*67e74705SXin Li       // Restore the saved scope to SemaRef
308*67e74705SXin Li       SemaRef.CurrentInstantiationScope = oldScope;
309*67e74705SXin Li       return newScope;
310*67e74705SXin Li     }
311*67e74705SXin Li 
312*67e74705SXin Li     /// \brief deletes the given scope, and all otuer scopes, down to the
313*67e74705SXin Li     /// given outermost scope.
deleteScopes(LocalInstantiationScope * Scope,LocalInstantiationScope * Outermost)314*67e74705SXin Li     static void deleteScopes(LocalInstantiationScope *Scope,
315*67e74705SXin Li                              LocalInstantiationScope *Outermost) {
316*67e74705SXin Li       while (Scope && Scope != Outermost) {
317*67e74705SXin Li         LocalInstantiationScope *Out = Scope->Outer;
318*67e74705SXin Li         delete Scope;
319*67e74705SXin Li         Scope = Out;
320*67e74705SXin Li       }
321*67e74705SXin Li     }
322*67e74705SXin Li 
323*67e74705SXin Li     /// \brief Find the instantiation of the declaration D within the current
324*67e74705SXin Li     /// instantiation scope.
325*67e74705SXin Li     ///
326*67e74705SXin Li     /// \param D The declaration whose instantiation we are searching for.
327*67e74705SXin Li     ///
328*67e74705SXin Li     /// \returns A pointer to the declaration or argument pack of declarations
329*67e74705SXin Li     /// to which the declaration \c D is instantiated, if found. Otherwise,
330*67e74705SXin Li     /// returns NULL.
331*67e74705SXin Li     llvm::PointerUnion<Decl *, DeclArgumentPack *> *
332*67e74705SXin Li     findInstantiationOf(const Decl *D);
333*67e74705SXin Li 
334*67e74705SXin Li     void InstantiatedLocal(const Decl *D, Decl *Inst);
335*67e74705SXin Li     void InstantiatedLocalPackArg(const Decl *D, ParmVarDecl *Inst);
336*67e74705SXin Li     void MakeInstantiatedLocalArgPack(const Decl *D);
337*67e74705SXin Li 
338*67e74705SXin Li     /// \brief Note that the given parameter pack has been partially substituted
339*67e74705SXin Li     /// via explicit specification of template arguments
340*67e74705SXin Li     /// (C++0x [temp.arg.explicit]p9).
341*67e74705SXin Li     ///
342*67e74705SXin Li     /// \param Pack The parameter pack, which will always be a template
343*67e74705SXin Li     /// parameter pack.
344*67e74705SXin Li     ///
345*67e74705SXin Li     /// \param ExplicitArgs The explicitly-specified template arguments provided
346*67e74705SXin Li     /// for this parameter pack.
347*67e74705SXin Li     ///
348*67e74705SXin Li     /// \param NumExplicitArgs The number of explicitly-specified template
349*67e74705SXin Li     /// arguments provided for this parameter pack.
350*67e74705SXin Li     void SetPartiallySubstitutedPack(NamedDecl *Pack,
351*67e74705SXin Li                                      const TemplateArgument *ExplicitArgs,
352*67e74705SXin Li                                      unsigned NumExplicitArgs);
353*67e74705SXin Li 
354*67e74705SXin Li     /// \brief Reset the partially-substituted pack when it is no longer of
355*67e74705SXin Li     /// interest.
ResetPartiallySubstitutedPack()356*67e74705SXin Li     void ResetPartiallySubstitutedPack() {
357*67e74705SXin Li       assert(PartiallySubstitutedPack && "No partially-substituted pack");
358*67e74705SXin Li       PartiallySubstitutedPack = nullptr;
359*67e74705SXin Li       ArgsInPartiallySubstitutedPack = nullptr;
360*67e74705SXin Li       NumArgsInPartiallySubstitutedPack = 0;
361*67e74705SXin Li     }
362*67e74705SXin Li 
363*67e74705SXin Li     /// \brief Retrieve the partially-substitued template parameter pack.
364*67e74705SXin Li     ///
365*67e74705SXin Li     /// If there is no partially-substituted parameter pack, returns NULL.
366*67e74705SXin Li     NamedDecl *
367*67e74705SXin Li     getPartiallySubstitutedPack(const TemplateArgument **ExplicitArgs = nullptr,
368*67e74705SXin Li                                 unsigned *NumExplicitArgs = nullptr) const;
369*67e74705SXin Li   };
370*67e74705SXin Li 
371*67e74705SXin Li   class TemplateDeclInstantiator
372*67e74705SXin Li     : public DeclVisitor<TemplateDeclInstantiator, Decl *>
373*67e74705SXin Li   {
374*67e74705SXin Li     Sema &SemaRef;
375*67e74705SXin Li     Sema::ArgumentPackSubstitutionIndexRAII SubstIndex;
376*67e74705SXin Li     DeclContext *Owner;
377*67e74705SXin Li     const MultiLevelTemplateArgumentList &TemplateArgs;
378*67e74705SXin Li     Sema::LateInstantiatedAttrVec* LateAttrs;
379*67e74705SXin Li     LocalInstantiationScope *StartingScope;
380*67e74705SXin Li 
381*67e74705SXin Li     /// \brief A list of out-of-line class template partial
382*67e74705SXin Li     /// specializations that will need to be instantiated after the
383*67e74705SXin Li     /// enclosing class's instantiation is complete.
384*67e74705SXin Li     SmallVector<std::pair<ClassTemplateDecl *,
385*67e74705SXin Li                                 ClassTemplatePartialSpecializationDecl *>, 4>
386*67e74705SXin Li       OutOfLinePartialSpecs;
387*67e74705SXin Li 
388*67e74705SXin Li     /// \brief A list of out-of-line variable template partial
389*67e74705SXin Li     /// specializations that will need to be instantiated after the
390*67e74705SXin Li     /// enclosing variable's instantiation is complete.
391*67e74705SXin Li     /// FIXME: Verify that this is needed.
392*67e74705SXin Li     SmallVector<
393*67e74705SXin Li         std::pair<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>, 4>
394*67e74705SXin Li     OutOfLineVarPartialSpecs;
395*67e74705SXin Li 
396*67e74705SXin Li   public:
TemplateDeclInstantiator(Sema & SemaRef,DeclContext * Owner,const MultiLevelTemplateArgumentList & TemplateArgs)397*67e74705SXin Li     TemplateDeclInstantiator(Sema &SemaRef, DeclContext *Owner,
398*67e74705SXin Li                              const MultiLevelTemplateArgumentList &TemplateArgs)
399*67e74705SXin Li       : SemaRef(SemaRef),
400*67e74705SXin Li         SubstIndex(SemaRef, SemaRef.ArgumentPackSubstitutionIndex),
401*67e74705SXin Li         Owner(Owner), TemplateArgs(TemplateArgs), LateAttrs(nullptr),
402*67e74705SXin Li         StartingScope(nullptr) {}
403*67e74705SXin Li 
404*67e74705SXin Li // Define all the decl visitors using DeclNodes.inc
405*67e74705SXin Li #define DECL(DERIVED, BASE) \
406*67e74705SXin Li     Decl *Visit ## DERIVED ## Decl(DERIVED ## Decl *D);
407*67e74705SXin Li #define ABSTRACT_DECL(DECL)
408*67e74705SXin Li 
409*67e74705SXin Li // Decls which never appear inside a class or function.
410*67e74705SXin Li #define OBJCCONTAINER(DERIVED, BASE)
411*67e74705SXin Li #define FILESCOPEASM(DERIVED, BASE)
412*67e74705SXin Li #define IMPORT(DERIVED, BASE)
413*67e74705SXin Li #define LINKAGESPEC(DERIVED, BASE)
414*67e74705SXin Li #define OBJCCOMPATIBLEALIAS(DERIVED, BASE)
415*67e74705SXin Li #define OBJCMETHOD(DERIVED, BASE)
416*67e74705SXin Li #define OBJCTYPEPARAM(DERIVED, BASE)
417*67e74705SXin Li #define OBJCIVAR(DERIVED, BASE)
418*67e74705SXin Li #define OBJCPROPERTY(DERIVED, BASE)
419*67e74705SXin Li #define OBJCPROPERTYIMPL(DERIVED, BASE)
420*67e74705SXin Li #define EMPTY(DERIVED, BASE)
421*67e74705SXin Li 
422*67e74705SXin Li // Decls which use special-case instantiation code.
423*67e74705SXin Li #define BLOCK(DERIVED, BASE)
424*67e74705SXin Li #define CAPTURED(DERIVED, BASE)
425*67e74705SXin Li #define IMPLICITPARAM(DERIVED, BASE)
426*67e74705SXin Li 
427*67e74705SXin Li #include "clang/AST/DeclNodes.inc"
428*67e74705SXin Li 
429*67e74705SXin Li     // A few supplemental visitor functions.
430*67e74705SXin Li     Decl *VisitCXXMethodDecl(CXXMethodDecl *D,
431*67e74705SXin Li                              TemplateParameterList *TemplateParams,
432*67e74705SXin Li                              bool IsClassScopeSpecialization = false);
433*67e74705SXin Li     Decl *VisitFunctionDecl(FunctionDecl *D,
434*67e74705SXin Li                             TemplateParameterList *TemplateParams);
435*67e74705SXin Li     Decl *VisitDecl(Decl *D);
436*67e74705SXin Li     Decl *VisitVarDecl(VarDecl *D, bool InstantiatingVarTemplate);
437*67e74705SXin Li 
438*67e74705SXin Li     // Enable late instantiation of attributes.  Late instantiated attributes
439*67e74705SXin Li     // will be stored in LA.
enableLateAttributeInstantiation(Sema::LateInstantiatedAttrVec * LA)440*67e74705SXin Li     void enableLateAttributeInstantiation(Sema::LateInstantiatedAttrVec *LA) {
441*67e74705SXin Li       LateAttrs = LA;
442*67e74705SXin Li       StartingScope = SemaRef.CurrentInstantiationScope;
443*67e74705SXin Li     }
444*67e74705SXin Li 
445*67e74705SXin Li     // Disable late instantiation of attributes.
disableLateAttributeInstantiation()446*67e74705SXin Li     void disableLateAttributeInstantiation() {
447*67e74705SXin Li       LateAttrs = nullptr;
448*67e74705SXin Li       StartingScope = nullptr;
449*67e74705SXin Li     }
450*67e74705SXin Li 
getStartingScope()451*67e74705SXin Li     LocalInstantiationScope *getStartingScope() const { return StartingScope; }
452*67e74705SXin Li 
453*67e74705SXin Li     typedef
454*67e74705SXin Li       SmallVectorImpl<std::pair<ClassTemplateDecl *,
455*67e74705SXin Li                                      ClassTemplatePartialSpecializationDecl *> >
456*67e74705SXin Li         ::iterator
457*67e74705SXin Li       delayed_partial_spec_iterator;
458*67e74705SXin Li 
459*67e74705SXin Li     typedef SmallVectorImpl<std::pair<
460*67e74705SXin Li         VarTemplateDecl *, VarTemplatePartialSpecializationDecl *> >::iterator
461*67e74705SXin Li     delayed_var_partial_spec_iterator;
462*67e74705SXin Li 
463*67e74705SXin Li     /// \brief Return an iterator to the beginning of the set of
464*67e74705SXin Li     /// "delayed" partial specializations, which must be passed to
465*67e74705SXin Li     /// InstantiateClassTemplatePartialSpecialization once the class
466*67e74705SXin Li     /// definition has been completed.
delayed_partial_spec_begin()467*67e74705SXin Li     delayed_partial_spec_iterator delayed_partial_spec_begin() {
468*67e74705SXin Li       return OutOfLinePartialSpecs.begin();
469*67e74705SXin Li     }
470*67e74705SXin Li 
delayed_var_partial_spec_begin()471*67e74705SXin Li     delayed_var_partial_spec_iterator delayed_var_partial_spec_begin() {
472*67e74705SXin Li       return OutOfLineVarPartialSpecs.begin();
473*67e74705SXin Li     }
474*67e74705SXin Li 
475*67e74705SXin Li     /// \brief Return an iterator to the end of the set of
476*67e74705SXin Li     /// "delayed" partial specializations, which must be passed to
477*67e74705SXin Li     /// InstantiateClassTemplatePartialSpecialization once the class
478*67e74705SXin Li     /// definition has been completed.
delayed_partial_spec_end()479*67e74705SXin Li     delayed_partial_spec_iterator delayed_partial_spec_end() {
480*67e74705SXin Li       return OutOfLinePartialSpecs.end();
481*67e74705SXin Li     }
482*67e74705SXin Li 
delayed_var_partial_spec_end()483*67e74705SXin Li     delayed_var_partial_spec_iterator delayed_var_partial_spec_end() {
484*67e74705SXin Li       return OutOfLineVarPartialSpecs.end();
485*67e74705SXin Li     }
486*67e74705SXin Li 
487*67e74705SXin Li     // Helper functions for instantiating methods.
488*67e74705SXin Li     TypeSourceInfo *SubstFunctionType(FunctionDecl *D,
489*67e74705SXin Li                              SmallVectorImpl<ParmVarDecl *> &Params);
490*67e74705SXin Li     bool InitFunctionInstantiation(FunctionDecl *New, FunctionDecl *Tmpl);
491*67e74705SXin Li     bool InitMethodInstantiation(CXXMethodDecl *New, CXXMethodDecl *Tmpl);
492*67e74705SXin Li 
493*67e74705SXin Li     TemplateParameterList *
494*67e74705SXin Li       SubstTemplateParams(TemplateParameterList *List);
495*67e74705SXin Li 
496*67e74705SXin Li     bool SubstQualifier(const DeclaratorDecl *OldDecl,
497*67e74705SXin Li                         DeclaratorDecl *NewDecl);
498*67e74705SXin Li     bool SubstQualifier(const TagDecl *OldDecl,
499*67e74705SXin Li                         TagDecl *NewDecl);
500*67e74705SXin Li 
501*67e74705SXin Li     Decl *VisitVarTemplateSpecializationDecl(
502*67e74705SXin Li         VarTemplateDecl *VarTemplate, VarDecl *FromVar, void *InsertPos,
503*67e74705SXin Li         const TemplateArgumentListInfo &TemplateArgsInfo,
504*67e74705SXin Li         ArrayRef<TemplateArgument> Converted);
505*67e74705SXin Li 
506*67e74705SXin Li     Decl *InstantiateTypedefNameDecl(TypedefNameDecl *D, bool IsTypeAlias);
507*67e74705SXin Li     ClassTemplatePartialSpecializationDecl *
508*67e74705SXin Li     InstantiateClassTemplatePartialSpecialization(
509*67e74705SXin Li                                               ClassTemplateDecl *ClassTemplate,
510*67e74705SXin Li                            ClassTemplatePartialSpecializationDecl *PartialSpec);
511*67e74705SXin Li     VarTemplatePartialSpecializationDecl *
512*67e74705SXin Li     InstantiateVarTemplatePartialSpecialization(
513*67e74705SXin Li         VarTemplateDecl *VarTemplate,
514*67e74705SXin Li         VarTemplatePartialSpecializationDecl *PartialSpec);
515*67e74705SXin Li     void InstantiateEnumDefinition(EnumDecl *Enum, EnumDecl *Pattern);
516*67e74705SXin Li   };
517*67e74705SXin Li }
518*67e74705SXin Li 
519*67e74705SXin Li #endif // LLVM_CLANG_SEMA_TEMPLATE_H
520