1212795Sdim//===------- SemaTemplate.h - C++ Templates ---------------------*- C++ -*-===/
2212795Sdim//
3212795Sdim//                     The LLVM Compiler Infrastructure
4212795Sdim//
5212795Sdim// This file is distributed under the University of Illinois Open Source
6212795Sdim// License. See LICENSE.TXT for details.
7212795Sdim//===----------------------------------------------------------------------===/
8212795Sdim//
9212795Sdim//  This file provides types used in the semantic analysis of C++ templates.
10212795Sdim//
11212795Sdim//===----------------------------------------------------------------------===/
12212795Sdim#ifndef LLVM_CLANG_SEMA_TEMPLATE_H
13212795Sdim#define LLVM_CLANG_SEMA_TEMPLATE_H
14212795Sdim
15212795Sdim#include "clang/AST/DeclTemplate.h"
16218893Sdim#include "clang/AST/DeclVisitor.h"
17252723Sdim#include "clang/Sema/Sema.h"
18212795Sdim#include "llvm/ADT/SmallVector.h"
19212795Sdim#include <cassert>
20218893Sdim#include <utility>
21212795Sdim
22212795Sdimnamespace clang {
23212795Sdim  /// \brief Data structure that captures multiple levels of template argument
24212795Sdim  /// lists for use in template instantiation.
25212795Sdim  ///
26212795Sdim  /// Multiple levels of template arguments occur when instantiating the
27212795Sdim  /// definitions of member templates. For example:
28212795Sdim  ///
29212795Sdim  /// \code
30212795Sdim  /// template<typename T>
31212795Sdim  /// struct X {
32212795Sdim  ///   template<T Value>
33212795Sdim  ///   struct Y {
34212795Sdim  ///     void f();
35212795Sdim  ///   };
36212795Sdim  /// };
37212795Sdim  /// \endcode
38212795Sdim  ///
39212795Sdim  /// When instantiating X<int>::Y<17>::f, the multi-level template argument
40212795Sdim  /// list will contain a template argument list (int) at depth 0 and a
41212795Sdim  /// template argument list (17) at depth 1.
42212795Sdim  class MultiLevelTemplateArgumentList {
43252723Sdim    /// \brief The template argument list at a certain template depth
44252723Sdim    typedef ArrayRef<TemplateArgument> ArgList;
45252723Sdim
46212795Sdim    /// \brief The template argument lists, stored from the innermost template
47212795Sdim    /// argument list (first) to the outermost template argument list (last).
48226890Sdim    SmallVector<ArgList, 4> TemplateArgumentLists;
49212795Sdim
50212795Sdim  public:
51212795Sdim    /// \brief Construct an empty set of template argument lists.
52212795Sdim    MultiLevelTemplateArgumentList() { }
53212795Sdim
54212795Sdim    /// \brief Construct a single-level template argument list.
55212795Sdim    explicit
56212795Sdim    MultiLevelTemplateArgumentList(const TemplateArgumentList &TemplateArgs) {
57212795Sdim      addOuterTemplateArguments(&TemplateArgs);
58212795Sdim    }
59212795Sdim
60212795Sdim    /// \brief Determine the number of levels in this template argument
61212795Sdim    /// list.
62212795Sdim    unsigned getNumLevels() const { return TemplateArgumentLists.size(); }
63212795Sdim
64212795Sdim    /// \brief Retrieve the template argument at a given depth and index.
65212795Sdim    const TemplateArgument &operator()(unsigned Depth, unsigned Index) const {
66212795Sdim      assert(Depth < TemplateArgumentLists.size());
67252723Sdim      assert(Index < TemplateArgumentLists[getNumLevels() - Depth - 1].size());
68252723Sdim      return TemplateArgumentLists[getNumLevels() - Depth - 1][Index];
69212795Sdim    }
70212795Sdim
71212795Sdim    /// \brief Determine whether there is a non-NULL template argument at the
72212795Sdim    /// given depth and index.
73212795Sdim    ///
74212795Sdim    /// There must exist a template argument list at the given depth.
75212795Sdim    bool hasTemplateArgument(unsigned Depth, unsigned Index) const {
76212795Sdim      assert(Depth < TemplateArgumentLists.size());
77212795Sdim
78252723Sdim      if (Index >= TemplateArgumentLists[getNumLevels() - Depth - 1].size())
79212795Sdim        return false;
80212795Sdim
81212795Sdim      return !(*this)(Depth, Index).isNull();
82212795Sdim    }
83212795Sdim
84218893Sdim    /// \brief Clear out a specific template argument.
85218893Sdim    void setArgument(unsigned Depth, unsigned Index,
86218893Sdim                     TemplateArgument Arg) {
87218893Sdim      assert(Depth < TemplateArgumentLists.size());
88252723Sdim      assert(Index < TemplateArgumentLists[getNumLevels() - Depth - 1].size());
89218893Sdim      const_cast<TemplateArgument&>(
90252723Sdim                TemplateArgumentLists[getNumLevels() - Depth - 1][Index])
91218893Sdim        = Arg;
92218893Sdim    }
93218893Sdim
94212795Sdim    /// \brief Add a new outermost level to the multi-level template argument
95212795Sdim    /// list.
96212795Sdim    void addOuterTemplateArguments(const TemplateArgumentList *TemplateArgs) {
97252723Sdim      addOuterTemplateArguments(ArgList(TemplateArgs->data(),
98252723Sdim                                        TemplateArgs->size()));
99212795Sdim    }
100252723Sdim
101252723Sdim    /// \brief Add a new outmost level to the multi-level template argument
102252723Sdim    /// list.
103252723Sdim    void addOuterTemplateArguments(ArgList Args) {
104252723Sdim      TemplateArgumentLists.push_back(Args);
105252723Sdim    }
106252723Sdim
107212795Sdim    /// \brief Retrieve the innermost template argument list.
108212795Sdim    const ArgList &getInnermost() const {
109212795Sdim      return TemplateArgumentLists.front();
110212795Sdim    }
111212795Sdim  };
112212795Sdim
113212795Sdim  /// \brief The context in which partial ordering of function templates occurs.
114212795Sdim  enum TPOC {
115212795Sdim    /// \brief Partial ordering of function templates for a function call.
116212795Sdim    TPOC_Call,
117212795Sdim    /// \brief Partial ordering of function templates for a call to a
118212795Sdim    /// conversion function.
119212795Sdim    TPOC_Conversion,
120212795Sdim    /// \brief Partial ordering of function templates in other contexts, e.g.,
121212795Sdim    /// taking the address of a function template or matching a function
122212795Sdim    /// template specialization to a function template.
123212795Sdim    TPOC_Other
124212795Sdim  };
125212795Sdim
126212795Sdim  // This is lame but unavoidable in a world without forward
127212795Sdim  // declarations of enums.  The alternatives are to either pollute
128212795Sdim  // Sema.h (by including this file) or sacrifice type safety (by
129212795Sdim  // making Sema.h declare things as enums).
130212795Sdim  class TemplatePartialOrderingContext {
131212795Sdim    TPOC Value;
132212795Sdim  public:
133212795Sdim    TemplatePartialOrderingContext(TPOC Value) : Value(Value) {}
134212795Sdim    operator TPOC() const { return Value; }
135212795Sdim  };
136212795Sdim
137212795Sdim  /// \brief Captures a template argument whose value has been deduced
138212795Sdim  /// via c++ template argument deduction.
139212795Sdim  class DeducedTemplateArgument : public TemplateArgument {
140212795Sdim    /// \brief For a non-type template argument, whether the value was
141212795Sdim    /// deduced from an array bound.
142212795Sdim    bool DeducedFromArrayBound;
143212795Sdim
144212795Sdim  public:
145212795Sdim    DeducedTemplateArgument()
146212795Sdim      : TemplateArgument(), DeducedFromArrayBound(false) { }
147212795Sdim
148212795Sdim    DeducedTemplateArgument(const TemplateArgument &Arg,
149212795Sdim                            bool DeducedFromArrayBound = false)
150212795Sdim      : TemplateArgument(Arg), DeducedFromArrayBound(DeducedFromArrayBound) { }
151212795Sdim
152212795Sdim    /// \brief Construct an integral non-type template argument that
153218893Sdim    /// has been deduced, possibly from an array bound.
154245431Sdim    DeducedTemplateArgument(ASTContext &Ctx,
155245431Sdim                            const llvm::APSInt &Value,
156212795Sdim                            QualType ValueType,
157212795Sdim                            bool DeducedFromArrayBound)
158245431Sdim      : TemplateArgument(Ctx, Value, ValueType),
159212795Sdim        DeducedFromArrayBound(DeducedFromArrayBound) { }
160212795Sdim
161212795Sdim    /// \brief For a non-type template argument, determine whether the
162212795Sdim    /// template argument was deduced from an array bound.
163212795Sdim    bool wasDeducedFromArrayBound() const { return DeducedFromArrayBound; }
164212795Sdim
165212795Sdim    /// \brief Specify whether the given non-type template argument
166212795Sdim    /// was deduced from an array bound.
167212795Sdim    void setDeducedFromArrayBound(bool Deduced) {
168212795Sdim      DeducedFromArrayBound = Deduced;
169212795Sdim    }
170212795Sdim  };
171212795Sdim
172212795Sdim  /// \brief A stack-allocated class that identifies which local
173212795Sdim  /// variable declaration instantiations are present in this scope.
174212795Sdim  ///
175212795Sdim  /// A new instance of this class type will be created whenever we
176212795Sdim  /// instantiate a new function declaration, which will have its own
177212795Sdim  /// set of parameter declarations.
178212795Sdim  class LocalInstantiationScope {
179218893Sdim  public:
180218893Sdim    /// \brief A set of declarations.
181226890Sdim    typedef SmallVector<Decl *, 4> DeclArgumentPack;
182218893Sdim
183218893Sdim  private:
184212795Sdim    /// \brief Reference to the semantic analysis that is performing
185212795Sdim    /// this template instantiation.
186212795Sdim    Sema &SemaRef;
187212795Sdim
188252723Sdim    typedef llvm::SmallDenseMap<
189252723Sdim        const Decl *, llvm::PointerUnion<Decl *, DeclArgumentPack *>, 4>
190252723Sdim    LocalDeclsMap;
191252723Sdim
192212795Sdim    /// \brief A mapping from local declarations that occur
193212795Sdim    /// within a template to their instantiations.
194212795Sdim    ///
195212795Sdim    /// This mapping is used during instantiation to keep track of,
196212795Sdim    /// e.g., function parameter and variable declarations. For example,
197212795Sdim    /// given:
198212795Sdim    ///
199212795Sdim    /// \code
200212795Sdim    ///   template<typename T> T add(T x, T y) { return x + y; }
201212795Sdim    /// \endcode
202212795Sdim    ///
203212795Sdim    /// when we instantiate add<int>, we will introduce a mapping from
204212795Sdim    /// the ParmVarDecl for 'x' that occurs in the template to the
205212795Sdim    /// instantiated ParmVarDecl for 'x'.
206218893Sdim    ///
207218893Sdim    /// For a parameter pack, the local instantiation scope may contain a
208218893Sdim    /// set of instantiated parameters. This is stored as a DeclArgumentPack
209218893Sdim    /// pointer.
210218893Sdim    LocalDeclsMap LocalDecls;
211212795Sdim
212218893Sdim    /// \brief The set of argument packs we've allocated.
213226890Sdim    SmallVector<DeclArgumentPack *, 1> ArgumentPacks;
214218893Sdim
215212795Sdim    /// \brief The outer scope, which contains local variable
216212795Sdim    /// definitions from some other instantiation (that may not be
217212795Sdim    /// relevant to this particular scope).
218212795Sdim    LocalInstantiationScope *Outer;
219212795Sdim
220212795Sdim    /// \brief Whether we have already exited this scope.
221212795Sdim    bool Exited;
222212795Sdim
223212795Sdim    /// \brief Whether to combine this scope with the outer scope, such that
224212795Sdim    /// lookup will search our outer scope.
225212795Sdim    bool CombineWithOuterScope;
226212795Sdim
227218893Sdim    /// \brief If non-NULL, the template parameter pack that has been
228218893Sdim    /// partially substituted per C++0x [temp.arg.explicit]p9.
229218893Sdim    NamedDecl *PartiallySubstitutedPack;
230218893Sdim
231218893Sdim    /// \brief If \c PartiallySubstitutedPack is non-null, the set of
232218893Sdim    /// explicitly-specified template arguments in that pack.
233218893Sdim    const TemplateArgument *ArgsInPartiallySubstitutedPack;
234218893Sdim
235218893Sdim    /// \brief If \c PartiallySubstitutedPack, the number of
236218893Sdim    /// explicitly-specified template arguments in
237218893Sdim    /// ArgsInPartiallySubstitutedPack.
238218893Sdim    unsigned NumArgsInPartiallySubstitutedPack;
239218893Sdim
240212795Sdim    // This class is non-copyable
241245431Sdim    LocalInstantiationScope(
242245431Sdim      const LocalInstantiationScope &) LLVM_DELETED_FUNCTION;
243245431Sdim    void operator=(const LocalInstantiationScope &) LLVM_DELETED_FUNCTION;
244212795Sdim
245212795Sdim  public:
246212795Sdim    LocalInstantiationScope(Sema &SemaRef, bool CombineWithOuterScope = false)
247212795Sdim      : SemaRef(SemaRef), Outer(SemaRef.CurrentInstantiationScope),
248218893Sdim        Exited(false), CombineWithOuterScope(CombineWithOuterScope),
249218893Sdim        PartiallySubstitutedPack(0)
250212795Sdim    {
251212795Sdim      SemaRef.CurrentInstantiationScope = this;
252212795Sdim    }
253212795Sdim
254212795Sdim    ~LocalInstantiationScope() {
255212795Sdim      Exit();
256212795Sdim    }
257218893Sdim
258218893Sdim    const Sema &getSema() const { return SemaRef; }
259212795Sdim
260212795Sdim    /// \brief Exit this local instantiation scope early.
261212795Sdim    void Exit() {
262212795Sdim      if (Exited)
263212795Sdim        return;
264212795Sdim
265218893Sdim      for (unsigned I = 0, N = ArgumentPacks.size(); I != N; ++I)
266218893Sdim        delete ArgumentPacks[I];
267218893Sdim
268212795Sdim      SemaRef.CurrentInstantiationScope = Outer;
269212795Sdim      Exited = true;
270212795Sdim    }
271212795Sdim
272235633Sdim    /// \brief Clone this scope, and all outer scopes, down to the given
273235633Sdim    /// outermost scope.
274235633Sdim    LocalInstantiationScope *cloneScopes(LocalInstantiationScope *Outermost) {
275235633Sdim      if (this == Outermost) return this;
276235633Sdim      LocalInstantiationScope *newScope =
277235633Sdim        new LocalInstantiationScope(SemaRef, CombineWithOuterScope);
278235633Sdim
279235633Sdim      newScope->Outer = 0;
280235633Sdim      if (Outer)
281235633Sdim        newScope->Outer = Outer->cloneScopes(Outermost);
282235633Sdim
283235633Sdim      newScope->PartiallySubstitutedPack = PartiallySubstitutedPack;
284235633Sdim      newScope->ArgsInPartiallySubstitutedPack = ArgsInPartiallySubstitutedPack;
285235633Sdim      newScope->NumArgsInPartiallySubstitutedPack =
286235633Sdim        NumArgsInPartiallySubstitutedPack;
287235633Sdim
288235633Sdim      for (LocalDeclsMap::iterator I = LocalDecls.begin(), E = LocalDecls.end();
289235633Sdim           I != E; ++I) {
290235633Sdim        const Decl *D = I->first;
291235633Sdim        llvm::PointerUnion<Decl *, DeclArgumentPack *> &Stored =
292235633Sdim          newScope->LocalDecls[D];
293235633Sdim        if (I->second.is<Decl *>()) {
294235633Sdim          Stored = I->second.get<Decl *>();
295235633Sdim        } else {
296235633Sdim          DeclArgumentPack *OldPack = I->second.get<DeclArgumentPack *>();
297235633Sdim          DeclArgumentPack *NewPack = new DeclArgumentPack(*OldPack);
298235633Sdim          Stored = NewPack;
299235633Sdim          newScope->ArgumentPacks.push_back(NewPack);
300235633Sdim        }
301235633Sdim      }
302235633Sdim      return newScope;
303235633Sdim    }
304235633Sdim
305235633Sdim    /// \brief deletes the given scope, and all otuer scopes, down to the
306235633Sdim    /// given outermost scope.
307235633Sdim    static void deleteScopes(LocalInstantiationScope *Scope,
308235633Sdim                             LocalInstantiationScope *Outermost) {
309235633Sdim      while (Scope && Scope != Outermost) {
310235633Sdim        LocalInstantiationScope *Out = Scope->Outer;
311235633Sdim        delete Scope;
312235633Sdim        Scope = Out;
313235633Sdim      }
314235633Sdim    }
315235633Sdim
316218893Sdim    /// \brief Find the instantiation of the declaration D within the current
317218893Sdim    /// instantiation scope.
318218893Sdim    ///
319218893Sdim    /// \param D The declaration whose instantiation we are searching for.
320218893Sdim    ///
321218893Sdim    /// \returns A pointer to the declaration or argument pack of declarations
322218893Sdim    /// to which the declaration \c D is instantiataed, if found. Otherwise,
323218893Sdim    /// returns NULL.
324218893Sdim    llvm::PointerUnion<Decl *, DeclArgumentPack *> *
325218893Sdim    findInstantiationOf(const Decl *D);
326212795Sdim
327218893Sdim    void InstantiatedLocal(const Decl *D, Decl *Inst);
328218893Sdim    void InstantiatedLocalPackArg(const Decl *D, Decl *Inst);
329218893Sdim    void MakeInstantiatedLocalArgPack(const Decl *D);
330218893Sdim
331218893Sdim    /// \brief Note that the given parameter pack has been partially substituted
332218893Sdim    /// via explicit specification of template arguments
333218893Sdim    /// (C++0x [temp.arg.explicit]p9).
334218893Sdim    ///
335218893Sdim    /// \param Pack The parameter pack, which will always be a template
336218893Sdim    /// parameter pack.
337218893Sdim    ///
338218893Sdim    /// \param ExplicitArgs The explicitly-specified template arguments provided
339218893Sdim    /// for this parameter pack.
340218893Sdim    ///
341218893Sdim    /// \param NumExplicitArgs The number of explicitly-specified template
342218893Sdim    /// arguments provided for this parameter pack.
343218893Sdim    void SetPartiallySubstitutedPack(NamedDecl *Pack,
344218893Sdim                                     const TemplateArgument *ExplicitArgs,
345218893Sdim                                     unsigned NumExplicitArgs);
346252723Sdim
347252723Sdim    /// \brief Reset the partially-substituted pack when it is no longer of
348252723Sdim    /// interest.
349252723Sdim    void ResetPartiallySubstitutedPack() {
350252723Sdim      assert(PartiallySubstitutedPack && "No partially-substituted pack");
351252723Sdim      PartiallySubstitutedPack = 0;
352252723Sdim      ArgsInPartiallySubstitutedPack = 0;
353252723Sdim      NumArgsInPartiallySubstitutedPack = 0;
354252723Sdim    }
355252723Sdim
356218893Sdim    /// \brief Retrieve the partially-substitued template parameter pack.
357218893Sdim    ///
358218893Sdim    /// If there is no partially-substituted parameter pack, returns NULL.
359218893Sdim    NamedDecl *getPartiallySubstitutedPack(
360218893Sdim                                      const TemplateArgument **ExplicitArgs = 0,
361218893Sdim                                           unsigned *NumExplicitArgs = 0) const;
362218893Sdim  };
363218893Sdim
364218893Sdim  class TemplateDeclInstantiator
365218893Sdim    : public DeclVisitor<TemplateDeclInstantiator, Decl *>
366218893Sdim  {
367218893Sdim    Sema &SemaRef;
368218893Sdim    Sema::ArgumentPackSubstitutionIndexRAII SubstIndex;
369218893Sdim    DeclContext *Owner;
370218893Sdim    const MultiLevelTemplateArgumentList &TemplateArgs;
371235633Sdim    Sema::LateInstantiatedAttrVec* LateAttrs;
372235633Sdim    LocalInstantiationScope *StartingScope;
373218893Sdim
374218893Sdim    /// \brief A list of out-of-line class template partial
375218893Sdim    /// specializations that will need to be instantiated after the
376218893Sdim    /// enclosing class's instantiation is complete.
377226890Sdim    SmallVector<std::pair<ClassTemplateDecl *,
378218893Sdim                                ClassTemplatePartialSpecializationDecl *>, 4>
379218893Sdim      OutOfLinePartialSpecs;
380218893Sdim
381263509Sdim    /// \brief A list of out-of-line variable template partial
382263509Sdim    /// specializations that will need to be instantiated after the
383263509Sdim    /// enclosing variable's instantiation is complete.
384263509Sdim    /// FIXME: Verify that this is needed.
385263509Sdim    SmallVector<
386263509Sdim        std::pair<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>, 4>
387263509Sdim    OutOfLineVarPartialSpecs;
388263509Sdim
389218893Sdim  public:
390218893Sdim    TemplateDeclInstantiator(Sema &SemaRef, DeclContext *Owner,
391218893Sdim                             const MultiLevelTemplateArgumentList &TemplateArgs)
392245431Sdim      : SemaRef(SemaRef),
393245431Sdim        SubstIndex(SemaRef, SemaRef.ArgumentPackSubstitutionIndex),
394245431Sdim        Owner(Owner), TemplateArgs(TemplateArgs), LateAttrs(0), StartingScope(0)
395245431Sdim    { }
396218893Sdim
397263509Sdim// Define all the decl visitors using DeclNodes.inc
398263509Sdim#define DECL(DERIVED, BASE) \
399263509Sdim    Decl *Visit ## DERIVED ## Decl(DERIVED ## Decl *D);
400263509Sdim#define ABSTRACT_DECL(DECL)
401263509Sdim
402263509Sdim// Decls which never appear inside a class or function.
403263509Sdim#define OBJCCONTAINER(DERIVED, BASE)
404263509Sdim#define FILESCOPEASM(DERIVED, BASE)
405263509Sdim#define IMPORT(DERIVED, BASE)
406263509Sdim#define LINKAGESPEC(DERIVED, BASE)
407263509Sdim#define OBJCCOMPATIBLEALIAS(DERIVED, BASE)
408263509Sdim#define OBJCMETHOD(DERIVED, BASE)
409263509Sdim#define OBJCIVAR(DERIVED, BASE)
410263509Sdim#define OBJCPROPERTY(DERIVED, BASE)
411263509Sdim#define OBJCPROPERTYIMPL(DERIVED, BASE)
412263509Sdim#define EMPTY(DERIVED, BASE)
413263509Sdim
414263509Sdim// Decls which use special-case instantiation code.
415263509Sdim#define BLOCK(DERIVED, BASE)
416263509Sdim#define CAPTURED(DERIVED, BASE)
417263509Sdim#define IMPLICITPARAM(DERIVED, BASE)
418263509Sdim
419263509Sdim#include "clang/AST/DeclNodes.inc"
420263509Sdim
421263509Sdim    // A few supplemental visitor functions.
422218893Sdim    Decl *VisitCXXMethodDecl(CXXMethodDecl *D,
423263509Sdim                             TemplateParameterList *TemplateParams,
424226890Sdim                             bool IsClassScopeSpecialization = false);
425263509Sdim    Decl *VisitFunctionDecl(FunctionDecl *D,
426263509Sdim                            TemplateParameterList *TemplateParams);
427263509Sdim    Decl *VisitDecl(Decl *D);
428263509Sdim    Decl *VisitVarDecl(VarDecl *D, bool InstantiatingVarTemplate);
429218893Sdim
430235633Sdim    // Enable late instantiation of attributes.  Late instantiated attributes
431235633Sdim    // will be stored in LA.
432235633Sdim    void enableLateAttributeInstantiation(Sema::LateInstantiatedAttrVec *LA) {
433235633Sdim      LateAttrs = LA;
434235633Sdim      StartingScope = SemaRef.CurrentInstantiationScope;
435235633Sdim    }
436235633Sdim
437235633Sdim    // Disable late instantiation of attributes.
438235633Sdim    void disableLateAttributeInstantiation() {
439235633Sdim      LateAttrs = 0;
440235633Sdim      StartingScope = 0;
441235633Sdim    }
442235633Sdim
443235633Sdim    LocalInstantiationScope *getStartingScope() const { return StartingScope; }
444235633Sdim
445218893Sdim    typedef
446226890Sdim      SmallVectorImpl<std::pair<ClassTemplateDecl *,
447218893Sdim                                     ClassTemplatePartialSpecializationDecl *> >
448218893Sdim        ::iterator
449218893Sdim      delayed_partial_spec_iterator;
450212795Sdim
451263509Sdim    typedef SmallVectorImpl<std::pair<
452263509Sdim        VarTemplateDecl *, VarTemplatePartialSpecializationDecl *> >::iterator
453263509Sdim    delayed_var_partial_spec_iterator;
454263509Sdim
455218893Sdim    /// \brief Return an iterator to the beginning of the set of
456218893Sdim    /// "delayed" partial specializations, which must be passed to
457218893Sdim    /// InstantiateClassTemplatePartialSpecialization once the class
458218893Sdim    /// definition has been completed.
459218893Sdim    delayed_partial_spec_iterator delayed_partial_spec_begin() {
460218893Sdim      return OutOfLinePartialSpecs.begin();
461212795Sdim    }
462212795Sdim
463263509Sdim    delayed_var_partial_spec_iterator delayed_var_partial_spec_begin() {
464263509Sdim      return OutOfLineVarPartialSpecs.begin();
465263509Sdim    }
466263509Sdim
467218893Sdim    /// \brief Return an iterator to the end of the set of
468218893Sdim    /// "delayed" partial specializations, which must be passed to
469218893Sdim    /// InstantiateClassTemplatePartialSpecialization once the class
470218893Sdim    /// definition has been completed.
471218893Sdim    delayed_partial_spec_iterator delayed_partial_spec_end() {
472218893Sdim      return OutOfLinePartialSpecs.end();
473212795Sdim    }
474212795Sdim
475263509Sdim    delayed_var_partial_spec_iterator delayed_var_partial_spec_end() {
476263509Sdim      return OutOfLineVarPartialSpecs.end();
477263509Sdim    }
478263509Sdim
479218893Sdim    // Helper functions for instantiating methods.
480218893Sdim    TypeSourceInfo *SubstFunctionType(FunctionDecl *D,
481226890Sdim                             SmallVectorImpl<ParmVarDecl *> &Params);
482218893Sdim    bool InitFunctionInstantiation(FunctionDecl *New, FunctionDecl *Tmpl);
483218893Sdim    bool InitMethodInstantiation(CXXMethodDecl *New, CXXMethodDecl *Tmpl);
484218893Sdim
485218893Sdim    TemplateParameterList *
486218893Sdim      SubstTemplateParams(TemplateParameterList *List);
487218893Sdim
488218893Sdim    bool SubstQualifier(const DeclaratorDecl *OldDecl,
489218893Sdim                        DeclaratorDecl *NewDecl);
490218893Sdim    bool SubstQualifier(const TagDecl *OldDecl,
491218893Sdim                        TagDecl *NewDecl);
492263509Sdim
493263509Sdim    Decl *VisitVarTemplateSpecializationDecl(
494263509Sdim        VarTemplateDecl *VarTemplate, VarDecl *FromVar, void *InsertPos,
495263509Sdim        const TemplateArgumentListInfo &TemplateArgsInfo,
496263509Sdim        llvm::ArrayRef<TemplateArgument> Converted);
497263509Sdim
498223017Sdim    Decl *InstantiateTypedefNameDecl(TypedefNameDecl *D, bool IsTypeAlias);
499218893Sdim    ClassTemplatePartialSpecializationDecl *
500218893Sdim    InstantiateClassTemplatePartialSpecialization(
501218893Sdim                                              ClassTemplateDecl *ClassTemplate,
502218893Sdim                           ClassTemplatePartialSpecializationDecl *PartialSpec);
503263509Sdim    VarTemplatePartialSpecializationDecl *
504263509Sdim    InstantiateVarTemplatePartialSpecialization(
505263509Sdim        VarTemplateDecl *VarTemplate,
506263509Sdim        VarTemplatePartialSpecializationDecl *PartialSpec);
507235633Sdim    void InstantiateEnumDefinition(EnumDecl *Enum, EnumDecl *Pattern);
508218893Sdim  };
509212795Sdim}
510212795Sdim
511212795Sdim#endif // LLVM_CLANG_SEMA_TEMPLATE_H
512