blob: b3f46519ab7f2fc17bf5ef5632dee709cd14daf6 [file] [log] [blame]
Douglas Gregord1102432009-08-28 17:37:35 +00001//===------- 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.
Douglas Gregor24bae922010-07-08 18:37:38 +000039 class MultiLevelTemplateArgumentList {
40 public:
41 typedef std::pair<const TemplateArgument *, unsigned> ArgList;
42
43 private:
Douglas Gregord1102432009-08-28 17:37:35 +000044 /// \brief The template argument lists, stored from the innermost template
Douglas Gregor357bbd02009-08-28 20:50:45 +000045 /// argument list (first) to the outermost template argument list (last).
Douglas Gregor24bae922010-07-08 18:37:38 +000046 llvm::SmallVector<ArgList, 4> TemplateArgumentLists;
Douglas Gregord1102432009-08-28 17:37:35 +000047
48 public:
49 /// \brief Construct an empty set of template argument lists.
50 MultiLevelTemplateArgumentList() { }
51
52 /// \brief Construct a single-level template argument list.
Douglas Gregor357bbd02009-08-28 20:50:45 +000053 explicit
Douglas Gregord6350ae2009-08-28 20:31:08 +000054 MultiLevelTemplateArgumentList(const TemplateArgumentList &TemplateArgs) {
Douglas Gregor24bae922010-07-08 18:37:38 +000055 addOuterTemplateArguments(&TemplateArgs);
Douglas Gregord1102432009-08-28 17:37:35 +000056 }
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());
Douglas Gregor24bae922010-07-08 18:37:38 +000065 assert(Index < TemplateArgumentLists[getNumLevels() - Depth - 1].second);
66 return TemplateArgumentLists[getNumLevels() - Depth - 1].first[Index];
Douglas Gregord6350ae2009-08-28 20:31:08 +000067 }
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
Douglas Gregor24bae922010-07-08 18:37:38 +000076 if (Index >= TemplateArgumentLists[getNumLevels() - Depth - 1].second)
Douglas Gregord6350ae2009-08-28 20:31:08 +000077 return false;
78
79 return !(*this)(Depth, Index).isNull();
Douglas Gregord1102432009-08-28 17:37:35 +000080 }
81
82 /// \brief Add a new outermost level to the multi-level template argument
83 /// list.
84 void addOuterTemplateArguments(const TemplateArgumentList *TemplateArgs) {
Douglas Gregor24bae922010-07-08 18:37:38 +000085 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));
Douglas Gregord1102432009-08-28 17:37:35 +000095 }
96
Douglas Gregord6350ae2009-08-28 20:31:08 +000097 /// \brief Retrieve the innermost template argument list.
Douglas Gregor24bae922010-07-08 18:37:38 +000098 const ArgList &getInnermost() const {
99 return TemplateArgumentLists.front();
Douglas Gregord6350ae2009-08-28 20:31:08 +0000100 }
Douglas Gregord1102432009-08-28 17:37:35 +0000101 };
Douglas Gregor8a514912009-09-14 18:39:43 +0000102
103 /// \brief The context in which partial ordering of function templates occurs.
104 enum TemplatePartialOrderingContext {
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 };
Douglas Gregor02024a92010-03-28 02:42:43 +0000115
116 /// \brief Captures a template argument whose value has been deduced
117 /// via c++ template argument deduction.
118 class DeducedTemplateArgument : public TemplateArgument {
119 /// \brief For a non-type template argument, whether the value was
120 /// deduced from an array bound.
121 bool DeducedFromArrayBound;
122
123 public:
124 DeducedTemplateArgument()
125 : TemplateArgument(), DeducedFromArrayBound(false) { }
126
127 DeducedTemplateArgument(const TemplateArgument &Arg,
128 bool DeducedFromArrayBound = false)
129 : TemplateArgument(Arg), DeducedFromArrayBound(DeducedFromArrayBound) { }
130
131 /// \brief Construct an integral non-type template argument that
132 /// has been deduced, possible from an array bound.
133 DeducedTemplateArgument(const llvm::APSInt &Value,
134 QualType ValueType,
135 bool DeducedFromArrayBound)
136 : TemplateArgument(Value, ValueType),
137 DeducedFromArrayBound(DeducedFromArrayBound) { }
138
139 /// \brief For a non-type template argument, determine whether the
140 /// template argument was deduced from an array bound.
141 bool wasDeducedFromArrayBound() const { return DeducedFromArrayBound; }
142
143 /// \brief Specify whether the given non-type template argument
144 /// was deduced from an array bound.
145 void setDeducedFromArrayBound(bool Deduced) {
146 DeducedFromArrayBound = Deduced;
147 }
148 };
Douglas Gregord1102432009-08-28 17:37:35 +0000149}
150
151#endif // LLVM_CLANG_SEMA_TEMPLATE_H