blob: 3f814e413db3deb99cebb5d5e14f228c82135386 [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.
49 MultiLevelTemplateArgumentList(const TemplateArgumentList *TemplateArgs) {
50 TemplateArgumentLists.push_back(TemplateArgs);
51 }
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());
60 assert(Index < TemplateArgumentLists[getNumLevels() - Depth]->size());
61 return TemplateArgumentLists[getNumLevels() - Depth]->get(Index);
62 }
63
64 /// \brief Add a new outermost level to the multi-level template argument
65 /// list.
66 void addOuterTemplateArguments(const TemplateArgumentList *TemplateArgs) {
67 TemplateArgumentLists.push_back(TemplateArgs);
68 }
69
70 // Implicit conversion to a single template argument list, to facilitate a
71 // gradual transition to MultiLevelTemplateArgumentLists.
72 operator const TemplateArgumentList &() const {
73 assert(getNumLevels() == 1 &&
74 "Conversion only works with a single level of template arguments");
75 return *TemplateArgumentLists.front();
76 }
77 };
78}
79
80#endif // LLVM_CLANG_SEMA_TEMPLATE_H