DeclTemplate.h revision 5b0f752655cc94b970113235110b56a722eb40d4
1aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor//===-- DeclTemplate.h - Classes for representing C++ templates -*- C++ -*-===//
2aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor//
3aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor//                     The LLVM Compiler Infrastructure
4aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor//
5aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor// This file is distributed under the University of Illinois Open Source
6aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor// License. See LICENSE.TXT for details.
7aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor//
8aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor//===----------------------------------------------------------------------===//
9aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor//
10aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor//  This file defines the C++ template declaration subclasses.
11aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor//
12aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor//===----------------------------------------------------------------------===//
13aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
14aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor#ifndef LLVM_CLANG_AST_DECLTEMPLATE_H
15aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor#define LLVM_CLANG_AST_DECLTEMPLATE_H
16aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
1755f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor#include "clang/AST/DeclCXX.h"
185b0f752655cc94b970113235110b56a722eb40d4Douglas Gregor#include "llvm/ADT/APSInt.h"
193e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor#include "llvm/ADT/FoldingSet.h"
2055f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor
21aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregornamespace clang {
22aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
23aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorclass TemplateParameterList;
24aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorclass TemplateDecl;
25aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorclass FunctionTemplateDecl;
26aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorclass ClassTemplateDecl;
27aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorclass TemplateTypeParmDecl;
28aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorclass NonTypeTemplateParmDecl;
29aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorclass TemplateTemplateParmDecl;
30aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
31aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor/// TemplateParameterList - Stores a list of template parameters for a
32aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor/// TemplateDecl and its derived classes.
33aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorclass TemplateParameterList {
34ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  /// The location of the 'template' keyword.
35ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  SourceLocation TemplateLoc;
36ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor
37ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  /// The locations of the '<' and '>' angle brackets.
38ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  SourceLocation LAngleLoc, RAngleLoc;
39ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor
40ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  /// The number of template parameters in this template
41aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  /// parameter list.
42aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  unsigned NumParams;
43aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
44ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  TemplateParameterList(SourceLocation TemplateLoc, SourceLocation LAngleLoc,
45ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor                        Decl **Params, unsigned NumParams,
46ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor                        SourceLocation RAngleLoc);
47aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
48aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorpublic:
49ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  static TemplateParameterList *Create(ASTContext &C,
50ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor                                       SourceLocation TemplateLoc,
51ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor                                       SourceLocation LAngleLoc,
52ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor                                       Decl **Params,
53ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor                                       unsigned NumParams,
54ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor                                       SourceLocation RAngleLoc);
55aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
56aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  /// iterator - Iterates through the template parameters in this list.
57aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  typedef Decl** iterator;
58aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
59aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  /// const_iterator - Iterates through the template parameters in this list.
60aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  typedef Decl* const* const_iterator;
61aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
62aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  iterator begin() { return reinterpret_cast<Decl **>(this + 1); }
63aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  const_iterator begin() const {
64aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor    return reinterpret_cast<Decl * const *>(this + 1);
65aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  }
66aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  iterator end() { return begin() + NumParams; }
67aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  const_iterator end() const { return begin() + NumParams; }
68aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
69aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  unsigned size() const { return NumParams; }
70ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor
7140808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor  const Decl* getParam(unsigned Idx) const {
7240808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor    assert(Idx < size() && "Template parameter index out-of-range");
7340808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor    return begin()[Idx];
7440808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor  }
7540808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor
7662cb18dd11472965e03374d40bc27d650bc331b6Douglas Gregor  /// \btief Returns the minimum number of arguments needed to form a
7762cb18dd11472965e03374d40bc27d650bc331b6Douglas Gregor  /// template specialization. This may be fewer than the number of
7862cb18dd11472965e03374d40bc27d650bc331b6Douglas Gregor  /// template parameters, if some of the parameters have default
7962cb18dd11472965e03374d40bc27d650bc331b6Douglas Gregor  /// arguments.
8062cb18dd11472965e03374d40bc27d650bc331b6Douglas Gregor  unsigned getMinRequiredArguments() const;
8162cb18dd11472965e03374d40bc27d650bc331b6Douglas Gregor
82ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  SourceLocation getTemplateLoc() const { return TemplateLoc; }
83ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  SourceLocation getLAngleLoc() const { return LAngleLoc; }
84ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  SourceLocation getRAngleLoc() const { return RAngleLoc; }
8562cb18dd11472965e03374d40bc27d650bc331b6Douglas Gregor
8662cb18dd11472965e03374d40bc27d650bc331b6Douglas Gregor  SourceRange getSourceRange() const {
8762cb18dd11472965e03374d40bc27d650bc331b6Douglas Gregor    return SourceRange(TemplateLoc, RAngleLoc);
8862cb18dd11472965e03374d40bc27d650bc331b6Douglas Gregor  }
89aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor};
90aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
91aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor//===----------------------------------------------------------------------===//
92aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor// Kinds of Templates
93aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor//===----------------------------------------------------------------------===//
94aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
95aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor/// TemplateDecl - The base class of all kinds of template declarations (e.g.,
96aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor/// class, function, etc.). The TemplateDecl class stores the list of template
97aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor/// parameters and a reference to the templated scoped declaration: the
98aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor/// underlying AST node.
99aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorclass TemplateDecl : public NamedDecl {
100aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorprotected:
101aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  // This is probably never used.
102aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
103aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor               DeclarationName Name)
104aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor    : NamedDecl(DK, DC, L, Name), TemplatedDecl(0), TemplateParams(0)
105aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  { }
106aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
107aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  // Construct a template decl with the given name and parameters.
108aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  // Used when there is not templated element (tt-params, alias?).
109aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
110aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor               DeclarationName Name, TemplateParameterList *Params)
111aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor    : NamedDecl(DK, DC, L, Name), TemplatedDecl(0), TemplateParams(Params)
112aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  { }
113aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
114aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  // Construct a template decl with name, parameters, and templated element.
115aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
116aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor               DeclarationName Name, TemplateParameterList *Params,
117aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor               NamedDecl *Decl)
118aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor    : NamedDecl(DK, DC, L, Name), TemplatedDecl(Decl),
119aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor      TemplateParams(Params) { }
120aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorpublic:
121aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  ~TemplateDecl();
122aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
123aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  /// Get the list of template parameters
124ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  TemplateParameterList *getTemplateParameters() const {
125aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor    return TemplateParams;
126aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  }
127aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
128aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  /// Get the underlying, templated declaration.
129aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  NamedDecl *getTemplatedDecl() const { return TemplatedDecl; }
130aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
131aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  // Implement isa/cast/dyncast/etc.
132aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  static bool classof(const Decl *D) {
133aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor      return D->getKind() >= TemplateFirst && D->getKind() <= TemplateLast;
134aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  }
135aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  static bool classof(const TemplateDecl *D) { return true; }
136aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  static bool classof(const FunctionTemplateDecl *D) { return true; }
137aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  static bool classof(const ClassTemplateDecl *D) { return true; }
138aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  static bool classof(const TemplateTemplateParmDecl *D) { return true; }
139aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
140aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorprotected:
141aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  NamedDecl *TemplatedDecl;
142aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  TemplateParameterList* TemplateParams;
143aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor};
144aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
145aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor/// Declaration of a template function.
146aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorclass FunctionTemplateDecl : public TemplateDecl {
147aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorprotected:
148aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  FunctionTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
149aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor                       TemplateParameterList *Params, NamedDecl *Decl)
150aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor    : TemplateDecl(FunctionTemplate, DC, L, Name, Params, Decl) { }
151aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorpublic:
152aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  /// Get the underling function declaration of the template.
153aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  FunctionDecl *getTemplatedDecl() const {
154aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor    return static_cast<FunctionDecl*>(TemplatedDecl);
155aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  }
156aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
157aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  /// Create a template function node.
158aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  static FunctionTemplateDecl *Create(ASTContext &C, DeclContext *DC,
159aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor                                      SourceLocation L,
160aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor                                      DeclarationName Name,
161aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor                                      TemplateParameterList *Params,
162aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor                                      NamedDecl *Decl);
163aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
164aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  // Implement isa/cast/dyncast support
165aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  static bool classof(const Decl *D)
166aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  { return D->getKind() == FunctionTemplate; }
167aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  static bool classof(const FunctionTemplateDecl *D)
168aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  { return true; }
169aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor};
170aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
171aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor//===----------------------------------------------------------------------===//
172aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor// Kinds of Template Parameters
173aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor//===----------------------------------------------------------------------===//
174aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
175aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor/// The TemplateParmPosition class defines the position of a template parameter
176aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor/// within a template parameter list. Because template parameter can be listed
177aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor/// sequentially for out-of-line template members, each template parameter is
178aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor/// given a Depth - the nesting of template parameter scopes - and a Position -
179aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor/// the occurrence within the parameter list.
180aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor/// This class is inheritedly privately by different kinds of template
181aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor/// parameters and is not part of the Decl hierarchy. Just a facility.
182aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorclass TemplateParmPosition
183aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor{
184aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorprotected:
185aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  // FIXME: This should probably never be called, but it's here as
186aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  TemplateParmPosition()
187aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor    : Depth(0), Position(0)
188aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  { /* assert(0 && "Cannot create positionless template parameter"); */ }
189aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
190aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  TemplateParmPosition(unsigned D, unsigned P)
191aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor    : Depth(D), Position(P)
192aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  { }
193aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
194aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  // FIXME: These probably don't need to be ints. int:5 for depth, int:8 for
195aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  // position? Maybe?
196aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  unsigned Depth;
197aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  unsigned Position;
198aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
199aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorpublic:
200aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  /// Get the nesting depth of the template parameter.
201aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  unsigned getDepth() const { return Depth; }
202aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
203aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  /// Get the position of the template parameter within its parameter list.
204aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  unsigned getPosition() const { return Position; }
205aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor};
206aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
207aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor/// TemplateTypeParmDecl - Declaration of a template type parameter,
208aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor/// e.g., "T" in
209aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor/// @code
210aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor/// template<typename T> class vector;
211aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor/// @endcode
212fab9d67cebb87be968e7ae31a3b549a5279b5d51Douglas Gregorclass TemplateTypeParmDecl : public TypeDecl {
213fab9d67cebb87be968e7ae31a3b549a5279b5d51Douglas Gregor  /// \brief Whether this template type parameter was declaration with
214fab9d67cebb87be968e7ae31a3b549a5279b5d51Douglas Gregor  /// the 'typename' keyword. If false, it was declared with the
215aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  /// 'class' keyword.
216aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  bool Typename : 1;
217aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
218d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  /// \brief Whether this template type parameter inherited its
219d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  /// default argument.
220d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  bool InheritedDefault : 1;
221d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor
222d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  /// \brief The location of the default argument, if any.
223d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  SourceLocation DefaultArgumentLoc;
224d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor
225d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  /// \brief The default template argument, if any.
226d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  QualType DefaultArgument;
227d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor
228fab9d67cebb87be968e7ae31a3b549a5279b5d51Douglas Gregor  TemplateTypeParmDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
229fab9d67cebb87be968e7ae31a3b549a5279b5d51Douglas Gregor                       bool Typename, QualType Type)
230d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor    : TypeDecl(TemplateTypeParm, DC, L, Id), Typename(Typename),
231d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor      InheritedDefault(false), DefaultArgument() {
232fab9d67cebb87be968e7ae31a3b549a5279b5d51Douglas Gregor    TypeForDecl = Type.getTypePtr();
233fab9d67cebb87be968e7ae31a3b549a5279b5d51Douglas Gregor  }
234fab9d67cebb87be968e7ae31a3b549a5279b5d51Douglas Gregor
235aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorpublic:
236aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  static TemplateTypeParmDecl *Create(ASTContext &C, DeclContext *DC,
237aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor                                      SourceLocation L, unsigned D, unsigned P,
238aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor                                      IdentifierInfo *Id, bool Typename);
239aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
240fab9d67cebb87be968e7ae31a3b549a5279b5d51Douglas Gregor  /// \brief Whether this template type parameter was declared with
241fab9d67cebb87be968e7ae31a3b549a5279b5d51Douglas Gregor  /// the 'typename' keyword. If not, it was declared with the 'class'
242fab9d67cebb87be968e7ae31a3b549a5279b5d51Douglas Gregor  /// keyword.
243aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  bool wasDeclaredWithTypename() const { return Typename; }
244aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
245d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  /// \brief Determine whether this template parameter has a default
246d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  /// argument.
247d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  bool hasDefaultArgument() const { return !DefaultArgument.isNull(); }
248d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor
249d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  /// \brief Retrieve the default argument, if any.
250d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  QualType getDefaultArgument() const { return DefaultArgument; }
251d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor
252d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  /// \brief Retrieve the location of the default argument, if any.
253d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  SourceLocation getDefaultArgumentLoc() const { return DefaultArgumentLoc; }
254d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor
255d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  /// \brief Determines whether the default argument was inherited
256d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  /// from a previous declaration of this template.
257d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  bool defaultArgumentWasInherited() const { return InheritedDefault; }
258d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor
259d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  /// \brief Set the default argument for this template parameter, and
260d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  /// whether that default argument was inherited from another
261d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  /// declaration.
262d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  void setDefaultArgument(QualType DefArg, SourceLocation DefArgLoc,
263d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor                          bool Inherited) {
264d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor    DefaultArgument = DefArg;
265d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor    DefaultArgumentLoc = DefArgLoc;
266d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor    InheritedDefault = Inherited;
267d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  }
268d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor
269aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  // Implement isa/cast/dyncast/etc.
270aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  static bool classof(const Decl *D) {
271aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor    return D->getKind() == TemplateTypeParm;
272aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  }
273aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  static bool classof(const TemplateTypeParmDecl *D) { return true; }
274aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
275aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorprotected:
276fab9d67cebb87be968e7ae31a3b549a5279b5d51Douglas Gregor  /// Serialize this TemplateTypeParmDecl.  Called by Decl::Emit.
277aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  virtual void EmitImpl(llvm::Serializer& S) const;
278aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
279fab9d67cebb87be968e7ae31a3b549a5279b5d51Douglas Gregor  /// Deserialize a TemplateTypeParmDecl.  Called by Decl::Create.
280aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  static TemplateTypeParmDecl* CreateImpl(llvm::Deserializer& D, ASTContext& C);
281aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
282aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  friend Decl* Decl::Create(llvm::Deserializer& D, ASTContext& C);
283aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor};
284aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
285aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor/// NonTypeTemplateParmDecl - Declares a non-type template parameter,
286aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor/// e.g., "Size" in
287aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor/// @code
288aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor/// template<int Size> class array { };
289aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor/// @endcode
290aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorclass NonTypeTemplateParmDecl
291aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  : public VarDecl, protected TemplateParmPosition {
292d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  /// \brief The default template argument, if any.
293d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  Expr *DefaultArgument;
294d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor
295aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  NonTypeTemplateParmDecl(DeclContext *DC, SourceLocation L, unsigned D,
296aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor                          unsigned P, IdentifierInfo *Id, QualType T,
297aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor                          SourceLocation TSSL = SourceLocation())
298aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor    : VarDecl(NonTypeTemplateParm, DC, L, Id, T, VarDecl::None, TSSL),
299d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor      TemplateParmPosition(D, P), DefaultArgument(0)
300d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  { }
301d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor
302aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorpublic:
303aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  static NonTypeTemplateParmDecl *
304aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  Create(ASTContext &C, DeclContext *DC, SourceLocation L, unsigned D,
305aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor         unsigned P, IdentifierInfo *Id, QualType T,
306aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor         SourceLocation TypeSpecStartLoc = SourceLocation());
307aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
308aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  using TemplateParmPosition::getDepth;
309aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  using TemplateParmPosition::getPosition;
310aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
311d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  /// \brief Determine whether this template parameter has a default
312d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  /// argument.
313d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  bool hasDefaultArgument() const { return DefaultArgument; }
314d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor
315d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  /// \brief Retrieve the default argument, if any.
316d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  Expr *getDefaultArgument() const { return DefaultArgument; }
317d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor
318d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  /// \brief Retrieve the location of the default argument, if any.
319d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  SourceLocation getDefaultArgumentLoc() const;
320d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor
321d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  /// \brief Set the default argument for this template parameter.
322d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  void setDefaultArgument(Expr *DefArg) {
323d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor    DefaultArgument = DefArg;
324d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  }
325d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor
326aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  // Implement isa/cast/dyncast/etc.
327aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  static bool classof(const Decl *D) {
328aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor    return D->getKind() == NonTypeTemplateParm;
329aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  }
330aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  static bool classof(const NonTypeTemplateParmDecl *D) { return true; }
331aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
332aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorprotected:
333aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  /// EmitImpl - Serialize this TemplateTypeParmDecl.  Called by Decl::Emit.
334aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  virtual void EmitImpl(llvm::Serializer& S) const;
335aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
336aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  /// CreateImpl - Deserialize a TemplateTypeParmDecl.  Called by Decl::Create.
337aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  static NonTypeTemplateParmDecl* CreateImpl(llvm::Deserializer& D,
338aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor                                             ASTContext& C);
339aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
340aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  friend Decl* Decl::Create(llvm::Deserializer& D, ASTContext& C);
341aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor};
342aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
343aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor/// TemplateTemplateParmDecl - Declares a template template parameter,
344aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor/// e.g., "T" in
345aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor/// @code
346aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor/// template <template <typename> class T> class container { };
347aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor/// @endcode
348aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor/// A template template parameter is a TemplateDecl because it defines the
349aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor/// name of a template and the template parameters allowable for substitution.
350aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorclass TemplateTemplateParmDecl
351aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  : public TemplateDecl, protected TemplateParmPosition {
352d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor
353d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  /// \brief The default template argument, if any.
354d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  Expr *DefaultArgument;
355d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor
356aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L,
357aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor                           unsigned D, unsigned P,
358aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor                           IdentifierInfo *Id, TemplateParameterList *Params)
359aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor    : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
360d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor      TemplateParmPosition(D, P), DefaultArgument(0)
361aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor    { }
362d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor
363aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorpublic:
364aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  static TemplateTemplateParmDecl *Create(ASTContext &C, DeclContext *DC,
365aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor                                          SourceLocation L, unsigned D,
366aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor                                          unsigned P, IdentifierInfo *Id,
367aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor                                          TemplateParameterList *Params);
368aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
369aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  using TemplateParmPosition::getDepth;
370aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  using TemplateParmPosition::getPosition;
371aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
372d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  /// \brief Determine whether this template parameter has a default
373d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  /// argument.
374d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  bool hasDefaultArgument() const { return DefaultArgument; }
375d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor
376d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  /// \brief Retrieve the default argument, if any.
377d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  Expr *getDefaultArgument() const { return DefaultArgument; }
378d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor
379d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  /// \brief Retrieve the location of the default argument, if any.
380d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  SourceLocation getDefaultArgumentLoc() const;
381d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor
382d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  /// \brief Set the default argument for this template parameter.
383d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  void setDefaultArgument(Expr *DefArg) {
384d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor    DefaultArgument = DefArg;
385d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  }
386d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor
387aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  // Implement isa/cast/dyncast/etc.
388aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  static bool classof(const Decl *D) {
389aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor    return D->getKind() == TemplateTemplateParm;
390aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  }
391aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  static bool classof(const TemplateTemplateParmDecl *D) { return true; }
392aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
393aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorprotected:
394aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  /// EmitImpl - Serialize this TemplateTypeParmDecl.  Called by Decl::Emit.
395aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  virtual void EmitImpl(llvm::Serializer& S) const;
396aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
397aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  /// CreateImpl - Deserialize a TemplateTypeParmDecl.  Called by Decl::Create.
398aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  static TemplateTemplateParmDecl* CreateImpl(llvm::Deserializer& D,
399aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor                                              ASTContext& C);
400aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
401aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  friend Decl* Decl::Create(llvm::Deserializer& D, ASTContext& C);
402aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor};
403aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
4043e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// \brief Represents a template argument within a class template
4053e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// specialization.
4063e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregorclass TemplateArgument {
4073e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  union {
40840808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor    uintptr_t TypeOrValue;
409c971f8694661776ecdec2ccc33fbe0333eeaf191Douglas Gregor    struct {
4105b0f752655cc94b970113235110b56a722eb40d4Douglas Gregor      char Value[sizeof(llvm::APSInt)];
411c971f8694661776ecdec2ccc33fbe0333eeaf191Douglas Gregor      void *Type;
412c971f8694661776ecdec2ccc33fbe0333eeaf191Douglas Gregor    } Integer;
4133e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  };
4143e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
41540808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor  /// \brief Location of the beginning of this template argument.
41640808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor  SourceLocation StartLoc;
41740808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor
4183e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregorpublic:
4193e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  /// \brief The type of template argument we're storing.
4203e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  enum ArgKind {
4213e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor    /// The template argument is a type. It's value is stored in the
42240808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor    /// TypeOrValue field.
4233e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor    Type = 0,
4243e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor    /// The template argument is a declaration
4253e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor    Declaration = 1,
4265b0f752655cc94b970113235110b56a722eb40d4Douglas Gregor    /// The template argument is an integral value stored in an llvm::APSInt.
42740808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor    Integral = 2,
42840808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor    /// The template argument is a value- or type-dependent expression
42940808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor    /// stored in an Expr*.
43040808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor    Expression = 3
4313e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  } Kind;
4323e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
43340808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor  /// \brief Construct an empty, invalid template argument.
43440808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor  TemplateArgument() : TypeOrValue(0), StartLoc(), Kind(Type) { }
43540808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor
4363e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  /// \brief Construct a template type argument.
43740808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor  TemplateArgument(SourceLocation Loc, QualType T) : Kind(Type) {
43840808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor    TypeOrValue = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr());
43940808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor    StartLoc = Loc;
4403e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
4413e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
4423e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  /// \brief Construct a template argument that refers to a
4433e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  /// declaration, which is either an external declaration or a
4443e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  /// template declaration.
44540808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor  TemplateArgument(SourceLocation Loc, Decl *D) : Kind(Declaration) {
4463e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor    // FIXME: Need to be sure we have the "canonical" declaration!
44740808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor    TypeOrValue = reinterpret_cast<uintptr_t>(D);
44840808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor    StartLoc = Loc;
4493e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
4503e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
4513e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  /// \brief Construct an integral constant template argument.
4525b0f752655cc94b970113235110b56a722eb40d4Douglas Gregor  TemplateArgument(SourceLocation Loc, const llvm::APSInt &Value,
453c971f8694661776ecdec2ccc33fbe0333eeaf191Douglas Gregor                   QualType Type)
45440808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor    : Kind(Integral) {
4555b0f752655cc94b970113235110b56a722eb40d4Douglas Gregor    new (Integer.Value) llvm::APSInt(Value);
456c971f8694661776ecdec2ccc33fbe0333eeaf191Douglas Gregor    Integer.Type = Type.getAsOpaquePtr();
45740808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor    StartLoc = Loc;
4583e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
4593e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
46040808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor  /// \brief Construct a template argument that is an expression.
46140808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor  ///
46240808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor  /// This form of template argument only occurs in template argument
46340808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor  /// lists used for dependent types and for expression; it will not
46440808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor  /// occur in a non-dependent, canonical template argument list.
46540808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor  TemplateArgument(Expr *E);
46640808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor
4673e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  /// \brief Copy constructor for a template argument.
4683e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  TemplateArgument(const TemplateArgument &Other) : Kind(Other.Kind) {
469c971f8694661776ecdec2ccc33fbe0333eeaf191Douglas Gregor    if (Kind == Integral) {
4705b0f752655cc94b970113235110b56a722eb40d4Douglas Gregor      new (Integer.Value) llvm::APSInt(*Other.getAsIntegral());
471c971f8694661776ecdec2ccc33fbe0333eeaf191Douglas Gregor      Integer.Type = Other.Integer.Type;
472c971f8694661776ecdec2ccc33fbe0333eeaf191Douglas Gregor    }
4733e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor    else
47440808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor      TypeOrValue = Other.TypeOrValue;
47540808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor    StartLoc = Other.StartLoc;
4763e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
4773e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
4783e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  TemplateArgument& operator=(const TemplateArgument& Other) {
47940808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor    // FIXME: Does not provide the strong guarantee for exception
48040808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor    // safety.
4815b0f752655cc94b970113235110b56a722eb40d4Douglas Gregor    using llvm::APSInt;
4823e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
4833e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor    if (Kind == Other.Kind && Kind == Integral) {
4843e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor      // Copy integral values.
4853e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor      *this->getAsIntegral() = *Other.getAsIntegral();
486c971f8694661776ecdec2ccc33fbe0333eeaf191Douglas Gregor      Integer.Type = Other.Integer.Type;
4873e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor    } else {
4883e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor      // Destroy the current integral value, if that's what we're holding.
4893e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor      if (Kind == Integral)
4905b0f752655cc94b970113235110b56a722eb40d4Douglas Gregor        getAsIntegral()->~APSInt();
4913e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
4923e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor      Kind = Other.Kind;
4933e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
494c971f8694661776ecdec2ccc33fbe0333eeaf191Douglas Gregor      if (Other.Kind == Integral) {
4955b0f752655cc94b970113235110b56a722eb40d4Douglas Gregor        new (Integer.Value) llvm::APSInt(*Other.getAsIntegral());
496c971f8694661776ecdec2ccc33fbe0333eeaf191Douglas Gregor        Integer.Type = Other.Integer.Type;
497c971f8694661776ecdec2ccc33fbe0333eeaf191Douglas Gregor      } else
49840808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor        TypeOrValue = Other.TypeOrValue;
4993e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor    }
50040808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor    StartLoc = Other.StartLoc;
50140808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor
5023e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor    return *this;
5033e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
5043e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
5053e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  ~TemplateArgument() {
5065b0f752655cc94b970113235110b56a722eb40d4Douglas Gregor    using llvm::APSInt;
5073e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
5083e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor    if (Kind == Integral)
5095b0f752655cc94b970113235110b56a722eb40d4Douglas Gregor      getAsIntegral()->~APSInt();
5103e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
5113e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
5123e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  /// \brief Return the kind of stored template argument.
5133e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  ArgKind getKind() const { return Kind; }
5143e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
5153e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  /// \brief Retrieve the template argument as a type.
5163e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  QualType getAsType() const {
5173e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor    if (Kind != Type)
5183e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor      return QualType();
5193e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
5203e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor    return QualType::getFromOpaquePtr(
52140808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor                                 reinterpret_cast<void*>(TypeOrValue));
5223e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
5233e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
5243e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  /// \brief Retrieve the template argument as a declaration.
5253e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  Decl *getAsDecl() const {
5263e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor    if (Kind != Declaration)
5273e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor      return 0;
52840808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor    return reinterpret_cast<Decl *>(TypeOrValue);
5293e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
5303e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
5313e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  /// \brief Retrieve the template argument as an integral value.
5325b0f752655cc94b970113235110b56a722eb40d4Douglas Gregor  llvm::APSInt *getAsIntegral() {
5333e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor    if (Kind != Integral)
5343e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor      return 0;
5355b0f752655cc94b970113235110b56a722eb40d4Douglas Gregor    return reinterpret_cast<llvm::APSInt*>(&Integer.Value[0]);
5363e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
5373e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
5385b0f752655cc94b970113235110b56a722eb40d4Douglas Gregor  const llvm::APSInt *getAsIntegral() const {
5393e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor    return const_cast<TemplateArgument*>(this)->getAsIntegral();
5403e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
5413e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
542c971f8694661776ecdec2ccc33fbe0333eeaf191Douglas Gregor  /// \brief Retrieve the type of the integral value.
543c971f8694661776ecdec2ccc33fbe0333eeaf191Douglas Gregor  QualType getIntegralType() const {
544c971f8694661776ecdec2ccc33fbe0333eeaf191Douglas Gregor    if (Kind != Integral)
545c971f8694661776ecdec2ccc33fbe0333eeaf191Douglas Gregor      return QualType();
546c971f8694661776ecdec2ccc33fbe0333eeaf191Douglas Gregor
547c971f8694661776ecdec2ccc33fbe0333eeaf191Douglas Gregor    return QualType::getFromOpaquePtr(Integer.Type);
548c971f8694661776ecdec2ccc33fbe0333eeaf191Douglas Gregor  }
549c971f8694661776ecdec2ccc33fbe0333eeaf191Douglas Gregor
55040808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor  /// \brief Retrieve the template argument as an expression.
55140808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor  Expr *getAsExpr() const {
55240808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor    if (Kind != Expression)
55340808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor      return 0;
55440808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor
55540808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor    return reinterpret_cast<Expr *>(TypeOrValue);
55640808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor  }
55740808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor
55840808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor  /// \brief Retrieve the location where the template argument starts.
55940808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor  SourceLocation getLocation() const { return StartLoc; }
56040808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor
5613e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  /// \brief Used to insert TemplateArguments into FoldingSets.
5623e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  void Profile(llvm::FoldingSetNodeID &ID) const {
5633e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor    ID.AddInteger(Kind);
5643e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor    switch (Kind) {
5653e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor    case Type:
5663e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor      getAsType().Profile(ID);
5673e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor      break;
5683e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
5693e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor    case Declaration:
5703e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor      ID.AddPointer(getAsDecl()); // FIXME: Must be canonical!
5713e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor      break;
5723e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
5733e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor    case Integral:
5743e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor      getAsIntegral()->Profile(ID);
575c971f8694661776ecdec2ccc33fbe0333eeaf191Douglas Gregor      getIntegralType().Profile(ID);
5763e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor      break;
57740808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor
57840808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor    case Expression:
57940808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor      // FIXME: We need a canonical representation of expressions.
58040808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor      ID.AddPointer(getAsExpr());
58140808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor      break;
5823e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor    }
5833e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
5843e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor};
5853e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
586cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor// \brief Describes the kind of template specialization that a
587cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor// particular template specialization declaration represents.
588cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregorenum TemplateSpecializationKind {
589cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  /// This template specialization was formed from a template-id but
590cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  /// has not yet been declared, defined, or instantiated.
591cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  TSK_Undeclared = 0,
592cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  /// This template specialization was declared or defined by an
593cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  /// explicit specialization (C++ [temp.expl.spec]).
594cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  TSK_ExplicitSpecialization,
595cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  /// This template specialization was implicitly instantiated from a
596cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  /// template. (C++ [temp.inst]).
597cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  TSK_ImplicitInstantiation,
598cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  /// This template specialization was instantiated from a template
599cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  /// due to an explicit instantiation request (C++ [temp.explicit]).
600cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  TSK_ExplicitInstantiation
601cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor};
602cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor
6033e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// \brief Represents a class template specialization, which refers to
6043e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// a class template with a given set of template arguments.
6053e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor///
6063e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// Class template specializations represent both explicit
6073e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// specialization of class templates, as in the example below, and
6083e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// implicit instantiations of class templates.
6093e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor///
6103e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// \code
6113e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// template<typename T> class array;
6123e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor///
6133e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// template<>
6143e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// class array<bool> { }; // class template specialization array<bool>
6153e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// \endcode
6163e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregorclass ClassTemplateSpecializationDecl
6173e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  : public CXXRecordDecl, public llvm::FoldingSetNode {
6183e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  /// \brief The template that this specialization specializes
6193e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  ClassTemplateDecl *SpecializedTemplate;
6203e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
6213e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  /// \brief The number of template arguments. The actual arguments
6223e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  /// are allocated after the ClassTemplateSpecializationDecl object.
623cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  unsigned NumTemplateArgs : 16;
624cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor
625cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  /// \brief The kind of specialization this declaration refers to.
626cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  /// Really a value of type TemplateSpecializationKind.
627cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  unsigned SpecializationKind : 2;
628cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor
6293e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  ClassTemplateSpecializationDecl(DeclContext *DC, SourceLocation L,
6303e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor                                  ClassTemplateDecl *SpecializedTemplate,
6313e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor                                  TemplateArgument *TemplateArgs,
6323e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor                                  unsigned NumTemplateArgs);
6333e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
6343e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregorpublic:
6353e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  static ClassTemplateSpecializationDecl *
6363e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  Create(ASTContext &Context, DeclContext *DC, SourceLocation L,
6373e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor         ClassTemplateDecl *SpecializedTemplate,
638cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor         TemplateArgument *TemplateArgs, unsigned NumTemplateArgs,
639cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor         ClassTemplateSpecializationDecl *PrevDecl);
6403e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
6413e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  /// \brief Retrieve the template that this specialization specializes.
6423e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  ClassTemplateDecl *getSpecializedTemplate() const {
6433e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor    return SpecializedTemplate;
6443e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
6453e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
6463e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  typedef const TemplateArgument * template_arg_iterator;
6473e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  template_arg_iterator template_arg_begin() const {
6483e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor    return reinterpret_cast<template_arg_iterator>(this + 1);
6493e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
6503e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
6513e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  template_arg_iterator template_arg_end() const {
6523e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor    return template_arg_begin() + NumTemplateArgs;
6533e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
6543e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
6552943aed177b33ae3f14273b11a7b398e5276ec62Douglas Gregor  const TemplateArgument *getTemplateArgs() const {
6562943aed177b33ae3f14273b11a7b398e5276ec62Douglas Gregor    return template_arg_begin();
6572943aed177b33ae3f14273b11a7b398e5276ec62Douglas Gregor  }
6582943aed177b33ae3f14273b11a7b398e5276ec62Douglas Gregor
6593e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  unsigned getNumTemplateArgs() const { return NumTemplateArgs; }
6603e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
661cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  /// \brief Determine the kind of specialization that this
662cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  /// declaration represents.
663cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  TemplateSpecializationKind getSpecializationKind() const {
664cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor    return static_cast<TemplateSpecializationKind>(SpecializationKind);
665cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  }
666cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor
667cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  void setSpecializationKind(TemplateSpecializationKind TSK) {
668cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor    SpecializationKind = TSK;
669cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  }
670cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor
6713e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  void Profile(llvm::FoldingSetNodeID &ID) const {
6723e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor    Profile(ID, template_arg_begin(), getNumTemplateArgs());
6733e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
6743e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
675fc705b84347e6fb4746a1a7e26949f64c2f2f358Douglas Gregor  /// \brief Sets the type of this specialization as it was written by
676fc705b84347e6fb4746a1a7e26949f64c2f2f358Douglas Gregor  /// the user. This will be a class template specialization type.
677fc705b84347e6fb4746a1a7e26949f64c2f2f358Douglas Gregor  void setTypeAsWritten(QualType T) {
678fc705b84347e6fb4746a1a7e26949f64c2f2f358Douglas Gregor    TypeForDecl = T.getTypePtr();
679fc705b84347e6fb4746a1a7e26949f64c2f2f358Douglas Gregor  }
680fc705b84347e6fb4746a1a7e26949f64c2f2f358Douglas Gregor
6813e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  static void
6823e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  Profile(llvm::FoldingSetNodeID &ID, const TemplateArgument *TemplateArgs,
6833e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor          unsigned NumTemplateArgs) {
6843e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor    for (unsigned Arg = 0; Arg != NumTemplateArgs; ++Arg)
6853e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor      TemplateArgs[Arg].Profile(ID);
6863e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
6873e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
6883e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  static bool classof(const Decl *D) {
6893e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor    return D->getKind() == ClassTemplateSpecialization;
6903e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
6913e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
6923e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  static bool classof(const ClassTemplateSpecializationDecl *) {
6933e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor    return true;
6943e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
6953e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor};
6963e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
6973e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// Declaration of a class template.
6983e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregorclass ClassTemplateDecl : public TemplateDecl {
6993e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregorprotected:
7003e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  ClassTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
7013e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor                    TemplateParameterList *Params, NamedDecl *Decl)
7023e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor    : TemplateDecl(ClassTemplate, DC, L, Name, Params, Decl) { }
7033e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
7043e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  /// \brief The class template specializations for this class
7053e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  /// template, including explicit specializations and instantiations.
7063e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  llvm::FoldingSet<ClassTemplateSpecializationDecl> Specializations;
7073e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
7083e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregorpublic:
7093e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  /// Get the underlying class declarations of the template.
7103e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  CXXRecordDecl *getTemplatedDecl() const {
7113e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor    return static_cast<CXXRecordDecl *>(TemplatedDecl);
7123e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
7133e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
7143e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  /// Create a class teplate node.
7153e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  static ClassTemplateDecl *Create(ASTContext &C, DeclContext *DC,
7163e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor                                   SourceLocation L,
7173e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor                                   DeclarationName Name,
7183e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor                                   TemplateParameterList *Params,
7193e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor                                   NamedDecl *Decl);
7203e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
7213e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  /// \brief Retrieve the set of specializations of this class template.
7223e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  llvm::FoldingSet<ClassTemplateSpecializationDecl> &getSpecializations() {
7233e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor    return Specializations;
7243e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
7253e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
7263e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  // Implement isa/cast/dyncast support
7273e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  static bool classof(const Decl *D)
7283e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  { return D->getKind() == ClassTemplate; }
7293e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  static bool classof(const ClassTemplateDecl *D)
7303e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  { return true; }
7313e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor};
7323e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
733aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor} /* end of namespace clang */
734aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
735aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor#endif
736