DeclTemplate.h revision d684b0027e16163c4bdba3e2f8bfadda7d62a0d3
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"
1855f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor
19aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregornamespace clang {
20aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
21aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorclass TemplateParameterList;
22aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorclass TemplateDecl;
23aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorclass FunctionTemplateDecl;
24aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorclass ClassTemplateDecl;
25aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorclass TemplateTypeParmDecl;
26aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorclass NonTypeTemplateParmDecl;
27aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorclass TemplateTemplateParmDecl;
28aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
29aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor/// TemplateParameterList - Stores a list of template parameters for a
30aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor/// TemplateDecl and its derived classes.
31aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorclass TemplateParameterList {
32ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  /// The location of the 'template' keyword.
33ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  SourceLocation TemplateLoc;
34ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor
35ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  /// The locations of the '<' and '>' angle brackets.
36ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  SourceLocation LAngleLoc, RAngleLoc;
37ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor
38ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  /// The number of template parameters in this template
39aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  /// parameter list.
40aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  unsigned NumParams;
41aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
42ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  TemplateParameterList(SourceLocation TemplateLoc, SourceLocation LAngleLoc,
43ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor                        Decl **Params, unsigned NumParams,
44ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor                        SourceLocation RAngleLoc);
45aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
46aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorpublic:
47ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  static TemplateParameterList *Create(ASTContext &C,
48ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor                                       SourceLocation TemplateLoc,
49ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor                                       SourceLocation LAngleLoc,
50ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor                                       Decl **Params,
51ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor                                       unsigned NumParams,
52ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor                                       SourceLocation RAngleLoc);
53aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
54aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  /// iterator - Iterates through the template parameters in this list.
55aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  typedef Decl** iterator;
56aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
57aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  /// const_iterator - Iterates through the template parameters in this list.
58aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  typedef Decl* const* const_iterator;
59aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
60aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  iterator begin() { return reinterpret_cast<Decl **>(this + 1); }
61aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  const_iterator begin() const {
62aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor    return reinterpret_cast<Decl * const *>(this + 1);
63aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  }
64aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  iterator end() { return begin() + NumParams; }
65aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  const_iterator end() const { return begin() + NumParams; }
66aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
67aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  unsigned size() const { return NumParams; }
68ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor
69ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  SourceLocation getTemplateLoc() const { return TemplateLoc; }
70ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  SourceLocation getLAngleLoc() const { return LAngleLoc; }
71ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  SourceLocation getRAngleLoc() const { return RAngleLoc; }
72aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor};
73aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
74aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor//===----------------------------------------------------------------------===//
75aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor// Kinds of Templates
76aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor//===----------------------------------------------------------------------===//
77aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
78aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor/// TemplateDecl - The base class of all kinds of template declarations (e.g.,
79aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor/// class, function, etc.). The TemplateDecl class stores the list of template
80aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor/// parameters and a reference to the templated scoped declaration: the
81aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor/// underlying AST node.
82aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorclass TemplateDecl : public NamedDecl {
83aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorprotected:
84aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  // This is probably never used.
85aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
86aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor               DeclarationName Name)
87aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor    : NamedDecl(DK, DC, L, Name), TemplatedDecl(0), TemplateParams(0)
88aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  { }
89aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
90aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  // Construct a template decl with the given name and parameters.
91aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  // Used when there is not templated element (tt-params, alias?).
92aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
93aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor               DeclarationName Name, TemplateParameterList *Params)
94aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor    : NamedDecl(DK, DC, L, Name), TemplatedDecl(0), TemplateParams(Params)
95aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  { }
96aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
97aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  // Construct a template decl with name, parameters, and templated element.
98aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
99aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor               DeclarationName Name, TemplateParameterList *Params,
100aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor               NamedDecl *Decl)
101aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor    : NamedDecl(DK, DC, L, Name), TemplatedDecl(Decl),
102aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor      TemplateParams(Params) { }
103aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorpublic:
104aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  ~TemplateDecl();
105aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
106aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  /// Get the list of template parameters
107ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  TemplateParameterList *getTemplateParameters() const {
108aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor    return TemplateParams;
109aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  }
110aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
111aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  /// Get the underlying, templated declaration.
112aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  NamedDecl *getTemplatedDecl() const { return TemplatedDecl; }
113aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
114aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  // Implement isa/cast/dyncast/etc.
115aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  static bool classof(const Decl *D) {
116aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor      return D->getKind() >= TemplateFirst && D->getKind() <= TemplateLast;
117aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  }
118aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  static bool classof(const TemplateDecl *D) { return true; }
119aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  static bool classof(const FunctionTemplateDecl *D) { return true; }
120aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  static bool classof(const ClassTemplateDecl *D) { return true; }
121aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  static bool classof(const TemplateTemplateParmDecl *D) { return true; }
122aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
123aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorprotected:
124aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  NamedDecl *TemplatedDecl;
125aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  TemplateParameterList* TemplateParams;
126aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor};
127aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
128aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor/// Declaration of a template function.
129aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorclass FunctionTemplateDecl : public TemplateDecl {
130aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorprotected:
131aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  FunctionTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
132aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor                       TemplateParameterList *Params, NamedDecl *Decl)
133aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor    : TemplateDecl(FunctionTemplate, DC, L, Name, Params, Decl) { }
134aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorpublic:
135aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  /// Get the underling function declaration of the template.
136aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  FunctionDecl *getTemplatedDecl() const {
137aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor    return static_cast<FunctionDecl*>(TemplatedDecl);
138aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  }
139aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
140aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  /// Create a template function node.
141aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  static FunctionTemplateDecl *Create(ASTContext &C, DeclContext *DC,
142aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor                                      SourceLocation L,
143aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor                                      DeclarationName Name,
144aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor                                      TemplateParameterList *Params,
145aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor                                      NamedDecl *Decl);
146aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
147aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  // Implement isa/cast/dyncast support
148aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  static bool classof(const Decl *D)
149aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  { return D->getKind() == FunctionTemplate; }
150aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  static bool classof(const FunctionTemplateDecl *D)
151aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  { return true; }
152aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor};
153aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
154aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor/// Declaration of a template class.
155aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorclass ClassTemplateDecl : public TemplateDecl {
156aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorprotected:
157aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  ClassTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
158aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor                    TemplateParameterList *Params, NamedDecl *Decl)
159aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor    : TemplateDecl(ClassTemplate, DC, L, Name, Params, Decl) { }
160aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorpublic:
161aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  /// Get the underlying class declarations of the template.
162aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  CXXRecordDecl *getTemplatedDecl() const {
16355f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor    return static_cast<CXXRecordDecl *>(TemplatedDecl);
164aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  }
165aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
166aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  /// Create a class teplate node.
167aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  static ClassTemplateDecl *Create(ASTContext &C, DeclContext *DC,
168aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor                                   SourceLocation L,
169aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor                                   DeclarationName Name,
170aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor                                   TemplateParameterList *Params,
171aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor                                   NamedDecl *Decl);
172aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
173aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  // Implement isa/cast/dyncast support
174aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  static bool classof(const Decl *D)
175aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  { return D->getKind() == ClassTemplate; }
176aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  static bool classof(const ClassTemplateDecl *D)
177aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  { return true; }
178aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor};
179aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
180aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor//===----------------------------------------------------------------------===//
181aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor// Kinds of Template Parameters
182aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor//===----------------------------------------------------------------------===//
183aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
184aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
185aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor/// The TemplateParmPosition class defines the position of a template parameter
186aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor/// within a template parameter list. Because template parameter can be listed
187aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor/// sequentially for out-of-line template members, each template parameter is
188aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor/// given a Depth - the nesting of template parameter scopes - and a Position -
189aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor/// the occurrence within the parameter list.
190aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor/// This class is inheritedly privately by different kinds of template
191aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor/// parameters and is not part of the Decl hierarchy. Just a facility.
192aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorclass TemplateParmPosition
193aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor{
194aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorprotected:
195aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  // FIXME: This should probably never be called, but it's here as
196aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  TemplateParmPosition()
197aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor    : Depth(0), Position(0)
198aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  { /* assert(0 && "Cannot create positionless template parameter"); */ }
199aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
200aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  TemplateParmPosition(unsigned D, unsigned P)
201aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor    : Depth(D), Position(P)
202aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  { }
203aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
204aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  // FIXME: These probably don't need to be ints. int:5 for depth, int:8 for
205aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  // position? Maybe?
206aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  unsigned Depth;
207aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  unsigned Position;
208aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
209aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorpublic:
210aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  /// Get the nesting depth of the template parameter.
211aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  unsigned getDepth() const { return Depth; }
212aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
213aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  /// Get the position of the template parameter within its parameter list.
214aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  unsigned getPosition() const { return Position; }
215aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor};
216aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
217aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor/// TemplateTypeParmDecl - Declaration of a template type parameter,
218aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor/// e.g., "T" in
219aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor/// @code
220aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor/// template<typename T> class vector;
221aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor/// @endcode
222fab9d67cebb87be968e7ae31a3b549a5279b5d51Douglas Gregorclass TemplateTypeParmDecl : public TypeDecl {
223fab9d67cebb87be968e7ae31a3b549a5279b5d51Douglas Gregor  /// \brief Whether this template type parameter was declaration with
224fab9d67cebb87be968e7ae31a3b549a5279b5d51Douglas Gregor  /// the 'typename' keyword. If false, it was declared with the
225aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  /// 'class' keyword.
226aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  bool Typename : 1;
227aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
228d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  /// \brief Whether this template type parameter inherited its
229d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  /// default argument.
230d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  bool InheritedDefault : 1;
231d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor
232d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  /// \brief The location of the default argument, if any.
233d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  SourceLocation DefaultArgumentLoc;
234d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor
235d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  /// \brief The default template argument, if any.
236d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  QualType DefaultArgument;
237d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor
238fab9d67cebb87be968e7ae31a3b549a5279b5d51Douglas Gregor  TemplateTypeParmDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
239fab9d67cebb87be968e7ae31a3b549a5279b5d51Douglas Gregor                       bool Typename, QualType Type)
240d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor    : TypeDecl(TemplateTypeParm, DC, L, Id), Typename(Typename),
241d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor      InheritedDefault(false), DefaultArgument() {
242fab9d67cebb87be968e7ae31a3b549a5279b5d51Douglas Gregor    TypeForDecl = Type.getTypePtr();
243fab9d67cebb87be968e7ae31a3b549a5279b5d51Douglas Gregor  }
244fab9d67cebb87be968e7ae31a3b549a5279b5d51Douglas Gregor
245aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorpublic:
246aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  static TemplateTypeParmDecl *Create(ASTContext &C, DeclContext *DC,
247aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor                                      SourceLocation L, unsigned D, unsigned P,
248aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor                                      IdentifierInfo *Id, bool Typename);
249aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
250fab9d67cebb87be968e7ae31a3b549a5279b5d51Douglas Gregor  /// \brief Whether this template type parameter was declared with
251fab9d67cebb87be968e7ae31a3b549a5279b5d51Douglas Gregor  /// the 'typename' keyword. If not, it was declared with the 'class'
252fab9d67cebb87be968e7ae31a3b549a5279b5d51Douglas Gregor  /// keyword.
253aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  bool wasDeclaredWithTypename() const { return Typename; }
254aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
255d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  /// \brief Determine whether this template parameter has a default
256d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  /// argument.
257d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  bool hasDefaultArgument() const { return !DefaultArgument.isNull(); }
258d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor
259d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  /// \brief Retrieve the default argument, if any.
260d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  QualType getDefaultArgument() const { return DefaultArgument; }
261d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor
262d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  /// \brief Retrieve the location of the default argument, if any.
263d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  SourceLocation getDefaultArgumentLoc() const { return DefaultArgumentLoc; }
264d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor
265d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  /// \brief Determines whether the default argument was inherited
266d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  /// from a previous declaration of this template.
267d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  bool defaultArgumentWasInherited() const { return InheritedDefault; }
268d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor
269d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  /// \brief Set the default argument for this template parameter, and
270d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  /// whether that default argument was inherited from another
271d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  /// declaration.
272d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  void setDefaultArgument(QualType DefArg, SourceLocation DefArgLoc,
273d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor                          bool Inherited) {
274d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor    DefaultArgument = DefArg;
275d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor    DefaultArgumentLoc = DefArgLoc;
276d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor    InheritedDefault = Inherited;
277d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  }
278d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor
279aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  // Implement isa/cast/dyncast/etc.
280aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  static bool classof(const Decl *D) {
281aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor    return D->getKind() == TemplateTypeParm;
282aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  }
283aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  static bool classof(const TemplateTypeParmDecl *D) { return true; }
284aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
285aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorprotected:
286fab9d67cebb87be968e7ae31a3b549a5279b5d51Douglas Gregor  /// Serialize this TemplateTypeParmDecl.  Called by Decl::Emit.
287aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  virtual void EmitImpl(llvm::Serializer& S) const;
288aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
289fab9d67cebb87be968e7ae31a3b549a5279b5d51Douglas Gregor  /// Deserialize a TemplateTypeParmDecl.  Called by Decl::Create.
290aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  static TemplateTypeParmDecl* CreateImpl(llvm::Deserializer& D, ASTContext& C);
291aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
292aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  friend Decl* Decl::Create(llvm::Deserializer& D, ASTContext& C);
293aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor};
294aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
295aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor/// NonTypeTemplateParmDecl - Declares a non-type template parameter,
296aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor/// e.g., "Size" in
297aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor/// @code
298aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor/// template<int Size> class array { };
299aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor/// @endcode
300aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorclass NonTypeTemplateParmDecl
301aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  : public VarDecl, protected TemplateParmPosition {
302d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  /// \brief The default template argument, if any.
303d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  Expr *DefaultArgument;
304d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor
305aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  NonTypeTemplateParmDecl(DeclContext *DC, SourceLocation L, unsigned D,
306aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor                          unsigned P, IdentifierInfo *Id, QualType T,
307aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor                          SourceLocation TSSL = SourceLocation())
308aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor    : VarDecl(NonTypeTemplateParm, DC, L, Id, T, VarDecl::None, TSSL),
309d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor      TemplateParmPosition(D, P), DefaultArgument(0)
310d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  { }
311d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor
312aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorpublic:
313aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  static NonTypeTemplateParmDecl *
314aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  Create(ASTContext &C, DeclContext *DC, SourceLocation L, unsigned D,
315aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor         unsigned P, IdentifierInfo *Id, QualType T,
316aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor         SourceLocation TypeSpecStartLoc = SourceLocation());
317aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
318aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  using TemplateParmPosition::getDepth;
319aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  using TemplateParmPosition::getPosition;
320aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
321d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  /// \brief Determine whether this template parameter has a default
322d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  /// argument.
323d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  bool hasDefaultArgument() const { return DefaultArgument; }
324d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor
325d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  /// \brief Retrieve the default argument, if any.
326d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  Expr *getDefaultArgument() const { return DefaultArgument; }
327d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor
328d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  /// \brief Retrieve the location of the default argument, if any.
329d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  SourceLocation getDefaultArgumentLoc() const;
330d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor
331d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  /// \brief Set the default argument for this template parameter.
332d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  void setDefaultArgument(Expr *DefArg) {
333d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor    DefaultArgument = DefArg;
334d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  }
335d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor
336aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  // Implement isa/cast/dyncast/etc.
337aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  static bool classof(const Decl *D) {
338aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor    return D->getKind() == NonTypeTemplateParm;
339aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  }
340aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  static bool classof(const NonTypeTemplateParmDecl *D) { return true; }
341aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
342aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorprotected:
343aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  /// EmitImpl - Serialize this TemplateTypeParmDecl.  Called by Decl::Emit.
344aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  virtual void EmitImpl(llvm::Serializer& S) const;
345aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
346aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  /// CreateImpl - Deserialize a TemplateTypeParmDecl.  Called by Decl::Create.
347aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  static NonTypeTemplateParmDecl* CreateImpl(llvm::Deserializer& D,
348aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor                                             ASTContext& C);
349aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
350aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  friend Decl* Decl::Create(llvm::Deserializer& D, ASTContext& C);
351aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor};
352aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
353aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor/// TemplateTemplateParmDecl - Declares a template template parameter,
354aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor/// e.g., "T" in
355aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor/// @code
356aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor/// template <template <typename> class T> class container { };
357aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor/// @endcode
358aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor/// A template template parameter is a TemplateDecl because it defines the
359aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor/// name of a template and the template parameters allowable for substitution.
360aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorclass TemplateTemplateParmDecl
361aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  : public TemplateDecl, protected TemplateParmPosition {
362d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor
363d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  /// \brief The default template argument, if any.
364d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  Expr *DefaultArgument;
365d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor
366aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L,
367aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor                           unsigned D, unsigned P,
368aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor                           IdentifierInfo *Id, TemplateParameterList *Params)
369aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor    : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
370d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor      TemplateParmPosition(D, P), DefaultArgument(0)
371aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor    { }
372d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor
373aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorpublic:
374aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  static TemplateTemplateParmDecl *Create(ASTContext &C, DeclContext *DC,
375aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor                                          SourceLocation L, unsigned D,
376aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor                                          unsigned P, IdentifierInfo *Id,
377aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor                                          TemplateParameterList *Params);
378aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
379aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  using TemplateParmPosition::getDepth;
380aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  using TemplateParmPosition::getPosition;
381aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
382d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  /// \brief Determine whether this template parameter has a default
383d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  /// argument.
384d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  bool hasDefaultArgument() const { return DefaultArgument; }
385d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor
386d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  /// \brief Retrieve the default argument, if any.
387d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  Expr *getDefaultArgument() const { return DefaultArgument; }
388d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor
389d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  /// \brief Retrieve the location of the default argument, if any.
390d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  SourceLocation getDefaultArgumentLoc() const;
391d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor
392d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  /// \brief Set the default argument for this template parameter.
393d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  void setDefaultArgument(Expr *DefArg) {
394d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor    DefaultArgument = DefArg;
395d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  }
396d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor
397aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  // Implement isa/cast/dyncast/etc.
398aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  static bool classof(const Decl *D) {
399aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor    return D->getKind() == TemplateTemplateParm;
400aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  }
401aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  static bool classof(const TemplateTemplateParmDecl *D) { return true; }
402aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
403aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorprotected:
404aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  /// EmitImpl - Serialize this TemplateTypeParmDecl.  Called by Decl::Emit.
405aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  virtual void EmitImpl(llvm::Serializer& S) const;
406aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
407aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  /// CreateImpl - Deserialize a TemplateTypeParmDecl.  Called by Decl::Create.
408aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  static TemplateTemplateParmDecl* CreateImpl(llvm::Deserializer& D,
409aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor                                              ASTContext& C);
410aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
411aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  friend Decl* Decl::Create(llvm::Deserializer& D, ASTContext& C);
412aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor};
413aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
414aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor} /* end of namespace clang */
415aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
416aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor#endif
417