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"
17249423Sdim#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 {
43251662Sdim    /// \brief The template argument list at a certain template depth
44251662Sdim    typedef ArrayRef<TemplateArgument> ArgList;
45251662Sdim
46212795Sdim    /// \brief The template argument lists, stored from the innermost template
47212795Sdim    /// argument list (first) to the outermost template argument list (last).
48226633Sdim    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());
67251662Sdim      assert(Index < TemplateArgumentLists[getNumLevels() - Depth - 1].size());
68251662Sdim      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
78251662Sdim      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());
88251662Sdim      assert(Index < TemplateArgumentLists[getNumLevels() - Depth - 1].size());
89218893Sdim      const_cast<TemplateArgument&>(
90251662Sdim                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) {
97251662Sdim      addOuterTemplateArguments(ArgList(TemplateArgs->data(),
98251662Sdim                                        TemplateArgs->size()));
99212795Sdim    }
100251662Sdim
101251662Sdim    /// \brief Add a new outmost level to the multi-level template argument
102251662Sdim    /// list.
103251662Sdim    void addOuterTemplateArguments(ArgList Args) {
104251662Sdim      TemplateArgumentLists.push_back(Args);
105251662Sdim    }
106251662Sdim
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.
154239462Sdim    DeducedTemplateArgument(ASTContext &Ctx,
155239462Sdim                            const llvm::APSInt &Value,
156212795Sdim                            QualType ValueType,
157212795Sdim                            bool DeducedFromArrayBound)
158239462Sdim      : 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.
181226633Sdim    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
188251662Sdim    typedef llvm::SmallDenseMap<
189251662Sdim        const Decl *, llvm::PointerUnion<Decl *, DeclArgumentPack *>, 4>
190251662Sdim    LocalDeclsMap;
191251662Sdim
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.
213226633Sdim    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
241243830Sdim    LocalInstantiationScope(
242243830Sdim      const LocalInstantiationScope &) LLVM_DELETED_FUNCTION;
243243830Sdim    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
272234353Sdim    /// \brief Clone this scope, and all outer scopes, down to the given
273234353Sdim    /// outermost scope.
274234353Sdim    LocalInstantiationScope *cloneScopes(LocalInstantiationScope *Outermost) {
275234353Sdim      if (this == Outermost) return this;
276234353Sdim      LocalInstantiationScope *newScope =
277234353Sdim        new LocalInstantiationScope(SemaRef, CombineWithOuterScope);
278234353Sdim
279234353Sdim      newScope->Outer = 0;
280234353Sdim      if (Outer)
281234353Sdim        newScope->Outer = Outer->cloneScopes(Outermost);
282234353Sdim
283234353Sdim      newScope->PartiallySubstitutedPack = PartiallySubstitutedPack;
284234353Sdim      newScope->ArgsInPartiallySubstitutedPack = ArgsInPartiallySubstitutedPack;
285234353Sdim      newScope->NumArgsInPartiallySubstitutedPack =
286234353Sdim        NumArgsInPartiallySubstitutedPack;
287234353Sdim
288234353Sdim      for (LocalDeclsMap::iterator I = LocalDecls.begin(), E = LocalDecls.end();
289234353Sdim           I != E; ++I) {
290234353Sdim        const Decl *D = I->first;
291234353Sdim        llvm::PointerUnion<Decl *, DeclArgumentPack *> &Stored =
292234353Sdim          newScope->LocalDecls[D];
293234353Sdim        if (I->second.is<Decl *>()) {
294234353Sdim          Stored = I->second.get<Decl *>();
295234353Sdim        } else {
296234353Sdim          DeclArgumentPack *OldPack = I->second.get<DeclArgumentPack *>();
297234353Sdim          DeclArgumentPack *NewPack = new DeclArgumentPack(*OldPack);
298234353Sdim          Stored = NewPack;
299234353Sdim          newScope->ArgumentPacks.push_back(NewPack);
300234353Sdim        }
301234353Sdim      }
302234353Sdim      return newScope;
303234353Sdim    }
304234353Sdim
305234353Sdim    /// \brief deletes the given scope, and all otuer scopes, down to the
306234353Sdim    /// given outermost scope.
307234353Sdim    static void deleteScopes(LocalInstantiationScope *Scope,
308234353Sdim                             LocalInstantiationScope *Outermost) {
309234353Sdim      while (Scope && Scope != Outermost) {
310234353Sdim        LocalInstantiationScope *Out = Scope->Outer;
311234353Sdim        delete Scope;
312234353Sdim        Scope = Out;
313234353Sdim      }
314234353Sdim    }
315234353Sdim
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);
346249423Sdim
347249423Sdim    /// \brief Reset the partially-substituted pack when it is no longer of
348249423Sdim    /// interest.
349249423Sdim    void ResetPartiallySubstitutedPack() {
350249423Sdim      assert(PartiallySubstitutedPack && "No partially-substituted pack");
351249423Sdim      PartiallySubstitutedPack = 0;
352249423Sdim      ArgsInPartiallySubstitutedPack = 0;
353249423Sdim      NumArgsInPartiallySubstitutedPack = 0;
354249423Sdim    }
355249423Sdim
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;
371234353Sdim    Sema::LateInstantiatedAttrVec* LateAttrs;
372234353Sdim    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.
377226633Sdim    SmallVector<std::pair<ClassTemplateDecl *,
378218893Sdim                                ClassTemplatePartialSpecializationDecl *>, 4>
379218893Sdim      OutOfLinePartialSpecs;
380218893Sdim
381263508Sdim    /// \brief A list of out-of-line variable template partial
382263508Sdim    /// specializations that will need to be instantiated after the
383263508Sdim    /// enclosing variable's instantiation is complete.
384263508Sdim    /// FIXME: Verify that this is needed.
385263508Sdim    SmallVector<
386263508Sdim        std::pair<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>, 4>
387263508Sdim    OutOfLineVarPartialSpecs;
388263508Sdim
389218893Sdim  public:
390218893Sdim    TemplateDeclInstantiator(Sema &SemaRef, DeclContext *Owner,
391218893Sdim                             const MultiLevelTemplateArgumentList &TemplateArgs)
392239462Sdim      : SemaRef(SemaRef),
393239462Sdim        SubstIndex(SemaRef, SemaRef.ArgumentPackSubstitutionIndex),
394239462Sdim        Owner(Owner), TemplateArgs(TemplateArgs), LateAttrs(0), StartingScope(0)
395239462Sdim    { }
396218893Sdim
397263508Sdim// Define all the decl visitors using DeclNodes.inc
398263508Sdim#define DECL(DERIVED, BASE) \
399263508Sdim    Decl *Visit ## DERIVED ## Decl(DERIVED ## Decl *D);
400263508Sdim#define ABSTRACT_DECL(DECL)
401263508Sdim
402263508Sdim// Decls which never appear inside a class or function.
403263508Sdim#define OBJCCONTAINER(DERIVED, BASE)
404263508Sdim#define FILESCOPEASM(DERIVED, BASE)
405263508Sdim#define IMPORT(DERIVED, BASE)
406263508Sdim#define LINKAGESPEC(DERIVED, BASE)
407263508Sdim#define OBJCCOMPATIBLEALIAS(DERIVED, BASE)
408263508Sdim#define OBJCMETHOD(DERIVED, BASE)
409263508Sdim#define OBJCIVAR(DERIVED, BASE)
410263508Sdim#define OBJCPROPERTY(DERIVED, BASE)
411263508Sdim#define OBJCPROPERTYIMPL(DERIVED, BASE)
412263508Sdim#define EMPTY(DERIVED, BASE)
413263508Sdim
414263508Sdim// Decls which use special-case instantiation code.
415263508Sdim#define BLOCK(DERIVED, BASE)
416263508Sdim#define CAPTURED(DERIVED, BASE)
417263508Sdim#define IMPLICITPARAM(DERIVED, BASE)
418263508Sdim
419263508Sdim#include "clang/AST/DeclNodes.inc"
420263508Sdim
421263508Sdim    // A few supplemental visitor functions.
422218893Sdim    Decl *VisitCXXMethodDecl(CXXMethodDecl *D,
423263508Sdim                             TemplateParameterList *TemplateParams,
424226633Sdim                             bool IsClassScopeSpecialization = false);
425263508Sdim    Decl *VisitFunctionDecl(FunctionDecl *D,
426263508Sdim                            TemplateParameterList *TemplateParams);
427263508Sdim    Decl *VisitDecl(Decl *D);
428263508Sdim    Decl *VisitVarDecl(VarDecl *D, bool InstantiatingVarTemplate);
429218893Sdim
430234353Sdim    // Enable late instantiation of attributes.  Late instantiated attributes
431234353Sdim    // will be stored in LA.
432234353Sdim    void enableLateAttributeInstantiation(Sema::LateInstantiatedAttrVec *LA) {
433234353Sdim      LateAttrs = LA;
434234353Sdim      StartingScope = SemaRef.CurrentInstantiationScope;
435234353Sdim    }
436234353Sdim
437234353Sdim    // Disable late instantiation of attributes.
438234353Sdim    void disableLateAttributeInstantiation() {
439234353Sdim      LateAttrs = 0;
440234353Sdim      StartingScope = 0;
441234353Sdim    }
442234353Sdim
443234353Sdim    LocalInstantiationScope *getStartingScope() const { return StartingScope; }
444234353Sdim
445218893Sdim    typedef
446226633Sdim      SmallVectorImpl<std::pair<ClassTemplateDecl *,
447218893Sdim                                     ClassTemplatePartialSpecializationDecl *> >
448218893Sdim        ::iterator
449218893Sdim      delayed_partial_spec_iterator;
450212795Sdim
451263508Sdim    typedef SmallVectorImpl<std::pair<
452263508Sdim        VarTemplateDecl *, VarTemplatePartialSpecializationDecl *> >::iterator
453263508Sdim    delayed_var_partial_spec_iterator;
454263508Sdim
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
463263508Sdim    delayed_var_partial_spec_iterator delayed_var_partial_spec_begin() {
464263508Sdim      return OutOfLineVarPartialSpecs.begin();
465263508Sdim    }
466263508Sdim
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
475263508Sdim    delayed_var_partial_spec_iterator delayed_var_partial_spec_end() {
476263508Sdim      return OutOfLineVarPartialSpecs.end();
477263508Sdim    }
478263508Sdim
479218893Sdim    // Helper functions for instantiating methods.
480218893Sdim    TypeSourceInfo *SubstFunctionType(FunctionDecl *D,
481226633Sdim                             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);
492263508Sdim
493263508Sdim    Decl *VisitVarTemplateSpecializationDecl(
494263508Sdim        VarTemplateDecl *VarTemplate, VarDecl *FromVar, void *InsertPos,
495263508Sdim        const TemplateArgumentListInfo &TemplateArgsInfo,
496263508Sdim        llvm::ArrayRef<TemplateArgument> Converted);
497263508Sdim
498223017Sdim    Decl *InstantiateTypedefNameDecl(TypedefNameDecl *D, bool IsTypeAlias);
499218893Sdim    ClassTemplatePartialSpecializationDecl *
500218893Sdim    InstantiateClassTemplatePartialSpecialization(
501218893Sdim                                              ClassTemplateDecl *ClassTemplate,
502218893Sdim                           ClassTemplatePartialSpecializationDecl *PartialSpec);
503263508Sdim    VarTemplatePartialSpecializationDecl *
504263508Sdim    InstantiateVarTemplatePartialSpecialization(
505263508Sdim        VarTemplateDecl *VarTemplate,
506263508Sdim        VarTemplatePartialSpecializationDecl *PartialSpec);
507234353Sdim    void InstantiateEnumDefinition(EnumDecl *Enum, EnumDecl *Pattern);
508218893Sdim  };
509212795Sdim}
510212795Sdim
511212795Sdim#endif // LLVM_CLANG_SEMA_TEMPLATE_H
512