DeclTemplate.h revision 16573fa9705b546b7597c273b25b85d6321e2b33
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"
18275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall#include "clang/AST/TemplateBase.h"
19f67875d5addf36b951ad37fb04509ab2b572c88aDouglas Gregor#include "llvm/ADT/PointerUnion.h"
203f3ce82674b44a58a2af7d90feb55acd906dd762Anders Carlsson#include <limits>
2155f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor
22aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregornamespace clang {
23aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
24aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorclass TemplateParameterList;
25aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorclass TemplateDecl;
26aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorclass FunctionTemplateDecl;
27aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorclass ClassTemplateDecl;
28c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregorclass ClassTemplatePartialSpecializationDecl;
29aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorclass TemplateTypeParmDecl;
30aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorclass NonTypeTemplateParmDecl;
31aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorclass TemplateTemplateParmDecl;
32aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
33f67875d5addf36b951ad37fb04509ab2b572c88aDouglas Gregor/// \brief Stores a template parameter of any kind.
34f67875d5addf36b951ad37fb04509ab2b572c88aDouglas Gregortypedef llvm::PointerUnion3<TemplateTypeParmDecl*, NonTypeTemplateParmDecl*,
35f67875d5addf36b951ad37fb04509ab2b572c88aDouglas Gregor                            TemplateTemplateParmDecl*> TemplateParameter;
36f67875d5addf36b951ad37fb04509ab2b572c88aDouglas Gregor
37aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor/// TemplateParameterList - Stores a list of template parameters for a
38aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor/// TemplateDecl and its derived classes.
39aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorclass TemplateParameterList {
40ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  /// The location of the 'template' keyword.
41ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  SourceLocation TemplateLoc;
42ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor
43ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  /// The locations of the '<' and '>' angle brackets.
44ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  SourceLocation LAngleLoc, RAngleLoc;
45ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor
46ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  /// The number of template parameters in this template
47aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  /// parameter list.
48aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  unsigned NumParams;
49aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
50ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  TemplateParameterList(SourceLocation TemplateLoc, SourceLocation LAngleLoc,
51bf4ea56cdc376cef5a12abf6bf18dc34805c2226Douglas Gregor                        NamedDecl **Params, unsigned NumParams,
52ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor                        SourceLocation RAngleLoc);
53aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
54aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorpublic:
551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  static TemplateParameterList *Create(ASTContext &C,
56ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor                                       SourceLocation TemplateLoc,
57ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor                                       SourceLocation LAngleLoc,
58bf4ea56cdc376cef5a12abf6bf18dc34805c2226Douglas Gregor                                       NamedDecl **Params,
59ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor                                       unsigned NumParams,
60ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor                                       SourceLocation RAngleLoc);
61aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
62aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  /// iterator - Iterates through the template parameters in this list.
63bf4ea56cdc376cef5a12abf6bf18dc34805c2226Douglas Gregor  typedef NamedDecl** iterator;
64aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
65aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  /// const_iterator - Iterates through the template parameters in this list.
66bf4ea56cdc376cef5a12abf6bf18dc34805c2226Douglas Gregor  typedef NamedDecl* const* const_iterator;
67aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
68bf4ea56cdc376cef5a12abf6bf18dc34805c2226Douglas Gregor  iterator begin() { return reinterpret_cast<NamedDecl **>(this + 1); }
69aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  const_iterator begin() const {
70bf4ea56cdc376cef5a12abf6bf18dc34805c2226Douglas Gregor    return reinterpret_cast<NamedDecl * const *>(this + 1);
71aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  }
72aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  iterator end() { return begin() + NumParams; }
73aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  const_iterator end() const { return begin() + NumParams; }
74aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
75aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  unsigned size() const { return NumParams; }
76ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor
77bf4ea56cdc376cef5a12abf6bf18dc34805c2226Douglas Gregor  NamedDecl* getParam(unsigned Idx) {
78f67875d5addf36b951ad37fb04509ab2b572c88aDouglas Gregor    assert(Idx < size() && "Template parameter index out-of-range");
79f67875d5addf36b951ad37fb04509ab2b572c88aDouglas Gregor    return begin()[Idx];
80f67875d5addf36b951ad37fb04509ab2b572c88aDouglas Gregor  }
81f67875d5addf36b951ad37fb04509ab2b572c88aDouglas Gregor
82bf4ea56cdc376cef5a12abf6bf18dc34805c2226Douglas Gregor  const NamedDecl* getParam(unsigned Idx) const {
8340808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor    assert(Idx < size() && "Template parameter index out-of-range");
8440808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor    return begin()[Idx];
8540808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor  }
8640808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor
8762cb18dd11472965e03374d40bc27d650bc331b6Douglas Gregor  /// \btief Returns the minimum number of arguments needed to form a
8862cb18dd11472965e03374d40bc27d650bc331b6Douglas Gregor  /// template specialization. This may be fewer than the number of
8962cb18dd11472965e03374d40bc27d650bc331b6Douglas Gregor  /// template parameters, if some of the parameters have default
900ceffb51b28b09db67404058c642dcb1f877f6e8Anders Carlsson  /// arguments or if there is a parameter pack.
9162cb18dd11472965e03374d40bc27d650bc331b6Douglas Gregor  unsigned getMinRequiredArguments() const;
9262cb18dd11472965e03374d40bc27d650bc331b6Douglas Gregor
93ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \brief Get the depth of this template parameter list in the set of
94ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// template parameter lists.
95ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ///
96ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// The first template parameter list in a declaration will have depth 0,
97ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// the second template parameter list will have depth 1, etc.
98ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  unsigned getDepth() const;
99ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor
100ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  SourceLocation getTemplateLoc() const { return TemplateLoc; }
101ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  SourceLocation getLAngleLoc() const { return LAngleLoc; }
102ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  SourceLocation getRAngleLoc() const { return RAngleLoc; }
10362cb18dd11472965e03374d40bc27d650bc331b6Douglas Gregor
10462cb18dd11472965e03374d40bc27d650bc331b6Douglas Gregor  SourceRange getSourceRange() const {
10562cb18dd11472965e03374d40bc27d650bc331b6Douglas Gregor    return SourceRange(TemplateLoc, RAngleLoc);
10662cb18dd11472965e03374d40bc27d650bc331b6Douglas Gregor  }
107aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor};
108aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
109127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// \brief A helper class for making template argument lists.
110127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorclass TemplateArgumentListBuilder {
111127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateArgument *StructuredArgs;
112127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned MaxStructuredArgs;
113127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned NumStructuredArgs;
1141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
115127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateArgument *FlatArgs;
116127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned MaxFlatArgs;
117127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned NumFlatArgs;
1181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
119127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  bool AddingToPack;
120127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned PackBeginIndex;
1211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
122aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorpublic:
123127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateArgumentListBuilder(const TemplateParameterList *Parameters,
124127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                              unsigned NumTemplateArgs)
1251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  : StructuredArgs(0), MaxStructuredArgs(Parameters->size()),
1261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  NumStructuredArgs(0), FlatArgs(0),
127127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  MaxFlatArgs(std::max(MaxStructuredArgs, NumTemplateArgs)), NumFlatArgs(0),
128127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  AddingToPack(false), PackBeginIndex(0) { }
1291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
130127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  void Append(const TemplateArgument& Arg);
131127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  void BeginPack();
132127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  void EndPack();
1331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
134127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  void ReleaseArgs();
1351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  unsigned flatSize() const {
137127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return NumFlatArgs;
138127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  }
139127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  const TemplateArgument *getFlatArguments() const {
140127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return FlatArgs;
141127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  }
1421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
143127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned structuredSize() const {
144127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    // If we don't have any structured args, just reuse the flat size.
145127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    if (!StructuredArgs)
146127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      return flatSize();
1471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
148127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return NumStructuredArgs;
149d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  }
150127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  const TemplateArgument *getStructuredArguments() const {
151127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    // If we don't have any structured args, just reuse the flat args.
152127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    if (!StructuredArgs)
153127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      return getFlatArguments();
1541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
155127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return StructuredArgs;
156aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  }
157aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor};
158aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
159127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// \brief A template argument list.
160127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor///
161127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// FIXME: In the future, this class will be extended to support
162127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// variadic templates and member templates, which will make some of
163127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// the function names below make more sense.
164127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorclass TemplateArgumentList {
165127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief The template argument list.
166127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  ///
167127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// The integer value will be non-zero to indicate that this
168127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// template argument list does not own the pointer.
169127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  llvm::PointerIntPair<const TemplateArgument *, 1> FlatArguments;
1701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
171127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief The number of template arguments in this template
172127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// argument list.
173127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned NumFlatArguments;
1741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
175127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  llvm::PointerIntPair<const TemplateArgument *, 1> StructuredArguments;
176127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned NumStructuredArguments;
1771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
178aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorpublic:
179127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateArgumentList(ASTContext &Context,
180127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                       TemplateArgumentListBuilder &Builder,
181127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                       bool TakeArgs);
1821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
183b9aa6b214c8fbc3e081dde575eef1f0913d48bdcDouglas Gregor  /// \brief Produces a shallow copy of the given template argument list
184b9aa6b214c8fbc3e081dde575eef1f0913d48bdcDouglas Gregor  TemplateArgumentList(const TemplateArgumentList &Other);
185b9aa6b214c8fbc3e081dde575eef1f0913d48bdcDouglas Gregor
186127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  ~TemplateArgumentList();
1871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
188127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the template argument at a given index.
1891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  const TemplateArgument &get(unsigned Idx) const {
190127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    assert(Idx < NumFlatArguments && "Invalid template argument index");
191127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return getFlatArgumentList()[Idx];
192127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  }
1931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
194127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the template argument at a given index.
195127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  const TemplateArgument &operator[](unsigned Idx) const { return get(Idx); }
1961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
197127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the number of template arguments in this
198127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// template argument list.
199127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned size() const { return NumFlatArguments; }
2001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
201127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the number of template arguments in the
202127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// flattened template argument list.
203127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned flat_size() const { return NumFlatArguments; }
2041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
205127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the flattened template argument list.
2061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  const TemplateArgument *getFlatArgumentList() const {
207127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return FlatArguments.getPointer();
208127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  }
209127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor};
2101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
211127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor//===----------------------------------------------------------------------===//
212127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor// Kinds of Templates
213127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor//===----------------------------------------------------------------------===//
214aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
215127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// TemplateDecl - The base class of all kinds of template declarations (e.g.,
216127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// class, function, etc.). The TemplateDecl class stores the list of template
217127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// parameters and a reference to the templated scoped declaration: the
218127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// underlying AST node.
219127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorclass TemplateDecl : public NamedDecl {
220127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorprotected:
221127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // This is probably never used.
222127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
223127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor               DeclarationName Name)
2241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    : NamedDecl(DK, DC, L, Name), TemplatedDecl(0), TemplateParams(0) { }
225d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor
226127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // Construct a template decl with the given name and parameters.
227127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // Used when there is not templated element (tt-params, alias?).
228127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
229127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor               DeclarationName Name, TemplateParameterList *Params)
2301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    : NamedDecl(DK, DC, L, Name), TemplatedDecl(0), TemplateParams(Params) { }
231d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor
232127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // Construct a template decl with name, parameters, and templated element.
233127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
234127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor               DeclarationName Name, TemplateParameterList *Params,
235127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor               NamedDecl *Decl)
236127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    : NamedDecl(DK, DC, L, Name), TemplatedDecl(Decl),
237127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      TemplateParams(Params) { }
238127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorpublic:
239127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  ~TemplateDecl();
240d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor
241127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// Get the list of template parameters
242127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateParameterList *getTemplateParameters() const {
243127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return TemplateParams;
244d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  }
245d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor
246127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// Get the underlying, templated declaration.
247127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  NamedDecl *getTemplatedDecl() const { return TemplatedDecl; }
248127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
249aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  // Implement isa/cast/dyncast/etc.
25080cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
251127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static bool classof(const TemplateDecl *D) { return true; }
252127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static bool classof(const FunctionTemplateDecl *D) { return true; }
253127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static bool classof(const ClassTemplateDecl *D) { return true; }
254aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  static bool classof(const TemplateTemplateParmDecl *D) { return true; }
25580cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classofKind(Kind K) {
25680cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall    return K >= TemplateFirst && K <= TemplateLast;
25780cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  }
258aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
259127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorprotected:
260127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  NamedDecl *TemplatedDecl;
261127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateParameterList* TemplateParams;
262127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor};
2631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// \brief Provides information about a function template specialization,
265127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// which is a FunctionDecl that has been explicitly specialization or
266127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// instantiated from a function template.
267127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorclass FunctionTemplateSpecializationInfo : public llvm::FoldingSetNode {
268127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorpublic:
2691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// \brief The function template specialization that this structure
270127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// describes.
271127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  FunctionDecl *Function;
2721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// \brief The function template from which this function template
274127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// specialization was generated.
2751fd2dd145d9bcdf0b8d60a88e1795b6ae83656f5Douglas Gregor  ///
276d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor  /// The two bits are contain the top 4 values of TemplateSpecializationKind.
277d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor  llvm::PointerIntPair<FunctionTemplateDecl *, 2> Template;
2781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
279127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief The template arguments used to produce the function template
280127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// specialization from the function template.
281127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  const TemplateArgumentList *TemplateArguments;
2821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
283b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  /// \brief The point at which this function template specialization was
284b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  /// first instantiated.
285b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  SourceLocation PointOfInstantiation;
286b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor
2871fd2dd145d9bcdf0b8d60a88e1795b6ae83656f5Douglas Gregor  /// \brief Retrieve the template from which this function was specialized.
2881fd2dd145d9bcdf0b8d60a88e1795b6ae83656f5Douglas Gregor  FunctionTemplateDecl *getTemplate() const { return Template.getPointer(); }
289d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor
290d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor  /// \brief Determine what kind of template specialization this is.
291d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor  TemplateSpecializationKind getTemplateSpecializationKind() const {
292d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor    return (TemplateSpecializationKind)(Template.getInt() + 1);
293d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor  }
294d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor
295d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor  /// \brief Set the template specialization kind.
296d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor  void setTemplateSpecializationKind(TemplateSpecializationKind TSK) {
2971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    assert(TSK != TSK_Undeclared &&
298d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor         "Cannot encode TSK_Undeclared for a function template specialization");
299d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor    Template.setInt(TSK - 1);
3001fd2dd145d9bcdf0b8d60a88e1795b6ae83656f5Douglas Gregor  }
3011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
302b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  /// \brief Retrieve the first point of instantiation of this function
303b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  /// template specialization.
304b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  ///
305b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  /// The point of instantiation may be an invalid source location if this
306b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  /// function has yet to be instantiated.
307b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  SourceLocation getPointOfInstantiation() const {
308b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor    return PointOfInstantiation;
309b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  }
310b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor
311b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  /// \brief Set the (first) point of instantiation of this function template
312b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  /// specialization.
313b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  void setPointOfInstantiation(SourceLocation POI) {
314b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor    PointOfInstantiation = POI;
315b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  }
316b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor
317127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  void Profile(llvm::FoldingSetNodeID &ID) {
3181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    Profile(ID, TemplateArguments->getFlatArgumentList(),
319828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor            TemplateArguments->flat_size(),
3201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            Function->getASTContext());
321127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  }
3221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  static void
3241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  Profile(llvm::FoldingSetNodeID &ID, const TemplateArgument *TemplateArgs,
325828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor          unsigned NumTemplateArgs, ASTContext &Context) {
326127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    ID.AddInteger(NumTemplateArgs);
327127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    for (unsigned Arg = 0; Arg != NumTemplateArgs; ++Arg)
328828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor      TemplateArgs[Arg].Profile(ID, Context);
3291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  }
330127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor};
3311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3322db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor/// \brief Provides information a specialization of a member of a class
3332db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor/// template, which may be a member function, static data member, or
3342db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor/// member class.
3352db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregorclass MemberSpecializationInfo {
33644e368b6a85c42d681148ccd5e0052418ff9751eDouglas Gregor  // The member declaration from which this member was instantiated, and the
33744e368b6a85c42d681148ccd5e0052418ff9751eDouglas Gregor  // manner in which the instantiation occurred (in the lower two bits).
33844e368b6a85c42d681148ccd5e0052418ff9751eDouglas Gregor  llvm::PointerIntPair<NamedDecl *, 2> MemberAndTSK;
3392db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor
340b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  // The point at which this member was first instantiated.
341b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  SourceLocation PointOfInstantiation;
342b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor
3432db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregorpublic:
3442db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor  explicit
3452db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor  MemberSpecializationInfo(NamedDecl *IF, TemplateSpecializationKind TSK)
346b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor    : MemberAndTSK(IF, TSK - 1), PointOfInstantiation() {
34744e368b6a85c42d681148ccd5e0052418ff9751eDouglas Gregor    assert(TSK != TSK_Undeclared &&
34844e368b6a85c42d681148ccd5e0052418ff9751eDouglas Gregor           "Cannot encode undeclared template specializations for members");
34944e368b6a85c42d681148ccd5e0052418ff9751eDouglas Gregor  }
3502db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor
3512db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor  /// \brief Retrieve the member declaration from which this member was
3522db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor  /// instantiated.
35344e368b6a85c42d681148ccd5e0052418ff9751eDouglas Gregor  NamedDecl *getInstantiatedFrom() const { return MemberAndTSK.getPointer(); }
3542db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor
3552db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor  /// \brief Determine what kind of template specialization this is.
3562db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor  TemplateSpecializationKind getTemplateSpecializationKind() const {
35744e368b6a85c42d681148ccd5e0052418ff9751eDouglas Gregor    return (TemplateSpecializationKind)(MemberAndTSK.getInt() + 1);
3582db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor  }
3592db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor
3602db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor  /// \brief Set the template specialization kind.
3612db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor  void setTemplateSpecializationKind(TemplateSpecializationKind TSK) {
36244e368b6a85c42d681148ccd5e0052418ff9751eDouglas Gregor    assert(TSK != TSK_Undeclared &&
36344e368b6a85c42d681148ccd5e0052418ff9751eDouglas Gregor           "Cannot encode undeclared template specializations for members");
36444e368b6a85c42d681148ccd5e0052418ff9751eDouglas Gregor    MemberAndTSK.setInt(TSK - 1);
3652db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor  }
366b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor
367b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  /// \brief Retrieve the first point of instantiation of this member.
368b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  /// If the point of instantiation is an invalid location, then this member
369b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  /// has not yet been instantiated.
370b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  SourceLocation getPointOfInstantiation() const {
371b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor    return PointOfInstantiation;
372b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  }
373b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor
374b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  /// \brief Set the first point of instantiation.
375b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  void setPointOfInstantiation(SourceLocation POI) {
376b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor    PointOfInstantiation = POI;
377b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  }
3782db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor};
379af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
380af2094e7cecadf36667deb61a83587ffdd979bd3John McCall/// \brief Provides information about a dependent function-template
381af2094e7cecadf36667deb61a83587ffdd979bd3John McCall/// specialization declaration.  Since explicit function template
382af2094e7cecadf36667deb61a83587ffdd979bd3John McCall/// specialization and instantiation declarations can only appear in
383af2094e7cecadf36667deb61a83587ffdd979bd3John McCall/// namespace scope, and you can only specialize a member of a
384af2094e7cecadf36667deb61a83587ffdd979bd3John McCall/// fully-specialized class, the only way to get one of these is in
385af2094e7cecadf36667deb61a83587ffdd979bd3John McCall/// a friend declaration like the following:
386af2094e7cecadf36667deb61a83587ffdd979bd3John McCall///
387af2094e7cecadf36667deb61a83587ffdd979bd3John McCall///   template <class T> void foo(T);
388af2094e7cecadf36667deb61a83587ffdd979bd3John McCall///   template <class T> class A {
389af2094e7cecadf36667deb61a83587ffdd979bd3John McCall///     friend void foo<>(T);
390af2094e7cecadf36667deb61a83587ffdd979bd3John McCall///   };
391af2094e7cecadf36667deb61a83587ffdd979bd3John McCallclass DependentFunctionTemplateSpecializationInfo {
392af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  union {
393af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    // Force sizeof to be a multiple of sizeof(void*) so that the
394af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    // trailing data is aligned.
395af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    void *Aligner;
396af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
397af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    struct {
398af2094e7cecadf36667deb61a83587ffdd979bd3John McCall      /// The number of potential template candidates.
399af2094e7cecadf36667deb61a83587ffdd979bd3John McCall      unsigned NumTemplates;
400af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
401af2094e7cecadf36667deb61a83587ffdd979bd3John McCall      /// The number of template arguments.
402af2094e7cecadf36667deb61a83587ffdd979bd3John McCall      unsigned NumArgs;
403af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    } d;
404af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  };
405af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
406af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  /// The locations of the left and right angle brackets.
407af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  SourceRange AngleLocs;
408af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
409af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  FunctionTemplateDecl * const *getTemplates() const {
410af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    return reinterpret_cast<FunctionTemplateDecl*const*>(this+1);
411af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  }
412af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
413af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  const TemplateArgumentLoc *getTemplateArgs() const {
414af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    return reinterpret_cast<const TemplateArgumentLoc*>(
41533cab704d9b3b5b0218d578a20593bdfb0b1eb23John McCall             &getTemplates()[getNumTemplates()]);
416af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  }
417af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
418af2094e7cecadf36667deb61a83587ffdd979bd3John McCallpublic:
419af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  DependentFunctionTemplateSpecializationInfo(
420af2094e7cecadf36667deb61a83587ffdd979bd3John McCall                                 const UnresolvedSetImpl &Templates,
421af2094e7cecadf36667deb61a83587ffdd979bd3John McCall                                 const TemplateArgumentListInfo &TemplateArgs);
422af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
423af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  /// \brief Returns the number of function templates that this might
424af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  /// be a specialization of.
425af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  unsigned getNumTemplates() const {
426af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    return d.NumTemplates;
427af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  }
428af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
429af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  /// \brief Returns the i'th template candidate.
430af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  FunctionTemplateDecl *getTemplate(unsigned I) const {
431af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    assert(I < getNumTemplates() && "template index out of range");
432af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    return getTemplates()[I];
433af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  }
434af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
435af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  /// \brief Returns the number of explicit template arguments that were given.
436af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  unsigned getNumTemplateArgs() const {
437af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    return d.NumArgs;
438af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  }
439af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
440af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  /// \brief Returns the nth template argument.
441af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  const TemplateArgumentLoc &getTemplateArg(unsigned I) const {
442af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    assert(I < getNumTemplateArgs() && "template arg index out of range");
443af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    return getTemplateArgs()[I];
444af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  }
445af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
446af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  SourceLocation getLAngleLoc() const {
447af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    return AngleLocs.getBegin();
448af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  }
449af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
450af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  SourceLocation getRAngleLoc() const {
451af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    return AngleLocs.getEnd();
452af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  }
453af2094e7cecadf36667deb61a83587ffdd979bd3John McCall};
4542db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor
455127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// Declaration of a template function.
4561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpclass FunctionTemplateDecl : public TemplateDecl {
457127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorprotected:
458127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Data that is common to all of the declarations of a given
459127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// function template.
460127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  struct Common {
461fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor    Common() : InstantiatedFromMember(0, false) { }
4621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
463127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    /// \brief The function template specializations for this function
464127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    /// template, including explicit specializations and instantiations.
465127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    llvm::FoldingSet<FunctionTemplateSpecializationInfo> Specializations;
4661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
467d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor    /// \brief The member function template from which this was most
468d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor    /// directly instantiated (or null).
469fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor    ///
470fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor    /// The boolean value indicates whether this member function template
471fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor    /// was explicitly specialized.
472fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor    llvm::PointerIntPair<FunctionTemplateDecl*, 1, bool> InstantiatedFromMember;
4733e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  };
4741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
475127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief A pointer to the previous declaration (if this is a redeclaration)
476127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// or to the data that is common to all declarations of this function
477127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// template.
478127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  llvm::PointerUnion<Common*, FunctionTemplateDecl*> CommonOrPrev;
4791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// \brief Retrieves the "common" pointer shared by all
481127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// (re-)declarations of the same function template. Calling this routine
482127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// may implicitly allocate memory for the common pointer.
483127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  Common *getCommonPtr();
4841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
485127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  FunctionTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
486127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                       TemplateParameterList *Params, NamedDecl *Decl)
487127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    : TemplateDecl(FunctionTemplate, DC, L, Name, Params, Decl),
488127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      CommonOrPrev((Common*)0) { }
4891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4903e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregorpublic:
491127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  void Destroy(ASTContext &C);
4921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
493127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// Get the underlying function declaration of the template.
494127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  FunctionDecl *getTemplatedDecl() const {
495127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return static_cast<FunctionDecl*>(TemplatedDecl);
4963e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
4973e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
498127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the set of function template specializations of this
499127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// function template.
500127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  llvm::FoldingSet<FunctionTemplateSpecializationInfo> &getSpecializations() {
501127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return getCommonPtr()->Specializations;
5023e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
5031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
504127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the previous declaration of this function template, or
505127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// NULL if no such declaration exists.
506127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  const FunctionTemplateDecl *getPreviousDeclaration() const {
507127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return CommonOrPrev.dyn_cast<FunctionTemplateDecl*>();
5083e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
5093e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
510127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the previous declaration of this function template, or
511127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// NULL if no such declaration exists.
512127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  FunctionTemplateDecl *getPreviousDeclaration() {
513127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return CommonOrPrev.dyn_cast<FunctionTemplateDecl*>();
5143e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
5151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
516127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Set the previous declaration of this function template.
517127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  void setPreviousDeclaration(FunctionTemplateDecl *Prev) {
518127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    if (Prev)
519127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      CommonOrPrev = Prev;
520127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  }
5211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
522b57a4fe73b8227c0dba651818b8495dfca61e530Argyrios Kyrtzidis  virtual FunctionTemplateDecl *getCanonicalDecl();
5231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// \brief Retrieve the member function template that this function template
525d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// was instantiated from.
526d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  ///
527d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// This routine will return non-NULL for member function templates of
528d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// class templates.  For example, given:
529d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  ///
530d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// \code
531d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// template <typename T>
532d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// struct X {
533d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  ///   template <typename U> void f();
534d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// };
535d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// \endcode
536d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  ///
537d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// X<int>::A<float> is a CXXMethodDecl (whose parent is X<int>, a
5381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// ClassTemplateSpecializationDecl) for which getPrimaryTemplate() will
539d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// return X<int>::f, a FunctionTemplateDecl (whose parent is again
540d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// X<int>) for which getInstantiatedFromMemberTemplate() will return
5411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// X<T>::f, a FunctionTemplateDecl (whose parent is X<T>, a
542d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// ClassTemplateDecl).
543d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  ///
5441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// \returns NULL if this is not an instantiation of a member function
545d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// template.
546d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  FunctionTemplateDecl *getInstantiatedFromMemberTemplate() {
547fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor    return getCommonPtr()->InstantiatedFromMember.getPointer();
548d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  }
5491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
550d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  void setInstantiatedFromMemberTemplate(FunctionTemplateDecl *FTD) {
551fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor    assert(!getCommonPtr()->InstantiatedFromMember.getPointer());
552fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor    getCommonPtr()->InstantiatedFromMember.setPointer(FTD);
553d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  }
5541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
555fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  /// \brief Determines whether this template was a specialization of a
556fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  /// member template.
557fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  ///
558fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  /// In the following example, the function template \c X<int>::f is a
559fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  /// member specialization.
560fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  ///
561fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  /// \code
562fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  /// template<typename T>
563fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  /// struct X {
564fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  ///   template<typename U> void f(T, U);
565fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  /// };
566fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  ///
567fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  /// template<> template<typename T>
568fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  /// void X<int>::f(int, T);
569fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  /// \endcode
570fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  bool isMemberSpecialization() {
571fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor    return getCommonPtr()->InstantiatedFromMember.getInt();
572fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  }
573fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor
574fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  /// \brief Note that this member template is a specialization.
575fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  void setMemberSpecialization() {
576fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor    assert(getCommonPtr()->InstantiatedFromMember.getPointer() &&
577fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor           "Only member templates can be member template specializations");
578fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor    getCommonPtr()->InstantiatedFromMember.setInt(true);
579fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  }
580fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor
581127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// Create a template function node.
582127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static FunctionTemplateDecl *Create(ASTContext &C, DeclContext *DC,
583127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                      SourceLocation L,
584127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                      DeclarationName Name,
585127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                      TemplateParameterList *Params,
586127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                      NamedDecl *Decl);
5873e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
588127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // Implement isa/cast/dyncast support
58980cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
59080cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classof(const FunctionTemplateDecl *D) { return true; }
59180cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classofKind(Kind K) { return K == FunctionTemplate; }
592127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor};
593d01b1da213aeb71fd40ff7fb78a194613cc1ece7Anders Carlsson
594127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor//===----------------------------------------------------------------------===//
595127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor// Kinds of Template Parameters
596127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor//===----------------------------------------------------------------------===//
59740808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor
598127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// The TemplateParmPosition class defines the position of a template parameter
599127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// within a template parameter list. Because template parameter can be listed
600127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// sequentially for out-of-line template members, each template parameter is
601127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// given a Depth - the nesting of template parameter scopes - and a Position -
602127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// the occurrence within the parameter list.
603127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// This class is inheritedly privately by different kinds of template
604127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// parameters and is not part of the Decl hierarchy. Just a facility.
6051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpclass TemplateParmPosition {
606127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorprotected:
607127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // FIXME: This should probably never be called, but it's here as
608127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateParmPosition()
609127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    : Depth(0), Position(0)
610127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  { /* assert(0 && "Cannot create positionless template parameter"); */ }
6113e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
612127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateParmPosition(unsigned D, unsigned P)
613127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    : Depth(D), Position(P)
614127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  { }
6153e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
616127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // FIXME: These probably don't need to be ints. int:5 for depth, int:8 for
617127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // position? Maybe?
618127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned Depth;
619127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned Position;
6203e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
621127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorpublic:
622127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// Get the nesting depth of the template parameter.
623127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned getDepth() const { return Depth; }
6243e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
625127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// Get the position of the template parameter within its parameter list.
626127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned getPosition() const { return Position; }
6271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
628127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// Get the index of the template parameter within its parameter list.
629127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned getIndex() const { return Position; }
630127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor};
6313e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
632127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// TemplateTypeParmDecl - Declaration of a template type parameter,
633127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// e.g., "T" in
634127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// @code
635127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// template<typename T> class vector;
636127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// @endcode
637127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorclass TemplateTypeParmDecl : public TypeDecl {
638127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Whether this template type parameter was declaration with
639127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// the 'typename' keyword. If false, it was declared with the
640127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// 'class' keyword.
641127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  bool Typename : 1;
6423e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
643127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Whether this template type parameter inherited its
644127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// default argument.
645127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  bool InheritedDefault : 1;
6463e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
647127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Whether this is a parameter pack.
648127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  bool ParameterPack : 1;
649127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
650127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief The default template argument, if any.
651a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall  TypeSourceInfo *DefaultArgument;
652127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
6531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  TemplateTypeParmDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
654127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                       bool Typename, QualType Type, bool ParameterPack)
655127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    : TypeDecl(TemplateTypeParm, DC, L, Id), Typename(Typename),
6561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      InheritedDefault(false), ParameterPack(ParameterPack), DefaultArgument() {
657127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    TypeForDecl = Type.getTypePtr();
6583e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
6593e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
660127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorpublic:
661127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static TemplateTypeParmDecl *Create(ASTContext &C, DeclContext *DC,
662127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                      SourceLocation L, unsigned D, unsigned P,
663127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                      IdentifierInfo *Id, bool Typename,
664127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                      bool ParameterPack);
665c971f8694661776ecdec2ccc33fbe0333eeaf191Douglas Gregor
666127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Whether this template type parameter was declared with
667127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// the 'typename' keyword. If not, it was declared with the 'class'
668127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// keyword.
669127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  bool wasDeclaredWithTypename() const { return Typename; }
670c971f8694661776ecdec2ccc33fbe0333eeaf191Douglas Gregor
671127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Determine whether this template parameter has a default
672127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// argument.
673833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  bool hasDefaultArgument() const { return DefaultArgument != 0; }
674199d99192fbcca9f043596c40ead4afab4999dbaDouglas Gregor
675127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the default argument, if any.
676833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  QualType getDefaultArgument() const { return DefaultArgument->getType(); }
67740808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor
678833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  /// \brief Retrieves the default argument's source information, if any.
679a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall  TypeSourceInfo *getDefaultArgumentInfo() const { return DefaultArgument; }
680833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall
681833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  /// \brief Retrieves the location of the default argument declaration.
682833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  SourceLocation getDefaultArgumentLoc() const;
68340808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor
684127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Determines whether the default argument was inherited
685127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// from a previous declaration of this template.
686127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  bool defaultArgumentWasInherited() const { return InheritedDefault; }
687f670c8cfa58b4c224eb8fb566130dc47844dd3deDouglas Gregor
688127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Set the default argument for this template parameter, and
689127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// whether that default argument was inherited from another
690127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// declaration.
691a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall  void setDefaultArgument(TypeSourceInfo *DefArg, bool Inherited) {
692127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    DefaultArgument = DefArg;
693127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    InheritedDefault = Inherited;
694f670c8cfa58b4c224eb8fb566130dc47844dd3deDouglas Gregor  }
69540808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor
696833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  /// \brief Removes the default argument of this template parameter.
697833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  void removeDefaultArgument() {
698833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall    DefaultArgument = 0;
699833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall    InheritedDefault = false;
700833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  }
701833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall
702ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \brief Retrieve the depth of the template parameter.
703ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  unsigned getDepth() const;
704ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor
705ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \brief Retrieve the index of the template parameter.
706ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  unsigned getIndex() const;
707ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor
708127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Returns whether this is a parameter pack.
709127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  bool isParameterPack() const { return ParameterPack; }
710fb25052736439d72a557cddd41dfb927bcb3d3e5Anders Carlsson
711127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // Implement isa/cast/dyncast/etc.
71280cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
713127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static bool classof(const TemplateTypeParmDecl *D) { return true; }
71480cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classofKind(Kind K) { return K == TemplateTypeParm; }
7153e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor};
7163e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
717127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// NonTypeTemplateParmDecl - Declares a non-type template parameter,
718127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// e.g., "Size" in
719127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// @code
720127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// template<int Size> class array { };
721127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// @endcode
722127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorclass NonTypeTemplateParmDecl
723127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  : public VarDecl, protected TemplateParmPosition {
724127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief The default template argument, if any.
725127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  Expr *DefaultArgument;
726127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
727127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  NonTypeTemplateParmDecl(DeclContext *DC, SourceLocation L, unsigned D,
728127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                          unsigned P, IdentifierInfo *Id, QualType T,
729a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall                          TypeSourceInfo *TInfo)
73016573fa9705b546b7597c273b25b85d6321e2b33Douglas Gregor    : VarDecl(NonTypeTemplateParm, DC, L, Id, T, TInfo, VarDecl::None,
73116573fa9705b546b7597c273b25b85d6321e2b33Douglas Gregor              VarDecl::None),
7321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      TemplateParmPosition(D, P), DefaultArgument(0)
733127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  { }
734127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
7351c5976e5e933c0d74f7e04e8f907a93f5edbfec1Anders Carlssonpublic:
736127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static NonTypeTemplateParmDecl *
737127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  Create(ASTContext &C, DeclContext *DC, SourceLocation L, unsigned D,
738a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall         unsigned P, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo);
7399ba41645892da0000fe8a7832b80208f44dafedaAnders Carlsson
740127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  using TemplateParmPosition::getDepth;
741127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  using TemplateParmPosition::getPosition;
742127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  using TemplateParmPosition::getIndex;
7431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
744127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Determine whether this template parameter has a default
745127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// argument.
746127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  bool hasDefaultArgument() const { return DefaultArgument; }
747fb25052736439d72a557cddd41dfb927bcb3d3e5Anders Carlsson
748127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the default argument, if any.
749127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  Expr *getDefaultArgument() const { return DefaultArgument; }
750127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
751127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the location of the default argument, if any.
752127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  SourceLocation getDefaultArgumentLoc() const;
753127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
754127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Set the default argument for this template parameter.
755127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  void setDefaultArgument(Expr *DefArg) {
756127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    DefaultArgument = DefArg;
7573b36b66a00b7d5bab71b486a54694f0ae397bddbAnders Carlsson  }
758127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
759127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // Implement isa/cast/dyncast/etc.
76080cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
761127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static bool classof(const NonTypeTemplateParmDecl *D) { return true; }
76280cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classofKind(Kind K) { return K == NonTypeTemplateParm; }
7631c5976e5e933c0d74f7e04e8f907a93f5edbfec1Anders Carlsson};
7641c5976e5e933c0d74f7e04e8f907a93f5edbfec1Anders Carlsson
765127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// TemplateTemplateParmDecl - Declares a template template parameter,
766127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// e.g., "T" in
767127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// @code
768127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// template <template <typename> class T> class container { };
769127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// @endcode
770127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// A template template parameter is a TemplateDecl because it defines the
771127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// name of a template and the template parameters allowable for substitution.
772127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorclass TemplateTemplateParmDecl
773127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  : public TemplateDecl, protected TemplateParmPosition {
7747e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
775127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief The default template argument, if any.
776788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor  TemplateArgumentLoc DefaultArgument;
7777e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
778127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L,
779127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                           unsigned D, unsigned P,
780127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                           IdentifierInfo *Id, TemplateParameterList *Params)
781127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
782788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor      TemplateParmPosition(D, P), DefaultArgument()
783127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    { }
7847e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
785127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorpublic:
786127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static TemplateTemplateParmDecl *Create(ASTContext &C, DeclContext *DC,
787127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                          SourceLocation L, unsigned D,
788127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                          unsigned P, IdentifierInfo *Id,
789127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                          TemplateParameterList *Params);
7907e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
791127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  using TemplateParmPosition::getDepth;
792127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  using TemplateParmPosition::getPosition;
793127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  using TemplateParmPosition::getIndex;
7941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
795127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Determine whether this template parameter has a default
796127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// argument.
797788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor  bool hasDefaultArgument() const {
798788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor    return !DefaultArgument.getArgument().isNull();
799788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor  }
8007e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
801127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the default argument, if any.
802788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor  const TemplateArgumentLoc &getDefaultArgument() const {
803788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor    return DefaultArgument;
804788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor  }
8057e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
806127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Set the default argument for this template parameter.
807788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor  void setDefaultArgument(const TemplateArgumentLoc &DefArg) {
808127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    DefaultArgument = DefArg;
809127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  }
8107e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
811127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // Implement isa/cast/dyncast/etc.
81280cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
813127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static bool classof(const TemplateTemplateParmDecl *D) { return true; }
81480cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classofKind(Kind K) { return K == TemplateTemplateParm; }
8157e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor};
8167e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
8173e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// \brief Represents a class template specialization, which refers to
8183e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// a class template with a given set of template arguments.
8193e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor///
8203e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// Class template specializations represent both explicit
8213e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// specialization of class templates, as in the example below, and
8223e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// implicit instantiations of class templates.
8233e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor///
8243e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// \code
8253e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// template<typename T> class array;
8261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///
8271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// template<>
8283e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// class array<bool> { }; // class template specialization array<bool>
8293e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// \endcode
8301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpclass ClassTemplateSpecializationDecl
8313e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  : public CXXRecordDecl, public llvm::FoldingSetNode {
8321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
8331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// \brief Structure that stores information about a class template
83437d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// specialization that was instantiated from a class template partial
83537d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// specialization.
83637d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  struct SpecializedPartialSpecialization {
83737d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    /// \brief The class template partial specialization from which this
83837d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    /// class template specialization was instantiated.
83937d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    ClassTemplatePartialSpecializationDecl *PartialSpecialization;
8401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
84137d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    /// \brief The template argument list deduced for the class template
84237d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    /// partial specialization itself.
84337d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    TemplateArgumentList *TemplateArgs;
84437d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  };
8451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
8463e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  /// \brief The template that this specialization specializes
84737d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  llvm::PointerUnion<ClassTemplateDecl *, SpecializedPartialSpecialization *>
84837d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    SpecializedTemplate;
8493e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
8503cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall  /// \brief The type-as-written of an explicit template specialization.
8513cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall  /// Does not apply to implicit specializations.
8523cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall  TypeSourceInfo *TypeAsWritten;
8533cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall
8547e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor  /// \brief The template arguments used to describe this specialization.
8557e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor  TemplateArgumentList TemplateArgs;
856cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor
8579cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall  /// \brief The point where this template was instantiated (if any)
8589cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall  SourceLocation PointOfInstantiation;
8599cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall
860cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  /// \brief The kind of specialization this declaration refers to.
861cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  /// Really a value of type TemplateSpecializationKind.
862d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor  unsigned SpecializationKind : 3;
863cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor
864c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregorprotected:
865c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK,
8667e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor                                  DeclContext *DC, SourceLocation L,
8673e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor                                  ClassTemplateDecl *SpecializedTemplate,
8688e9e9ef5348bce1a8f0741a5684fac3de9701c28Douglas Gregor                                  TemplateArgumentListBuilder &Builder,
8698e9e9ef5348bce1a8f0741a5684fac3de9701c28Douglas Gregor                                  ClassTemplateSpecializationDecl *PrevDecl);
8701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
8713e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregorpublic:
8723e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  static ClassTemplateSpecializationDecl *
8733e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  Create(ASTContext &Context, DeclContext *DC, SourceLocation L,
8743e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor         ClassTemplateDecl *SpecializedTemplate,
87591fdf6f576b91f023c3bebb0d3786aab555cb3c5Anders Carlsson         TemplateArgumentListBuilder &Builder,
876cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor         ClassTemplateSpecializationDecl *PrevDecl);
8773e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
87837d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  virtual void Destroy(ASTContext& C);
87937d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor
880136a6988960ac3aeb96f298da7a1a182db7217cdJohn McCall  virtual void getNameForDiagnostic(std::string &S,
881136a6988960ac3aeb96f298da7a1a182db7217cdJohn McCall                                    const PrintingPolicy &Policy,
882136a6988960ac3aeb96f298da7a1a182db7217cdJohn McCall                                    bool Qualified) const;
883136a6988960ac3aeb96f298da7a1a182db7217cdJohn McCall
8843e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  /// \brief Retrieve the template that this specialization specializes.
88537d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  ClassTemplateDecl *getSpecializedTemplate() const;
8863e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
8871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// \brief Retrieve the template arguments of the class template
88837d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// specialization.
8891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  const TemplateArgumentList &getTemplateArgs() const {
8907e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor    return TemplateArgs;
8913e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
8923e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
893cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  /// \brief Determine the kind of specialization that this
894cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  /// declaration represents.
895cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  TemplateSpecializationKind getSpecializationKind() const {
896cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor    return static_cast<TemplateSpecializationKind>(SpecializationKind);
897cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  }
898cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor
899cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  void setSpecializationKind(TemplateSpecializationKind TSK) {
900cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor    SpecializationKind = TSK;
901cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  }
902cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor
9039cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall  /// \brief Get the point of instantiation (if any), or null if none.
9049cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall  SourceLocation getPointOfInstantiation() const {
9059cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall    return PointOfInstantiation;
9069cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall  }
9079cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall
9089cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall  void setPointOfInstantiation(SourceLocation Loc) {
9099cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall    assert(Loc.isValid() && "point of instantiation must be valid!");
9109cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall    PointOfInstantiation = Loc;
9119cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall  }
9129cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall
91337d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// \brief If this class template specialization is an instantiation of
91437d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// a template (rather than an explicit specialization), return the
91537d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// class template or class template partial specialization from which it
91637d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// was instantiated.
9171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  llvm::PointerUnion<ClassTemplateDecl *,
91837d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor                     ClassTemplatePartialSpecializationDecl *>
91937d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  getInstantiatedFrom() const {
92037d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    if (getSpecializationKind() != TSK_ImplicitInstantiation &&
921d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor        getSpecializationKind() != TSK_ExplicitInstantiationDefinition &&
922d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor        getSpecializationKind() != TSK_ExplicitInstantiationDeclaration)
92337d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor      return (ClassTemplateDecl*)0;
9241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
9251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    if (SpecializedPartialSpecialization *PartialSpec
92637d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor          = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
92737d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor      return PartialSpec->PartialSpecialization;
9281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
92937d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    return const_cast<ClassTemplateDecl*>(
93037d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor                             SpecializedTemplate.get<ClassTemplateDecl*>());
93137d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  }
9321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
93337d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// \brief Retrieve the set of template arguments that should be used
93437d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// to instantiate members of the class template or class template partial
93537d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// specialization from which this class template specialization was
93637d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// instantiated.
93737d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  ///
93837d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// \returns For a class template specialization instantiated from the primary
93937d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// template, this function will return the same template arguments as
94037d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// getTemplateArgs(). For a class template specialization instantiated from
94137d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// a class template partial specialization, this function will return the
94237d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// deduced template arguments for the class template partial specialization
94337d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// itself.
94437d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  const TemplateArgumentList &getTemplateInstantiationArgs() const {
9451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    if (SpecializedPartialSpecialization *PartialSpec
94637d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor        = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
94737d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor      return *PartialSpec->TemplateArgs;
9481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
94937d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    return getTemplateArgs();
95037d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  }
9511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
95237d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// \brief Note that this class template specialization is actually an
95337d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// instantiation of the given class template partial specialization whose
95437d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// template arguments have been deduced.
95537d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  void setInstantiationOf(ClassTemplatePartialSpecializationDecl *PartialSpec,
95637d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor                          TemplateArgumentList *TemplateArgs) {
9571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    SpecializedPartialSpecialization *PS
95837d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor      = new (getASTContext()) SpecializedPartialSpecialization();
95937d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    PS->PartialSpecialization = PartialSpec;
96037d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    PS->TemplateArgs = TemplateArgs;
96137d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    SpecializedTemplate = PS;
96237d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  }
9631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
964fc705b84347e6fb4746a1a7e26949f64c2f2f358Douglas Gregor  /// \brief Sets the type of this specialization as it was written by
965fc705b84347e6fb4746a1a7e26949f64c2f2f358Douglas Gregor  /// the user. This will be a class template specialization type.
9663cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall  void setTypeAsWritten(TypeSourceInfo *T) {
9673cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall    TypeAsWritten = T;
9683cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall  }
9693cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall
9703cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall  /// \brief Gets the type of this specialization as it was written by
9713cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall  /// the user, if it was so written.
9723cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall  TypeSourceInfo *getTypeAsWritten() const {
9733cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall    return TypeAsWritten;
974fc705b84347e6fb4746a1a7e26949f64c2f2f358Douglas Gregor  }
975fc705b84347e6fb4746a1a7e26949f64c2f2f358Douglas Gregor
976c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  void Profile(llvm::FoldingSetNodeID &ID) const {
977828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor    Profile(ID, TemplateArgs.getFlatArgumentList(), TemplateArgs.flat_size(),
978828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor            getASTContext());
979c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  }
980c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
9811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  static void
9821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  Profile(llvm::FoldingSetNodeID &ID, const TemplateArgument *TemplateArgs,
983828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor          unsigned NumTemplateArgs, ASTContext &Context) {
9840ceffb51b28b09db67404058c642dcb1f877f6e8Anders Carlsson    ID.AddInteger(NumTemplateArgs);
9853e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor    for (unsigned Arg = 0; Arg != NumTemplateArgs; ++Arg)
986828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor      TemplateArgs[Arg].Profile(ID, Context);
9873e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
9883e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
98980cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
99080cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classofKind(Kind K) {
99180cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall    return K == ClassTemplateSpecialization ||
99280cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall           K == ClassTemplatePartialSpecialization;
9933e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
9943e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
9953e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  static bool classof(const ClassTemplateSpecializationDecl *) {
9963e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor    return true;
9973e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
998c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
999c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  static bool classof(const ClassTemplatePartialSpecializationDecl *) {
1000c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor    return true;
1001c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  }
1002c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor};
1003c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
10041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpclass ClassTemplatePartialSpecializationDecl
10051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  : public ClassTemplateSpecializationDecl {
10061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// \brief The list of template parameters
1007c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  TemplateParameterList* TemplateParams;
1008c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
1009833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  /// \brief The source info for the template arguments as written.
10103cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall  /// FIXME: redundant with TypeAsWritten?
1011833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  TemplateArgumentLoc *ArgsAsWritten;
1012833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  unsigned NumArgsAsWritten;
1013833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall
1014ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \brief The class template partial specialization from which this
1015ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// class template partial specialization was instantiated.
1016ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ///
1017ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// The boolean value will be true to indicate that this class template
1018ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// partial specialization was specialized at this level.
1019ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  llvm::PointerIntPair<ClassTemplatePartialSpecializationDecl *, 1, bool>
1020ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor      InstantiatedFromMember;
1021ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor
1022c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  ClassTemplatePartialSpecializationDecl(ASTContext &Context,
1023c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor                                         DeclContext *DC, SourceLocation L,
1024c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor                                         TemplateParameterList *Params,
1025c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor                                         ClassTemplateDecl *SpecializedTemplate,
10268e9e9ef5348bce1a8f0741a5684fac3de9701c28Douglas Gregor                                         TemplateArgumentListBuilder &Builder,
1027833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall                                         TemplateArgumentLoc *ArgInfos,
1028833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall                                         unsigned NumArgInfos,
10298e9e9ef5348bce1a8f0741a5684fac3de9701c28Douglas Gregor                               ClassTemplatePartialSpecializationDecl *PrevDecl)
10301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    : ClassTemplateSpecializationDecl(Context,
10318e9e9ef5348bce1a8f0741a5684fac3de9701c28Douglas Gregor                                      ClassTemplatePartialSpecialization,
10328e9e9ef5348bce1a8f0741a5684fac3de9701c28Douglas Gregor                                      DC, L, SpecializedTemplate, Builder,
10338e9e9ef5348bce1a8f0741a5684fac3de9701c28Douglas Gregor                                      PrevDecl),
1034833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall      TemplateParams(Params), ArgsAsWritten(ArgInfos),
1035833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall      NumArgsAsWritten(NumArgInfos), InstantiatedFromMember(0, false) { }
1036c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
1037c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregorpublic:
1038c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  static ClassTemplatePartialSpecializationDecl *
1039c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  Create(ASTContext &Context, DeclContext *DC, SourceLocation L,
1040c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor         TemplateParameterList *Params,
1041c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor         ClassTemplateDecl *SpecializedTemplate,
104291fdf6f576b91f023c3bebb0d3786aab555cb3c5Anders Carlsson         TemplateArgumentListBuilder &Builder,
1043d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall         const TemplateArgumentListInfo &ArgInfos,
10443cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall         QualType CanonInjectedType,
1045c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor         ClassTemplatePartialSpecializationDecl *PrevDecl);
1046c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
1047c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  /// Get the list of template parameters
1048c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  TemplateParameterList *getTemplateParameters() const {
1049c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor    return TemplateParams;
1050c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  }
1051c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
1052833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  /// Get the template arguments as written.
1053833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  TemplateArgumentLoc *getTemplateArgsAsWritten() const {
1054833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall    return ArgsAsWritten;
1055833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  }
1056833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall
1057833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  /// Get the number of template arguments as written.
1058833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  unsigned getNumTemplateArgsAsWritten() const {
1059833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall    return NumArgsAsWritten;
1060833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  }
1061833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall
1062ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \brief Retrieve the member class template partial specialization from
1063ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// which this particular class template partial specialization was
1064ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// instantiated.
1065ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ///
1066ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \code
1067ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// template<typename T>
1068ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// struct Outer {
1069ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ///   template<typename U> struct Inner;
1070ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ///   template<typename U> struct Inner<U*> { }; // #1
1071ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// };
1072ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ///
1073ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// Outer<float>::Inner<int*> ii;
1074ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \endcode
1075ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ///
1076ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// In this example, the instantiation of \c Outer<float>::Inner<int*> will
1077ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// end up instantiating the partial specialization
1078ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \c Outer<float>::Inner<U*>, which itself was instantiated from the class
1079ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// template partial specialization \c Outer<T>::Inner<U*>. Given
1080ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \c Outer<float>::Inner<U*>, this function would return
1081ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \c Outer<T>::Inner<U*>.
1082ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ClassTemplatePartialSpecializationDecl *getInstantiatedFromMember() {
1083ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor    ClassTemplatePartialSpecializationDecl *First
1084ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor      = cast<ClassTemplatePartialSpecializationDecl>(getFirstDeclaration());
1085ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor    return First->InstantiatedFromMember.getPointer();
1086ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  }
1087ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor
1088ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  void setInstantiatedFromMember(
1089ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor                          ClassTemplatePartialSpecializationDecl *PartialSpec) {
1090ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor    ClassTemplatePartialSpecializationDecl *First
1091ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor      = cast<ClassTemplatePartialSpecializationDecl>(getFirstDeclaration());
1092ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor    First->InstantiatedFromMember.setPointer(PartialSpec);
1093ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  }
1094ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor
1095ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \brief Determines whether this class template partial specialization
1096ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// template was a specialization of a member partial specialization.
1097ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ///
1098ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// In the following example, the member template partial specialization
1099ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \c X<int>::Inner<T*> is a member specialization.
1100ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ///
1101ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \code
1102ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// template<typename T>
1103ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// struct X {
1104ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ///   template<typename U> struct Inner;
1105ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ///   template<typename U> struct Inner<U*>;
1106ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// };
1107ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ///
1108ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// template<> template<typename T>
1109ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// struct X<int>::Inner<T*> { /* ... */ };
1110ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \endcode
1111ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  bool isMemberSpecialization() {
1112ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor    ClassTemplatePartialSpecializationDecl *First
1113ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor      = cast<ClassTemplatePartialSpecializationDecl>(getFirstDeclaration());
1114ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor    return First->InstantiatedFromMember.getInt();
1115ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  }
1116ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor
1117ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \brief Note that this member template is a specialization.
1118ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  void setMemberSpecialization() {
1119ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor    ClassTemplatePartialSpecializationDecl *First
1120ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor      = cast<ClassTemplatePartialSpecializationDecl>(getFirstDeclaration());
1121ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor    assert(First->InstantiatedFromMember.getPointer() &&
1122ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor           "Only member templates can be member template specializations");
1123ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor    return First->InstantiatedFromMember.setInt(true);
1124ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  }
1125ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor
1126c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  // FIXME: Add Profile support!
1127c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
112880cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
112980cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classofKind(Kind K) {
113080cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall    return K == ClassTemplatePartialSpecialization;
1131c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  }
1132c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
1133c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  static bool classof(const ClassTemplatePartialSpecializationDecl *) {
1134c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor    return true;
1135c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  }
11363e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor};
11373e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
11383e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// Declaration of a class template.
11393e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregorclass ClassTemplateDecl : public TemplateDecl {
11403e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregorprotected:
11415953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  /// \brief Data that is common to all of the declarations of a given
11425953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  /// class template.
11435953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  struct Common {
1144fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor    Common() : InstantiatedFromMember(0, 0) {}
1145e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall
11465953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor    /// \brief The class template specializations for this class
11475953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor    /// template, including explicit specializations and instantiations.
11485953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor    llvm::FoldingSet<ClassTemplateSpecializationDecl> Specializations;
11497da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor
1150c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor    /// \brief The class template partial specializations for this class
1151c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor    /// template.
11521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    llvm::FoldingSet<ClassTemplatePartialSpecializationDecl>
1153c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor      PartialSpecializations;
1154c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
11557da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor    /// \brief The injected-class-name type for this class template.
11567da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor    QualType InjectedClassNameType;
1157e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall
1158e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall    /// \brief The templated member class from which this was most
1159e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall    /// directly instantiated (or null).
1160fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor    ///
1161fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor    /// The boolean value indicates whether this member class template
1162fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor    /// was explicitly specialized.
1163fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor    llvm::PointerIntPair<ClassTemplateDecl *, 1, bool> InstantiatedFromMember;
11645953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  };
11655953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor
1166fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  // FIXME: Combine PreviousDeclaration with CommonPtr, as in
1167fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  // FunctionTemplateDecl.
1168fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor
11697532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas Gregor  /// \brief Previous declaration of this class template.
11705953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  ClassTemplateDecl *PreviousDeclaration;
11715953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor
11725953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  /// \brief Pointer to the data that is common to all of the
11735953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  /// declarations of this class template.
11741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  ///
11755953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  /// The first declaration of a class template (e.g., the declaration
11765953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  /// with no "previous declaration") owns this pointer.
11775953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  Common *CommonPtr;
11781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
11793e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  ClassTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
11805953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor                    TemplateParameterList *Params, NamedDecl *Decl,
11815953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor                    ClassTemplateDecl *PrevDecl, Common *CommonPtr)
11825953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor    : TemplateDecl(ClassTemplate, DC, L, Name, Params, Decl),
11835953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor      PreviousDeclaration(PrevDecl), CommonPtr(CommonPtr) { }
11843e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
11855953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  ~ClassTemplateDecl();
11863e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
11873e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregorpublic:
11883e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  /// Get the underlying class declarations of the template.
11893e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  CXXRecordDecl *getTemplatedDecl() const {
11903e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor    return static_cast<CXXRecordDecl *>(TemplatedDecl);
11913e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
11923e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
11937da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// \brief Retrieve the previous declaration of this template.
11947da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  ClassTemplateDecl *getPreviousDeclaration() const {
11957da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor    return PreviousDeclaration;
11967da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  }
11971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1198b57a4fe73b8227c0dba651818b8495dfca61e530Argyrios Kyrtzidis  virtual ClassTemplateDecl *getCanonicalDecl();
11997da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor
12005953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  /// Create a class template node.
12013e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  static ClassTemplateDecl *Create(ASTContext &C, DeclContext *DC,
12023e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor                                   SourceLocation L,
12033e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor                                   DeclarationName Name,
12043e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor                                   TemplateParameterList *Params,
12055953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor                                   NamedDecl *Decl,
12065953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor                                   ClassTemplateDecl *PrevDecl);
12073e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
12083e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  /// \brief Retrieve the set of specializations of this class template.
12093e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  llvm::FoldingSet<ClassTemplateSpecializationDecl> &getSpecializations() {
12105953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor    return CommonPtr->Specializations;
12113e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
12123e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
1213c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  /// \brief Retrieve the set of partial specializations of this class
1214c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  /// template.
1215c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  llvm::FoldingSet<ClassTemplatePartialSpecializationDecl> &
1216c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  getPartialSpecializations() {
1217c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor    return CommonPtr->PartialSpecializations;
1218c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  }
1219c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
1220b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  /// \brief Find a class template partial specialization with the given
1221b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  /// type T.
1222b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  ///
1223b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  /// \brief A dependent type that names a specialization of this class
1224b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  /// template.
1225b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  ///
1226b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  /// \returns the class template partial specialization that exactly matches
1227b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  /// the type \p T, or NULL if no such partial specialization exists.
1228b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  ClassTemplatePartialSpecializationDecl *findPartialSpecialization(QualType T);
12291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
12303cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall  /// \brief Retrieve the template specialization type of the
12313cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall  /// injected-class-name for this class template.
12327da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  ///
12337da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// The injected-class-name for a class template \c X is \c
12347da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// X<template-args>, where \c template-args is formed from the
12357da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// template arguments that correspond to the template parameters of
12367da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// \c X. For example:
12377da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  ///
12387da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// \code
12397da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// template<typename T, int N>
12407da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// struct array {
12417da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  ///   typedef array this_type; // "array" is equivalent to "array<T, N>"
12427da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// };
12437da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// \endcode
12443cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall  QualType getInjectedClassNameSpecialization(ASTContext &Context);
12457da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor
1246e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// \brief Retrieve the member class template that this class template was
1247e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// derived from.
1248e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  ///
1249e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// This routine will return non-NULL for templated member classes of
1250e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// class templates.  For example, given:
1251e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  ///
1252e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// \code
1253e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// template <typename T>
1254e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// struct X {
1255e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  ///   template <typename U> struct A {};
1256e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// };
1257e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// \endcode
1258e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  ///
1259e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// X<int>::A<float> is a ClassTemplateSpecializationDecl (whose parent
1260e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// is X<int>, also a CTSD) for which getSpecializedTemplate() will
1261e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// return X<int>::A<U>, a TemplateClassDecl (whose parent is again
1262e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// X<int>) for which getInstantiatedFromMemberTemplate() will return
1263e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// X<T>::A<U>, a TemplateClassDecl (whose parent is X<T>, also a TCD).
1264e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  ///
1265e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// \returns null if this is not an instantiation of a member class template.
1266e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  ClassTemplateDecl *getInstantiatedFromMemberTemplate() const {
1267fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor    return CommonPtr->InstantiatedFromMember.getPointer();
1268e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  }
1269e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall
1270e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  void setInstantiatedFromMemberTemplate(ClassTemplateDecl *CTD) {
1271fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor    assert(!CommonPtr->InstantiatedFromMember.getPointer());
1272fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor    CommonPtr->InstantiatedFromMember.setPointer(CTD);
1273e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  }
1274e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall
1275fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  /// \brief Determines whether this template was a specialization of a
1276fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  /// member template.
1277fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  ///
1278fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  /// In the following example, the member template \c X<int>::Inner is a
1279fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  /// member specialization.
1280fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  ///
1281fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  /// \code
1282fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  /// template<typename T>
1283fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  /// struct X {
1284fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  ///   template<typename U> struct Inner;
1285fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  /// };
1286fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  ///
1287fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  /// template<> template<typename T>
1288fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  /// struct X<int>::Inner { /* ... */ };
1289fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  /// \endcode
1290fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  bool isMemberSpecialization() {
1291fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor    return CommonPtr->InstantiatedFromMember.getInt();
1292fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  }
1293fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor
1294fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  /// \brief Note that this member template is a specialization.
1295fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  void setMemberSpecialization() {
1296fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor    assert(CommonPtr->InstantiatedFromMember.getPointer() &&
1297fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor           "Only member templates can be member template specializations");
1298fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor    CommonPtr->InstantiatedFromMember.setInt(true);
1299fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  }
1300fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor
13013e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  // Implement isa/cast/dyncast support
130280cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
130380cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classof(const ClassTemplateDecl *D) { return true; }
130480cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classofKind(Kind K) { return K == ClassTemplate; }
13055953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor
13065953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  virtual void Destroy(ASTContext& C);
13073e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor};
13083e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
1309dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall/// Declaration of a friend template.  For example:
1310dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall///
1311dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall/// template <typename T> class A {
1312dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall///   friend class MyVector<T>; // not a friend template
1313dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall///   template <typename U> friend class B; // friend template
1314dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall///   template <typename U> friend class Foo<T>::Nested; // friend template
1315dd4a3b0065b9a7e7b00073df415a798886c090f3John McCallclass FriendTemplateDecl : public Decl {
1316dd4a3b0065b9a7e7b00073df415a798886c090f3John McCallpublic:
131732f2fb53d9d7c28c94d8569fd0fcf06cccee0c3dJohn McCall  typedef llvm::PointerUnion<NamedDecl*,TypeSourceInfo*> FriendUnion;
1318dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
1319dd4a3b0065b9a7e7b00073df415a798886c090f3John McCallprivate:
1320dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  // The number of template parameters;  always non-zero.
1321dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  unsigned NumParams;
1322dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
1323dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  // The parameter list.
1324dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  TemplateParameterList **Params;
1325dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
1326dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  // The declaration that's a friend of this class.
1327dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  FriendUnion Friend;
1328dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
1329dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  // Location of the 'friend' specifier.
1330dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  SourceLocation FriendLoc;
1331dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
1332dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
1333dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  FriendTemplateDecl(DeclContext *DC, SourceLocation Loc,
1334dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall                     unsigned NParams,
1335dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall                     TemplateParameterList **Params,
1336dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall                     FriendUnion Friend,
1337dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall                     SourceLocation FriendLoc)
1338dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall    : Decl(Decl::FriendTemplate, DC, Loc),
1339dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall      NumParams(NParams),
1340dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall      Params(Params),
1341dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall      Friend(Friend),
1342dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall      FriendLoc(FriendLoc)
1343dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  {}
1344dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
1345dd4a3b0065b9a7e7b00073df415a798886c090f3John McCallpublic:
1346dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  static FriendTemplateDecl *Create(ASTContext &Context,
1347dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall                                    DeclContext *DC, SourceLocation Loc,
1348dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall                                    unsigned NParams,
1349dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall                                    TemplateParameterList **Params,
1350dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall                                    FriendUnion Friend,
1351dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall                                    SourceLocation FriendLoc);
1352dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
1353dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  /// If this friend declaration names a templated type (or
1354dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  /// a dependent member type of a templated type), return that
1355dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  /// type;  otherwise return null.
135632f2fb53d9d7c28c94d8569fd0fcf06cccee0c3dJohn McCall  TypeSourceInfo *getFriendType() const {
135732f2fb53d9d7c28c94d8569fd0fcf06cccee0c3dJohn McCall    return Friend.dyn_cast<TypeSourceInfo*>();
1358dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  }
1359dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
1360dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  /// If this friend declaration names a templated function (or
1361dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  /// a member function of a templated type), return that type;
1362dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  /// otherwise return null.
1363dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  NamedDecl *getFriendDecl() const {
1364dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall    return Friend.dyn_cast<NamedDecl*>();
1365dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  }
1366dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
1367dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  /// Retrieves the location of the 'friend' keyword.
1368dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  SourceLocation getFriendLoc() const {
1369dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall    return FriendLoc;
1370dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  }
1371dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
1372dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  TemplateParameterList *getTemplateParameterList(unsigned i) const {
1373dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall    assert(i <= NumParams);
1374dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall    return Params[i];
1375dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  }
1376dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
1377dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  unsigned getNumTemplateParameters() const {
1378dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall    return NumParams;
1379dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  }
1380dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
1381dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  // Implement isa/cast/dyncast/etc.
138280cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
138380cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classofKind(Kind K) { return K == Decl::FriendTemplate; }
1384dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  static bool classof(const FriendTemplateDecl *D) { return true; }
1385dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall};
1386dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
1387e53060fa78ad7e98352049f72787bdb7543e2a48Douglas Gregor/// Implementation of inline functions that require the template declarations
13881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpinline AnyFunctionDecl::AnyFunctionDecl(FunctionTemplateDecl *FTD)
1389e53060fa78ad7e98352049f72787bdb7543e2a48Douglas Gregor  : Function(FTD) { }
1390e53060fa78ad7e98352049f72787bdb7543e2a48Douglas Gregor
1391aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor} /* end of namespace clang */
1392aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
1393aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor#endif
1394