blob: b400cb3aba72f643906b4a72b75e078a8b22fad6 [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
41 /// argument list (first) to the outermost template argument list (last)
42 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 Gregord6350ae2009-08-28 20:31:08 +000049 MultiLevelTemplateArgumentList(const TemplateArgumentList &TemplateArgs) {
50 TemplateArgumentLists.push_back(&TemplateArgs);
Douglas Gregord1102432009-08-28 17:37:35 +000051 }
52
53 /// \brief Determine the number of levels in this template argument
54 /// list.
55 unsigned getNumLevels() const { return TemplateArgumentLists.size(); }
56
57 /// \brief Retrieve the template argument at a given depth and index.
58 const TemplateArgument &operator()(unsigned Depth, unsigned Index) const {
59 assert(Depth < TemplateArgumentLists.size());
Douglas Gregord6350ae2009-08-28 20:31:08 +000060 assert(Index < TemplateArgumentLists[getNumLevels() - Depth - 1]->size());
61 return TemplateArgumentLists[getNumLevels() - Depth - 1]->get(Index);
62 }
63
64 /// \brief Determine whether there is a non-NULL template argument at the
65 /// given depth and index.
66 ///
67 /// There must exist a template argument list at the given depth.
68 bool hasTemplateArgument(unsigned Depth, unsigned Index) const {
69 assert(Depth < TemplateArgumentLists.size());
70
71 if (Index >= TemplateArgumentLists[getNumLevels() - Depth - 1]->size())
72 return false;
73
74 return !(*this)(Depth, Index).isNull();
Douglas Gregord1102432009-08-28 17:37:35 +000075 }
76
77 /// \brief Add a new outermost level to the multi-level template argument
78 /// list.
79 void addOuterTemplateArguments(const TemplateArgumentList *TemplateArgs) {
80 TemplateArgumentLists.push_back(TemplateArgs);
81 }
82
Douglas Gregord6350ae2009-08-28 20:31:08 +000083 /// \brief Retrieve the innermost template argument list.
84 const TemplateArgumentList &getInnermost() const {
85 return *TemplateArgumentLists.front();
86 }
Douglas Gregord1102432009-08-28 17:37:35 +000087 };
88}
89
90#endif // LLVM_CLANG_SEMA_TEMPLATE_H