Template.h revision 2a7fb27913999d132cf9e10e03dc5271faa2e9d3
1//===------- SemaTemplate.h - C++ Templates ---------------------*- C++ -*-===/
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//===----------------------------------------------------------------------===/
8//
9//  This file provides types used in the semantic analysis of C++ templates.
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 "llvm/ADT/SmallVector.h"
17#include <cassert>
18
19namespace clang {
20  /// \brief Data structure that captures multiple levels of template argument
21  /// lists for use in template instantiation.
22  ///
23  /// Multiple levels of template arguments occur when instantiating the
24  /// definitions of member templates. For example:
25  ///
26  /// \code
27  /// template<typename T>
28  /// struct X {
29  ///   template<T Value>
30  ///   struct Y {
31  ///     void f();
32  ///   };
33  /// };
34  /// \endcode
35  ///
36  /// When instantiating X<int>::Y<17>::f, the multi-level template argument
37  /// list will contain a template argument list (int) at depth 0 and a
38  /// template argument list (17) at depth 1.
39  class MultiLevelTemplateArgumentList {
40  public:
41    typedef std::pair<const TemplateArgument *, unsigned> ArgList;
42
43  private:
44    /// \brief The template argument lists, stored from the innermost template
45    /// argument list (first) to the outermost template argument list (last).
46    llvm::SmallVector<ArgList, 4> TemplateArgumentLists;
47
48  public:
49    /// \brief Construct an empty set of template argument lists.
50    MultiLevelTemplateArgumentList() { }
51
52    /// \brief Construct a single-level template argument list.
53    explicit
54    MultiLevelTemplateArgumentList(const TemplateArgumentList &TemplateArgs) {
55      addOuterTemplateArguments(&TemplateArgs);
56    }
57
58    /// \brief Determine the number of levels in this template argument
59    /// list.
60    unsigned getNumLevels() const { return TemplateArgumentLists.size(); }
61
62    /// \brief Retrieve the template argument at a given depth and index.
63    const TemplateArgument &operator()(unsigned Depth, unsigned Index) const {
64      assert(Depth < TemplateArgumentLists.size());
65      assert(Index < TemplateArgumentLists[getNumLevels() - Depth - 1].second);
66      return TemplateArgumentLists[getNumLevels() - Depth - 1].first[Index];
67    }
68
69    /// \brief Determine whether there is a non-NULL template argument at the
70    /// given depth and index.
71    ///
72    /// There must exist a template argument list at the given depth.
73    bool hasTemplateArgument(unsigned Depth, unsigned Index) const {
74      assert(Depth < TemplateArgumentLists.size());
75
76      if (Index >= TemplateArgumentLists[getNumLevels() - Depth - 1].second)
77        return false;
78
79      return !(*this)(Depth, Index).isNull();
80    }
81
82    /// \brief Add a new outermost level to the multi-level template argument
83    /// list.
84    void addOuterTemplateArguments(const TemplateArgumentList *TemplateArgs) {
85      TemplateArgumentLists.push_back(
86                                    ArgList(TemplateArgs->getFlatArgumentList(),
87                                            TemplateArgs->flat_size()));
88    }
89
90    /// \brief Add a new outmost level to the multi-level template argument
91    /// list.
92    void addOuterTemplateArguments(const TemplateArgument *Args,
93                                   unsigned NumArgs) {
94      TemplateArgumentLists.push_back(ArgList(Args, NumArgs));
95    }
96
97    /// \brief Retrieve the innermost template argument list.
98    const ArgList &getInnermost() const {
99      return TemplateArgumentLists.front();
100    }
101  };
102
103  /// \brief The context in which partial ordering of function templates occurs.
104  enum TPOC {
105    /// \brief Partial ordering of function templates for a function call.
106    TPOC_Call,
107    /// \brief Partial ordering of function templates for a call to a
108    /// conversion function.
109    TPOC_Conversion,
110    /// \brief Partial ordering of function templates in other contexts, e.g.,
111    /// taking the address of a function template or matching a function
112    /// template specialization to a function template.
113    TPOC_Other
114  };
115
116  // This is lame but unavoidable in a world without forward
117  // declarations of enums.  The alternatives are to either pollute
118  // Sema.h (by including this file) or sacrifice type safety (by
119  // making Sema.h declare things as enums).
120  class TemplatePartialOrderingContext {
121    TPOC Value;
122  public:
123    TemplatePartialOrderingContext(TPOC Value) : Value(Value) {}
124    operator TPOC() const { return Value; }
125  };
126
127  /// \brief Captures a template argument whose value has been deduced
128  /// via c++ template argument deduction.
129  class DeducedTemplateArgument : public TemplateArgument {
130    /// \brief For a non-type template argument, whether the value was
131    /// deduced from an array bound.
132    bool DeducedFromArrayBound;
133
134  public:
135    DeducedTemplateArgument()
136      : TemplateArgument(), DeducedFromArrayBound(false) { }
137
138    DeducedTemplateArgument(const TemplateArgument &Arg,
139                            bool DeducedFromArrayBound = false)
140      : TemplateArgument(Arg), DeducedFromArrayBound(DeducedFromArrayBound) { }
141
142    /// \brief Construct an integral non-type template argument that
143    /// has been deduced, possible from an array bound.
144    DeducedTemplateArgument(const llvm::APSInt &Value,
145                            QualType ValueType,
146                            bool DeducedFromArrayBound)
147      : TemplateArgument(Value, ValueType),
148        DeducedFromArrayBound(DeducedFromArrayBound) { }
149
150    /// \brief For a non-type template argument, determine whether the
151    /// template argument was deduced from an array bound.
152    bool wasDeducedFromArrayBound() const { return DeducedFromArrayBound; }
153
154    /// \brief Specify whether the given non-type template argument
155    /// was deduced from an array bound.
156    void setDeducedFromArrayBound(bool Deduced) {
157      DeducedFromArrayBound = Deduced;
158    }
159  };
160
161  /// \brief A stack-allocated class that identifies which local
162  /// variable declaration instantiations are present in this scope.
163  ///
164  /// A new instance of this class type will be created whenever we
165  /// instantiate a new function declaration, which will have its own
166  /// set of parameter declarations.
167  class LocalInstantiationScope {
168    /// \brief Reference to the semantic analysis that is performing
169    /// this template instantiation.
170    Sema &SemaRef;
171
172    /// \brief A mapping from local declarations that occur
173    /// within a template to their instantiations.
174    ///
175    /// This mapping is used during instantiation to keep track of,
176    /// e.g., function parameter and variable declarations. For example,
177    /// given:
178    ///
179    /// \code
180    ///   template<typename T> T add(T x, T y) { return x + y; }
181    /// \endcode
182    ///
183    /// when we instantiate add<int>, we will introduce a mapping from
184    /// the ParmVarDecl for 'x' that occurs in the template to the
185    /// instantiated ParmVarDecl for 'x'.
186    llvm::DenseMap<const Decl *, Decl *> LocalDecls;
187
188    /// \brief The outer scope, which contains local variable
189    /// definitions from some other instantiation (that may not be
190    /// relevant to this particular scope).
191    LocalInstantiationScope *Outer;
192
193    /// \brief Whether we have already exited this scope.
194    bool Exited;
195
196    /// \brief Whether to combine this scope with the outer scope, such that
197    /// lookup will search our outer scope.
198    bool CombineWithOuterScope;
199
200    // This class is non-copyable
201    LocalInstantiationScope(const LocalInstantiationScope &);
202    LocalInstantiationScope &operator=(const LocalInstantiationScope &);
203
204  public:
205    LocalInstantiationScope(Sema &SemaRef, bool CombineWithOuterScope = false)
206      : SemaRef(SemaRef), Outer(SemaRef.CurrentInstantiationScope),
207        Exited(false), CombineWithOuterScope(CombineWithOuterScope)
208    {
209      SemaRef.CurrentInstantiationScope = this;
210    }
211
212    ~LocalInstantiationScope() {
213      Exit();
214    }
215
216    /// \brief Exit this local instantiation scope early.
217    void Exit() {
218      if (Exited)
219        return;
220
221      SemaRef.CurrentInstantiationScope = Outer;
222      Exited = true;
223    }
224
225    Decl *getInstantiationOf(const Decl *D);
226
227    VarDecl *getInstantiationOf(const VarDecl *Var) {
228      return cast<VarDecl>(getInstantiationOf(cast<Decl>(Var)));
229    }
230
231    ParmVarDecl *getInstantiationOf(const ParmVarDecl *Var) {
232      return cast<ParmVarDecl>(getInstantiationOf(cast<Decl>(Var)));
233    }
234
235    NonTypeTemplateParmDecl *getInstantiationOf(
236                                          const NonTypeTemplateParmDecl *Var) {
237      return cast<NonTypeTemplateParmDecl>(getInstantiationOf(cast<Decl>(Var)));
238    }
239
240    void InstantiatedLocal(const Decl *D, Decl *Inst);
241  };
242}
243
244#endif // LLVM_CLANG_SEMA_TEMPLATE_H
245