blob: ca59e2735518dd8014c7db88df8917135795f137 [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.
39 struct MultiLevelTemplateArgumentList {
40 /// \brief The template argument lists, stored from the innermost template
Douglas Gregor357bbd02009-08-28 20:50:45 +000041 /// argument list (first) to the outermost template argument list (last).
Douglas Gregord1102432009-08-28 17:37:35 +000042 llvm::SmallVector<const TemplateArgumentList *, 4> TemplateArgumentLists;
43
44 public:
45 /// \brief Construct an empty set of template argument lists.
46 MultiLevelTemplateArgumentList() { }
47
48 /// \brief Construct a single-level template argument list.
Douglas Gregor357bbd02009-08-28 20:50:45 +000049 explicit
Douglas Gregord6350ae2009-08-28 20:31:08 +000050 MultiLevelTemplateArgumentList(const TemplateArgumentList &TemplateArgs) {
51 TemplateArgumentLists.push_back(&TemplateArgs);
Douglas Gregord1102432009-08-28 17:37:35 +000052 }
53
54 /// \brief Determine the number of levels in this template argument
55 /// list.
56 unsigned getNumLevels() const { return TemplateArgumentLists.size(); }
57
58 /// \brief Retrieve the template argument at a given depth and index.
59 const TemplateArgument &operator()(unsigned Depth, unsigned Index) const {
60 assert(Depth < TemplateArgumentLists.size());
Douglas Gregord6350ae2009-08-28 20:31:08 +000061 assert(Index < TemplateArgumentLists[getNumLevels() - Depth - 1]->size());
62 return TemplateArgumentLists[getNumLevels() - Depth - 1]->get(Index);
63 }
64
65 /// \brief Determine whether there is a non-NULL template argument at the
66 /// given depth and index.
67 ///
68 /// There must exist a template argument list at the given depth.
69 bool hasTemplateArgument(unsigned Depth, unsigned Index) const {
70 assert(Depth < TemplateArgumentLists.size());
71
72 if (Index >= TemplateArgumentLists[getNumLevels() - Depth - 1]->size())
73 return false;
74
75 return !(*this)(Depth, Index).isNull();
Douglas Gregord1102432009-08-28 17:37:35 +000076 }
77
78 /// \brief Add a new outermost level to the multi-level template argument
79 /// list.
80 void addOuterTemplateArguments(const TemplateArgumentList *TemplateArgs) {
81 TemplateArgumentLists.push_back(TemplateArgs);
82 }
83
Douglas Gregord6350ae2009-08-28 20:31:08 +000084 /// \brief Retrieve the innermost template argument list.
85 const TemplateArgumentList &getInnermost() const {
86 return *TemplateArgumentLists.front();
87 }
Douglas Gregord1102432009-08-28 17:37:35 +000088 };
Douglas Gregor8a514912009-09-14 18:39:43 +000089
90 /// \brief The context in which partial ordering of function templates occurs.
91 enum TemplatePartialOrderingContext {
92 /// \brief Partial ordering of function templates for a function call.
93 TPOC_Call,
94 /// \brief Partial ordering of function templates for a call to a
95 /// conversion function.
96 TPOC_Conversion,
97 /// \brief Partial ordering of function templates in other contexts, e.g.,
98 /// taking the address of a function template or matching a function
99 /// template specialization to a function template.
100 TPOC_Other
101 };
Douglas Gregor02024a92010-03-28 02:42:43 +0000102
103 /// \brief Captures a template argument whose value has been deduced
104 /// via c++ template argument deduction.
105 class DeducedTemplateArgument : public TemplateArgument {
106 /// \brief For a non-type template argument, whether the value was
107 /// deduced from an array bound.
108 bool DeducedFromArrayBound;
109
110 public:
111 DeducedTemplateArgument()
112 : TemplateArgument(), DeducedFromArrayBound(false) { }
113
114 DeducedTemplateArgument(const TemplateArgument &Arg,
115 bool DeducedFromArrayBound = false)
116 : TemplateArgument(Arg), DeducedFromArrayBound(DeducedFromArrayBound) { }
117
118 /// \brief Construct an integral non-type template argument that
119 /// has been deduced, possible from an array bound.
120 DeducedTemplateArgument(const llvm::APSInt &Value,
121 QualType ValueType,
122 bool DeducedFromArrayBound)
123 : TemplateArgument(Value, ValueType),
124 DeducedFromArrayBound(DeducedFromArrayBound) { }
125
126 /// \brief For a non-type template argument, determine whether the
127 /// template argument was deduced from an array bound.
128 bool wasDeducedFromArrayBound() const { return DeducedFromArrayBound; }
129
130 /// \brief Specify whether the given non-type template argument
131 /// was deduced from an array bound.
132 void setDeducedFromArrayBound(bool Deduced) {
133 DeducedFromArrayBound = Deduced;
134 }
135 };
Douglas Gregord1102432009-08-28 17:37:35 +0000136}
137
138#endif // LLVM_CLANG_SEMA_TEMPLATE_H