DeclTemplate.h revision d0913557c800c8a712fb554032a833619f23bc56
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
11598d279ba8092186f606abaa8298f13a0816b9cf2Chris Lattner  llvm::SmallVector<TemplateArgument, 4> 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
13098d279ba8092186f606abaa8298f13a0816b9cf2Chris Lattner  void Append(const TemplateArgument &Arg);
131127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  void BeginPack();
132127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  void EndPack();
1331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
13498d279ba8092186f606abaa8298f13a0816b9cf2Chris Lattner  unsigned flatSize() const { return FlatArgs.size(); }
13598d279ba8092186f606abaa8298f13a0816b9cf2Chris Lattner  const TemplateArgument *getFlatArguments() const { return FlatArgs.data(); }
1361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
137127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned structuredSize() const {
138127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    // If we don't have any structured args, just reuse the flat size.
139127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    if (!StructuredArgs)
140127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      return flatSize();
1411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
142127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return NumStructuredArgs;
143d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  }
144127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  const TemplateArgument *getStructuredArguments() const {
145127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    // If we don't have any structured args, just reuse the flat args.
146127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    if (!StructuredArgs)
147127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      return getFlatArguments();
1481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
149127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return StructuredArgs;
150aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  }
151aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor};
152aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
153127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// \brief A template argument list.
154127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor///
155127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// FIXME: In the future, this class will be extended to support
156127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// variadic templates and member templates, which will make some of
157127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// the function names below make more sense.
158127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorclass TemplateArgumentList {
159127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief The template argument list.
160127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  ///
161127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// The integer value will be non-zero to indicate that this
16256ef550c5eeea0714c635782776389df2a177584Chris Lattner  /// template argument list does own the pointer.
163127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  llvm::PointerIntPair<const TemplateArgument *, 1> FlatArguments;
1641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
165127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief The number of template arguments in this template
166127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// argument list.
167127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned NumFlatArguments;
1681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
169127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  llvm::PointerIntPair<const TemplateArgument *, 1> StructuredArguments;
170127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned NumStructuredArguments;
1711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
172885989109ade7cb4dc493e25da41456c64b3cf6aChris Lattner  TemplateArgumentList(const TemplateArgumentList &Other); // DO NOT IMPL
173885989109ade7cb4dc493e25da41456c64b3cf6aChris Lattner  void operator=(const TemplateArgumentList &Other); // DO NOT IMPL
174aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorpublic:
17556ef550c5eeea0714c635782776389df2a177584Chris Lattner  /// TemplateArgumentList - If this constructor is passed "true" for 'TakeArgs'
17656ef550c5eeea0714c635782776389df2a177584Chris Lattner  /// it copies them into a locally new[]'d array.  If passed "false", then it
17756ef550c5eeea0714c635782776389df2a177584Chris Lattner  /// just references the array passed in.  This is only safe if the builder
17856ef550c5eeea0714c635782776389df2a177584Chris Lattner  /// outlives it, but saves a copy.
179127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateArgumentList(ASTContext &Context,
180127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                       TemplateArgumentListBuilder &Builder,
181127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                       bool TakeArgs);
1821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
183d0913557c800c8a712fb554032a833619f23bc56Argyrios Kyrtzidis  /// TemplateArgumentList - It copies the template arguments into a locally
184d0913557c800c8a712fb554032a833619f23bc56Argyrios Kyrtzidis  /// new[]'d array.
185d0913557c800c8a712fb554032a833619f23bc56Argyrios Kyrtzidis  TemplateArgumentList(ASTContext &Context,
186d0913557c800c8a712fb554032a833619f23bc56Argyrios Kyrtzidis                       unsigned NumArgs, const TemplateArgument *Args);
187d0913557c800c8a712fb554032a833619f23bc56Argyrios Kyrtzidis
188885989109ade7cb4dc493e25da41456c64b3cf6aChris Lattner  /// Produces a shallow copy of the given template argument list.  This
189885989109ade7cb4dc493e25da41456c64b3cf6aChris Lattner  /// assumes that the input argument list outlives it.  This takes the list as
190885989109ade7cb4dc493e25da41456c64b3cf6aChris Lattner  /// a pointer to avoid looking like a copy constructor, since this really
191885989109ade7cb4dc493e25da41456c64b3cf6aChris Lattner  /// really isn't safe to use that way.
192885989109ade7cb4dc493e25da41456c64b3cf6aChris Lattner  explicit TemplateArgumentList(const TemplateArgumentList *Other);
193b9aa6b214c8fbc3e081dde575eef1f0913d48bdcDouglas Gregor
1943458d43b68cc2fd1cb2b2304614e1dc3419820d8Ted Kremenek  /// Used to release the memory associated with a TemplateArgumentList
1953458d43b68cc2fd1cb2b2304614e1dc3419820d8Ted Kremenek  ///  object.  FIXME: This is currently not called anywhere, but the
1963458d43b68cc2fd1cb2b2304614e1dc3419820d8Ted Kremenek  ///  memory will still be freed when using a BumpPtrAllocator.
1973458d43b68cc2fd1cb2b2304614e1dc3419820d8Ted Kremenek  void Destroy(ASTContext &C);
1983458d43b68cc2fd1cb2b2304614e1dc3419820d8Ted Kremenek
199127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  ~TemplateArgumentList();
2001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
201127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the template argument at a given index.
2021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  const TemplateArgument &get(unsigned Idx) const {
203127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    assert(Idx < NumFlatArguments && "Invalid template argument index");
204127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return getFlatArgumentList()[Idx];
205127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  }
2061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
207127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the template argument at a given index.
208127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  const TemplateArgument &operator[](unsigned Idx) const { return get(Idx); }
2091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
210127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the number of template arguments in this
211127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// template argument list.
212127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned size() const { return NumFlatArguments; }
2131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
214127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the number of template arguments in the
215127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// flattened template argument list.
216127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned flat_size() const { return NumFlatArguments; }
2171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
218127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the flattened template argument list.
2191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  const TemplateArgument *getFlatArgumentList() const {
220127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return FlatArguments.getPointer();
221127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  }
222127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor};
2231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
224127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor//===----------------------------------------------------------------------===//
225127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor// Kinds of Templates
226127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor//===----------------------------------------------------------------------===//
227aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
228127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// TemplateDecl - The base class of all kinds of template declarations (e.g.,
229127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// class, function, etc.). The TemplateDecl class stores the list of template
230127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// parameters and a reference to the templated scoped declaration: the
231127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// underlying AST node.
232127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorclass TemplateDecl : public NamedDecl {
233127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorprotected:
234127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // This is probably never used.
235127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
236127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor               DeclarationName Name)
2371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    : NamedDecl(DK, DC, L, Name), TemplatedDecl(0), TemplateParams(0) { }
238d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor
239127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // Construct a template decl with the given name and parameters.
240127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // Used when there is not templated element (tt-params, alias?).
241127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
242127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor               DeclarationName Name, TemplateParameterList *Params)
2431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    : NamedDecl(DK, DC, L, Name), TemplatedDecl(0), TemplateParams(Params) { }
244d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor
245127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // Construct a template decl with name, parameters, and templated element.
246127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
247127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor               DeclarationName Name, TemplateParameterList *Params,
248127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor               NamedDecl *Decl)
249127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    : NamedDecl(DK, DC, L, Name), TemplatedDecl(Decl),
250127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      TemplateParams(Params) { }
251127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorpublic:
252127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  ~TemplateDecl();
253d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor
254127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// Get the list of template parameters
255127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateParameterList *getTemplateParameters() const {
256127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return TemplateParams;
257d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  }
258d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor
259127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// Get the underlying, templated declaration.
260127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  NamedDecl *getTemplatedDecl() const { return TemplatedDecl; }
261127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
262aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  // Implement isa/cast/dyncast/etc.
26380cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
264127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static bool classof(const TemplateDecl *D) { return true; }
265127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static bool classof(const FunctionTemplateDecl *D) { return true; }
266127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static bool classof(const ClassTemplateDecl *D) { return true; }
267aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  static bool classof(const TemplateTemplateParmDecl *D) { return true; }
26880cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classofKind(Kind K) {
2699a55591af3e5506b95a9718e15380129fbfc5ebcSean Hunt    return K >= firstTemplate && K <= lastTemplate;
27080cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  }
271aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
27280484d0de0dccee66d9f1760127c3e6e218987daDouglas Gregor  SourceRange getSourceRange() const {
27380484d0de0dccee66d9f1760127c3e6e218987daDouglas Gregor    return SourceRange(TemplateParams->getTemplateLoc(),
27480484d0de0dccee66d9f1760127c3e6e218987daDouglas Gregor                       TemplatedDecl->getSourceRange().getEnd());
27580484d0de0dccee66d9f1760127c3e6e218987daDouglas Gregor  }
27680484d0de0dccee66d9f1760127c3e6e218987daDouglas Gregor
277127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorprotected:
278127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  NamedDecl *TemplatedDecl;
279127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateParameterList* TemplateParams;
2808731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis
2818731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidispublic:
2828731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis  /// \brief Initialize the underlying templated declaration and
2838731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis  /// template parameters.
2848731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis  void init(NamedDecl *templatedDecl, TemplateParameterList* templateParams) {
2858731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis    assert(TemplatedDecl == 0 && "TemplatedDecl already set!");
2868731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis    assert(TemplateParams == 0 && "TemplateParams already set!");
2878731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis    TemplatedDecl = templatedDecl;
2888731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis    TemplateParams = templateParams;
2898731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis  }
290127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor};
2911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// \brief Provides information about a function template specialization,
293127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// which is a FunctionDecl that has been explicitly specialization or
294127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// instantiated from a function template.
295127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorclass FunctionTemplateSpecializationInfo : public llvm::FoldingSetNode {
296127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorpublic:
2971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// \brief The function template specialization that this structure
298127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// describes.
299127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  FunctionDecl *Function;
3001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// \brief The function template from which this function template
302127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// specialization was generated.
3031fd2dd145d9bcdf0b8d60a88e1795b6ae83656f5Douglas Gregor  ///
304d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor  /// The two bits are contain the top 4 values of TemplateSpecializationKind.
305d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor  llvm::PointerIntPair<FunctionTemplateDecl *, 2> Template;
3061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
307127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief The template arguments used to produce the function template
308127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// specialization from the function template.
309127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  const TemplateArgumentList *TemplateArguments;
3101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
311e03db98d67111ebf7622d9086951aacc24406b66Abramo Bagnara  /// \brief The template arguments as written in the sources, if provided.
312e03db98d67111ebf7622d9086951aacc24406b66Abramo Bagnara  const TemplateArgumentListInfo *TemplateArgumentsAsWritten;
313e03db98d67111ebf7622d9086951aacc24406b66Abramo Bagnara
314b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  /// \brief The point at which this function template specialization was
315b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  /// first instantiated.
316b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  SourceLocation PointOfInstantiation;
317b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor
3181fd2dd145d9bcdf0b8d60a88e1795b6ae83656f5Douglas Gregor  /// \brief Retrieve the template from which this function was specialized.
3191fd2dd145d9bcdf0b8d60a88e1795b6ae83656f5Douglas Gregor  FunctionTemplateDecl *getTemplate() const { return Template.getPointer(); }
320d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor
321d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor  /// \brief Determine what kind of template specialization this is.
322d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor  TemplateSpecializationKind getTemplateSpecializationKind() const {
323d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor    return (TemplateSpecializationKind)(Template.getInt() + 1);
324d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor  }
325d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor
326d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor  /// \brief Set the template specialization kind.
327d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor  void setTemplateSpecializationKind(TemplateSpecializationKind TSK) {
3281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    assert(TSK != TSK_Undeclared &&
329d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor         "Cannot encode TSK_Undeclared for a function template specialization");
330d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor    Template.setInt(TSK - 1);
3311fd2dd145d9bcdf0b8d60a88e1795b6ae83656f5Douglas Gregor  }
3321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
333b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  /// \brief Retrieve the first point of instantiation of this function
334b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  /// template specialization.
335b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  ///
336b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  /// The point of instantiation may be an invalid source location if this
337b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  /// function has yet to be instantiated.
338b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  SourceLocation getPointOfInstantiation() const {
339b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor    return PointOfInstantiation;
340b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  }
341b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor
342b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  /// \brief Set the (first) point of instantiation of this function template
343b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  /// specialization.
344b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  void setPointOfInstantiation(SourceLocation POI) {
345b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor    PointOfInstantiation = POI;
346b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  }
347b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor
348127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  void Profile(llvm::FoldingSetNodeID &ID) {
3491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    Profile(ID, TemplateArguments->getFlatArgumentList(),
350828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor            TemplateArguments->flat_size(),
3511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            Function->getASTContext());
352127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  }
3531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  static void
3551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  Profile(llvm::FoldingSetNodeID &ID, const TemplateArgument *TemplateArgs,
356828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor          unsigned NumTemplateArgs, ASTContext &Context) {
357127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    ID.AddInteger(NumTemplateArgs);
358127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    for (unsigned Arg = 0; Arg != NumTemplateArgs; ++Arg)
359828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor      TemplateArgs[Arg].Profile(ID, Context);
3601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  }
361127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor};
3621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3632db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor/// \brief Provides information a specialization of a member of a class
3642db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor/// template, which may be a member function, static data member, or
3652db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor/// member class.
3662db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregorclass MemberSpecializationInfo {
36744e368b6a85c42d681148ccd5e0052418ff9751eDouglas Gregor  // The member declaration from which this member was instantiated, and the
36844e368b6a85c42d681148ccd5e0052418ff9751eDouglas Gregor  // manner in which the instantiation occurred (in the lower two bits).
36944e368b6a85c42d681148ccd5e0052418ff9751eDouglas Gregor  llvm::PointerIntPair<NamedDecl *, 2> MemberAndTSK;
3702db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor
371b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  // The point at which this member was first instantiated.
372b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  SourceLocation PointOfInstantiation;
373b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor
3742db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregorpublic:
3752db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor  explicit
3762db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor  MemberSpecializationInfo(NamedDecl *IF, TemplateSpecializationKind TSK)
377b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor    : MemberAndTSK(IF, TSK - 1), PointOfInstantiation() {
37844e368b6a85c42d681148ccd5e0052418ff9751eDouglas Gregor    assert(TSK != TSK_Undeclared &&
37944e368b6a85c42d681148ccd5e0052418ff9751eDouglas Gregor           "Cannot encode undeclared template specializations for members");
38044e368b6a85c42d681148ccd5e0052418ff9751eDouglas Gregor  }
3812db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor
3822db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor  /// \brief Retrieve the member declaration from which this member was
3832db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor  /// instantiated.
38444e368b6a85c42d681148ccd5e0052418ff9751eDouglas Gregor  NamedDecl *getInstantiatedFrom() const { return MemberAndTSK.getPointer(); }
3852db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor
3862db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor  /// \brief Determine what kind of template specialization this is.
3872db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor  TemplateSpecializationKind getTemplateSpecializationKind() const {
38844e368b6a85c42d681148ccd5e0052418ff9751eDouglas Gregor    return (TemplateSpecializationKind)(MemberAndTSK.getInt() + 1);
3892db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor  }
3902db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor
3912db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor  /// \brief Set the template specialization kind.
3922db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor  void setTemplateSpecializationKind(TemplateSpecializationKind TSK) {
39344e368b6a85c42d681148ccd5e0052418ff9751eDouglas Gregor    assert(TSK != TSK_Undeclared &&
39444e368b6a85c42d681148ccd5e0052418ff9751eDouglas Gregor           "Cannot encode undeclared template specializations for members");
39544e368b6a85c42d681148ccd5e0052418ff9751eDouglas Gregor    MemberAndTSK.setInt(TSK - 1);
3962db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor  }
397b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor
398b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  /// \brief Retrieve the first point of instantiation of this member.
399b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  /// If the point of instantiation is an invalid location, then this member
400b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  /// has not yet been instantiated.
401b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  SourceLocation getPointOfInstantiation() const {
402b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor    return PointOfInstantiation;
403b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  }
404b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor
405b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  /// \brief Set the first point of instantiation.
406b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  void setPointOfInstantiation(SourceLocation POI) {
407b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor    PointOfInstantiation = POI;
408b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  }
4092db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor};
410af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
411af2094e7cecadf36667deb61a83587ffdd979bd3John McCall/// \brief Provides information about a dependent function-template
412af2094e7cecadf36667deb61a83587ffdd979bd3John McCall/// specialization declaration.  Since explicit function template
413af2094e7cecadf36667deb61a83587ffdd979bd3John McCall/// specialization and instantiation declarations can only appear in
414af2094e7cecadf36667deb61a83587ffdd979bd3John McCall/// namespace scope, and you can only specialize a member of a
415af2094e7cecadf36667deb61a83587ffdd979bd3John McCall/// fully-specialized class, the only way to get one of these is in
416af2094e7cecadf36667deb61a83587ffdd979bd3John McCall/// a friend declaration like the following:
417af2094e7cecadf36667deb61a83587ffdd979bd3John McCall///
418af2094e7cecadf36667deb61a83587ffdd979bd3John McCall///   template <class T> void foo(T);
419af2094e7cecadf36667deb61a83587ffdd979bd3John McCall///   template <class T> class A {
420af2094e7cecadf36667deb61a83587ffdd979bd3John McCall///     friend void foo<>(T);
421af2094e7cecadf36667deb61a83587ffdd979bd3John McCall///   };
422af2094e7cecadf36667deb61a83587ffdd979bd3John McCallclass DependentFunctionTemplateSpecializationInfo {
423af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  union {
424af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    // Force sizeof to be a multiple of sizeof(void*) so that the
425af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    // trailing data is aligned.
426af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    void *Aligner;
427af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
428af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    struct {
429af2094e7cecadf36667deb61a83587ffdd979bd3John McCall      /// The number of potential template candidates.
430af2094e7cecadf36667deb61a83587ffdd979bd3John McCall      unsigned NumTemplates;
431af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
432af2094e7cecadf36667deb61a83587ffdd979bd3John McCall      /// The number of template arguments.
433af2094e7cecadf36667deb61a83587ffdd979bd3John McCall      unsigned NumArgs;
434af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    } d;
435af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  };
436af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
437af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  /// The locations of the left and right angle brackets.
438af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  SourceRange AngleLocs;
439af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
440af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  FunctionTemplateDecl * const *getTemplates() const {
441af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    return reinterpret_cast<FunctionTemplateDecl*const*>(this+1);
442af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  }
443af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
444af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  const TemplateArgumentLoc *getTemplateArgs() const {
445af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    return reinterpret_cast<const TemplateArgumentLoc*>(
44633cab704d9b3b5b0218d578a20593bdfb0b1eb23John McCall             &getTemplates()[getNumTemplates()]);
447af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  }
448af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
449af2094e7cecadf36667deb61a83587ffdd979bd3John McCallpublic:
450af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  DependentFunctionTemplateSpecializationInfo(
451af2094e7cecadf36667deb61a83587ffdd979bd3John McCall                                 const UnresolvedSetImpl &Templates,
452af2094e7cecadf36667deb61a83587ffdd979bd3John McCall                                 const TemplateArgumentListInfo &TemplateArgs);
453af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
454af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  /// \brief Returns the number of function templates that this might
455af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  /// be a specialization of.
456af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  unsigned getNumTemplates() const {
457af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    return d.NumTemplates;
458af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  }
459af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
460af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  /// \brief Returns the i'th template candidate.
461af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  FunctionTemplateDecl *getTemplate(unsigned I) const {
462af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    assert(I < getNumTemplates() && "template index out of range");
463af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    return getTemplates()[I];
464af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  }
465af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
466af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  /// \brief Returns the number of explicit template arguments that were given.
467af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  unsigned getNumTemplateArgs() const {
468af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    return d.NumArgs;
469af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  }
470af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
471af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  /// \brief Returns the nth template argument.
472af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  const TemplateArgumentLoc &getTemplateArg(unsigned I) const {
473af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    assert(I < getNumTemplateArgs() && "template arg index out of range");
474af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    return getTemplateArgs()[I];
475af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  }
476af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
477af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  SourceLocation getLAngleLoc() const {
478af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    return AngleLocs.getBegin();
479af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  }
480af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
481af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  SourceLocation getRAngleLoc() const {
482af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    return AngleLocs.getEnd();
483af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  }
484af2094e7cecadf36667deb61a83587ffdd979bd3John McCall};
4852db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor
486127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// Declaration of a template function.
4871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpclass FunctionTemplateDecl : public TemplateDecl {
4880054531488928a424666ac11fcdc6bcc5112de52Douglas Gregor  static void DeallocateCommon(void *Ptr);
4890054531488928a424666ac11fcdc6bcc5112de52Douglas Gregor
490127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorprotected:
491127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Data that is common to all of the declarations of a given
492127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// function template.
493127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  struct Common {
494fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor    Common() : InstantiatedFromMember(0, false) { }
4951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
496127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    /// \brief The function template specializations for this function
497127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    /// template, including explicit specializations and instantiations.
498127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    llvm::FoldingSet<FunctionTemplateSpecializationInfo> Specializations;
4991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
500d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor    /// \brief The member function template from which this was most
501d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor    /// directly instantiated (or null).
502fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor    ///
503fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor    /// The boolean value indicates whether this member function template
504fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor    /// was explicitly specialized.
505fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor    llvm::PointerIntPair<FunctionTemplateDecl*, 1, bool> InstantiatedFromMember;
5063e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  };
5071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
508127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief A pointer to the previous declaration (if this is a redeclaration)
509127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// or to the data that is common to all declarations of this function
510127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// template.
511127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  llvm::PointerUnion<Common*, FunctionTemplateDecl*> CommonOrPrev;
5121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// \brief Retrieves the "common" pointer shared by all
514127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// (re-)declarations of the same function template. Calling this routine
515127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// may implicitly allocate memory for the common pointer.
516127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  Common *getCommonPtr();
5171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
518127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  FunctionTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
519127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                       TemplateParameterList *Params, NamedDecl *Decl)
520127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    : TemplateDecl(FunctionTemplate, DC, L, Name, Params, Decl),
521127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      CommonOrPrev((Common*)0) { }
5221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5233e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregorpublic:
524127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  void Destroy(ASTContext &C);
5251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
526127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// Get the underlying function declaration of the template.
527127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  FunctionDecl *getTemplatedDecl() const {
528127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return static_cast<FunctionDecl*>(TemplatedDecl);
5293e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
5303e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
531127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the set of function template specializations of this
532127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// function template.
533127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  llvm::FoldingSet<FunctionTemplateSpecializationInfo> &getSpecializations() {
534127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return getCommonPtr()->Specializations;
5353e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
5361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
537127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the previous declaration of this function template, or
538127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// NULL if no such declaration exists.
539127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  const FunctionTemplateDecl *getPreviousDeclaration() const {
540127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return CommonOrPrev.dyn_cast<FunctionTemplateDecl*>();
5413e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
5423e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
543127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the previous declaration of this function template, or
544127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// NULL if no such declaration exists.
545127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  FunctionTemplateDecl *getPreviousDeclaration() {
546127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return CommonOrPrev.dyn_cast<FunctionTemplateDecl*>();
5473e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
5481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
549127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Set the previous declaration of this function template.
550127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  void setPreviousDeclaration(FunctionTemplateDecl *Prev) {
551127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    if (Prev)
552127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      CommonOrPrev = Prev;
553127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  }
5541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
555b57a4fe73b8227c0dba651818b8495dfca61e530Argyrios Kyrtzidis  virtual FunctionTemplateDecl *getCanonicalDecl();
5561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// \brief Retrieve the member function template that this function template
558d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// was instantiated from.
559d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  ///
560d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// This routine will return non-NULL for member function templates of
561d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// class templates.  For example, given:
562d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  ///
563d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// \code
564d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// template <typename T>
565d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// struct X {
566d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  ///   template <typename U> void f();
567d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// };
568d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// \endcode
569d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  ///
570d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// X<int>::A<float> is a CXXMethodDecl (whose parent is X<int>, a
5711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// ClassTemplateSpecializationDecl) for which getPrimaryTemplate() will
572d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// return X<int>::f, a FunctionTemplateDecl (whose parent is again
573d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// X<int>) for which getInstantiatedFromMemberTemplate() will return
5741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// X<T>::f, a FunctionTemplateDecl (whose parent is X<T>, a
575d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// ClassTemplateDecl).
576d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  ///
5771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// \returns NULL if this is not an instantiation of a member function
578d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// template.
579d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  FunctionTemplateDecl *getInstantiatedFromMemberTemplate() {
580fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor    return getCommonPtr()->InstantiatedFromMember.getPointer();
581d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  }
5821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
583d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  void setInstantiatedFromMemberTemplate(FunctionTemplateDecl *FTD) {
584fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor    assert(!getCommonPtr()->InstantiatedFromMember.getPointer());
585fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor    getCommonPtr()->InstantiatedFromMember.setPointer(FTD);
586d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  }
5871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
588fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  /// \brief Determines whether this template was a specialization of a
589fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  /// member template.
590fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  ///
591fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  /// In the following example, the function template \c X<int>::f is a
592fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  /// member specialization.
593fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  ///
594fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  /// \code
595fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  /// template<typename T>
596fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  /// struct X {
597fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  ///   template<typename U> void f(T, U);
598fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  /// };
599fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  ///
600fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  /// template<> template<typename T>
601fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  /// void X<int>::f(int, T);
602fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  /// \endcode
603fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  bool isMemberSpecialization() {
604fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor    return getCommonPtr()->InstantiatedFromMember.getInt();
605fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  }
606fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor
607fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  /// \brief Note that this member template is a specialization.
608fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  void setMemberSpecialization() {
609fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor    assert(getCommonPtr()->InstantiatedFromMember.getPointer() &&
610fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor           "Only member templates can be member template specializations");
611fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor    getCommonPtr()->InstantiatedFromMember.setInt(true);
612fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  }
613fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor
614127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// Create a template function node.
615127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static FunctionTemplateDecl *Create(ASTContext &C, DeclContext *DC,
616127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                      SourceLocation L,
617127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                      DeclarationName Name,
618127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                      TemplateParameterList *Params,
619127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                      NamedDecl *Decl);
6203e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
621127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // Implement isa/cast/dyncast support
62280cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
62380cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classof(const FunctionTemplateDecl *D) { return true; }
62480cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classofKind(Kind K) { return K == FunctionTemplate; }
625127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor};
626d01b1da213aeb71fd40ff7fb78a194613cc1ece7Anders Carlsson
627127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor//===----------------------------------------------------------------------===//
628127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor// Kinds of Template Parameters
629127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor//===----------------------------------------------------------------------===//
63040808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor
631127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// The TemplateParmPosition class defines the position of a template parameter
632127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// within a template parameter list. Because template parameter can be listed
633127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// sequentially for out-of-line template members, each template parameter is
634127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// given a Depth - the nesting of template parameter scopes - and a Position -
635127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// the occurrence within the parameter list.
636127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// This class is inheritedly privately by different kinds of template
637127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// parameters and is not part of the Decl hierarchy. Just a facility.
6381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpclass TemplateParmPosition {
639127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorprotected:
640127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // FIXME: This should probably never be called, but it's here as
641127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateParmPosition()
642127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    : Depth(0), Position(0)
643127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  { /* assert(0 && "Cannot create positionless template parameter"); */ }
6443e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
645127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateParmPosition(unsigned D, unsigned P)
646127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    : Depth(D), Position(P)
647127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  { }
6483e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
649127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // FIXME: These probably don't need to be ints. int:5 for depth, int:8 for
650127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // position? Maybe?
651127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned Depth;
652127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned Position;
6533e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
654127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorpublic:
655127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// Get the nesting depth of the template parameter.
656127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned getDepth() const { return Depth; }
6573e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
658127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// Get the position of the template parameter within its parameter list.
659127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned getPosition() const { return Position; }
6601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
661127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// Get the index of the template parameter within its parameter list.
662127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned getIndex() const { return Position; }
663127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor};
6643e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
665127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// TemplateTypeParmDecl - Declaration of a template type parameter,
666127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// e.g., "T" in
667127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// @code
668127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// template<typename T> class vector;
669127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// @endcode
670127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorclass TemplateTypeParmDecl : public TypeDecl {
671127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Whether this template type parameter was declaration with
672127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// the 'typename' keyword. If false, it was declared with the
673127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// 'class' keyword.
674127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  bool Typename : 1;
6753e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
676127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Whether this template type parameter inherited its
677127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// default argument.
678127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  bool InheritedDefault : 1;
6793e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
680efed5c832de630715dd42211dd3b2aab5dd97a1bDouglas Gregor  /// \brief Whether this is a parameter pack.
681efed5c832de630715dd42211dd3b2aab5dd97a1bDouglas Gregor  bool ParameterPack : 1;
682efed5c832de630715dd42211dd3b2aab5dd97a1bDouglas Gregor
683127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief The default template argument, if any.
684a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall  TypeSourceInfo *DefaultArgument;
685127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
6861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  TemplateTypeParmDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
687efed5c832de630715dd42211dd3b2aab5dd97a1bDouglas Gregor                       bool Typename, QualType Type, bool ParameterPack)
688127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    : TypeDecl(TemplateTypeParm, DC, L, Id), Typename(Typename),
689efed5c832de630715dd42211dd3b2aab5dd97a1bDouglas Gregor      InheritedDefault(false), ParameterPack(ParameterPack), DefaultArgument() {
690efed5c832de630715dd42211dd3b2aab5dd97a1bDouglas Gregor    TypeForDecl = Type.getTypePtr();
691efed5c832de630715dd42211dd3b2aab5dd97a1bDouglas Gregor  }
6923e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
693127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorpublic:
694127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static TemplateTypeParmDecl *Create(ASTContext &C, DeclContext *DC,
695127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                      SourceLocation L, unsigned D, unsigned P,
696127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                      IdentifierInfo *Id, bool Typename,
697127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                      bool ParameterPack);
698c971f8694661776ecdec2ccc33fbe0333eeaf191Douglas Gregor
699127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Whether this template type parameter was declared with
700127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// the 'typename' keyword. If not, it was declared with the 'class'
701127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// keyword.
702127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  bool wasDeclaredWithTypename() const { return Typename; }
703c971f8694661776ecdec2ccc33fbe0333eeaf191Douglas Gregor
704127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Determine whether this template parameter has a default
705127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// argument.
706833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  bool hasDefaultArgument() const { return DefaultArgument != 0; }
707199d99192fbcca9f043596c40ead4afab4999dbaDouglas Gregor
708127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the default argument, if any.
709833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  QualType getDefaultArgument() const { return DefaultArgument->getType(); }
71040808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor
711833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  /// \brief Retrieves the default argument's source information, if any.
712a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall  TypeSourceInfo *getDefaultArgumentInfo() const { return DefaultArgument; }
713833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall
714833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  /// \brief Retrieves the location of the default argument declaration.
715833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  SourceLocation getDefaultArgumentLoc() const;
71640808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor
717127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Determines whether the default argument was inherited
718127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// from a previous declaration of this template.
719127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  bool defaultArgumentWasInherited() const { return InheritedDefault; }
720f670c8cfa58b4c224eb8fb566130dc47844dd3deDouglas Gregor
721127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Set the default argument for this template parameter, and
722127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// whether that default argument was inherited from another
723127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// declaration.
724a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall  void setDefaultArgument(TypeSourceInfo *DefArg, bool Inherited) {
725127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    DefaultArgument = DefArg;
726127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    InheritedDefault = Inherited;
727f670c8cfa58b4c224eb8fb566130dc47844dd3deDouglas Gregor  }
72840808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor
729833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  /// \brief Removes the default argument of this template parameter.
730833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  void removeDefaultArgument() {
731833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall    DefaultArgument = 0;
732833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall    InheritedDefault = false;
733833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  }
7348731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis
7358731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis  /// \brief Set whether this template type parameter was declared with
7368731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis  /// the 'typename' or 'class' keyword.
7378731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis  void setDeclaredWithTypename(bool withTypename) { Typename = withTypename; }
7388731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis
7398731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis  /// \brief Set whether this is a parameter pack.
7408731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis  void setParameterPack(bool isParamPack) { ParameterPack = isParamPack; }
741833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall
742ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \brief Retrieve the depth of the template parameter.
743ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  unsigned getDepth() const;
744ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor
745ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \brief Retrieve the index of the template parameter.
746ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  unsigned getIndex() const;
747ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor
748127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Returns whether this is a parameter pack.
749efed5c832de630715dd42211dd3b2aab5dd97a1bDouglas Gregor  bool isParameterPack() const { return ParameterPack; }
750fb25052736439d72a557cddd41dfb927bcb3d3e5Anders Carlsson
751127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // Implement isa/cast/dyncast/etc.
75280cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
753127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static bool classof(const TemplateTypeParmDecl *D) { return true; }
75480cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classofKind(Kind K) { return K == TemplateTypeParm; }
7553e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor};
7563e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
757127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// NonTypeTemplateParmDecl - Declares a non-type template parameter,
758127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// e.g., "Size" in
759127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// @code
760127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// template<int Size> class array { };
761127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// @endcode
762127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorclass NonTypeTemplateParmDecl
763127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  : public VarDecl, protected TemplateParmPosition {
764d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// \brief The default template argument, if any, and whether or not
765d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// it was inherited.
766d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  llvm::PointerIntPair<Expr*, 1, bool> DefaultArgumentAndInherited;
767127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
768127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  NonTypeTemplateParmDecl(DeclContext *DC, SourceLocation L, unsigned D,
769127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                          unsigned P, IdentifierInfo *Id, QualType T,
770a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall                          TypeSourceInfo *TInfo)
77116573fa9705b546b7597c273b25b85d6321e2b33Douglas Gregor    : VarDecl(NonTypeTemplateParm, DC, L, Id, T, TInfo, VarDecl::None,
77216573fa9705b546b7597c273b25b85d6321e2b33Douglas Gregor              VarDecl::None),
773d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara      TemplateParmPosition(D, P), DefaultArgumentAndInherited(0, false)
774127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  { }
775127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
7761c5976e5e933c0d74f7e04e8f907a93f5edbfec1Anders Carlssonpublic:
777127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static NonTypeTemplateParmDecl *
778127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  Create(ASTContext &C, DeclContext *DC, SourceLocation L, unsigned D,
779a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall         unsigned P, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo);
7809ba41645892da0000fe8a7832b80208f44dafedaAnders Carlsson
781127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  using TemplateParmPosition::getDepth;
782127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  using TemplateParmPosition::getPosition;
783127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  using TemplateParmPosition::getIndex;
7841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
785127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Determine whether this template parameter has a default
786127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// argument.
787d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  bool hasDefaultArgument() const {
788d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara    return DefaultArgumentAndInherited.getPointer() != 0;
789d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  }
790fb25052736439d72a557cddd41dfb927bcb3d3e5Anders Carlsson
791127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the default argument, if any.
792d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  Expr *getDefaultArgument() const {
793d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara    return DefaultArgumentAndInherited.getPointer();
794d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  }
795127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
796127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the location of the default argument, if any.
797127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  SourceLocation getDefaultArgumentLoc() const;
798127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
799d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// \brief Determines whether the default argument was inherited
800d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// from a previous declaration of this template.
801d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  bool defaultArgumentWasInherited() const {
802d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara    return DefaultArgumentAndInherited.getInt();
803d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  }
804d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara
805d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// \brief Set the default argument for this template parameter, and
806d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// whether that default argument was inherited from another
807d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// declaration.
808d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  void setDefaultArgument(Expr *DefArg, bool Inherited) {
809d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara    DefaultArgumentAndInherited.setPointer(DefArg);
810d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara    DefaultArgumentAndInherited.setInt(Inherited);
811d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  }
812d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara
813d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// \brief Removes the default argument of this template parameter.
814d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  void removeDefaultArgument() {
815d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara    DefaultArgumentAndInherited.setPointer(0);
816d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara    DefaultArgumentAndInherited.setInt(false);
8173b36b66a00b7d5bab71b486a54694f0ae397bddbAnders Carlsson  }
818127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
819127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // Implement isa/cast/dyncast/etc.
82080cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
821127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static bool classof(const NonTypeTemplateParmDecl *D) { return true; }
82280cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classofKind(Kind K) { return K == NonTypeTemplateParm; }
8231c5976e5e933c0d74f7e04e8f907a93f5edbfec1Anders Carlsson};
8241c5976e5e933c0d74f7e04e8f907a93f5edbfec1Anders Carlsson
825127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// TemplateTemplateParmDecl - Declares a template template parameter,
826127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// e.g., "T" in
827127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// @code
828127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// template <template <typename> class T> class container { };
829127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// @endcode
830127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// A template template parameter is a TemplateDecl because it defines the
831127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// name of a template and the template parameters allowable for substitution.
832127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorclass TemplateTemplateParmDecl
833127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  : public TemplateDecl, protected TemplateParmPosition {
8347e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
835d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// DefaultArgument - The default template argument, if any.
836788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor  TemplateArgumentLoc DefaultArgument;
837d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// Whether or not the default argument was inherited.
838d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  bool DefaultArgumentWasInherited;
8397e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
840127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L,
841127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                           unsigned D, unsigned P,
842127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                           IdentifierInfo *Id, TemplateParameterList *Params)
843127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
844d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara      TemplateParmPosition(D, P), DefaultArgument(),
845d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara      DefaultArgumentWasInherited(false)
846127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    { }
8477e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
848127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorpublic:
849127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static TemplateTemplateParmDecl *Create(ASTContext &C, DeclContext *DC,
850127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                          SourceLocation L, unsigned D,
851127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                          unsigned P, IdentifierInfo *Id,
852127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                          TemplateParameterList *Params);
8537e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
854127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  using TemplateParmPosition::getDepth;
855127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  using TemplateParmPosition::getPosition;
856127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  using TemplateParmPosition::getIndex;
8571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
858127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Determine whether this template parameter has a default
859127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// argument.
860d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  bool hasDefaultArgument() const {
861d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara    return !DefaultArgument.getArgument().isNull();
862788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor  }
8637e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
864127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the default argument, if any.
865d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  const TemplateArgumentLoc &getDefaultArgument() const {
866d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara    return DefaultArgument;
867d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  }
868d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara
869d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// \brief Retrieve the location of the default argument, if any.
870d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  SourceLocation getDefaultArgumentLoc() const;
871d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara
872d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// \brief Determines whether the default argument was inherited
873d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// from a previous declaration of this template.
874d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  bool defaultArgumentWasInherited() const {
875d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara    return DefaultArgumentWasInherited;
876788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor  }
8777e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
878d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// \brief Set the default argument for this template parameter, and
879d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// whether that default argument was inherited from another
880d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// declaration.
881d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  void setDefaultArgument(const TemplateArgumentLoc &DefArg, bool Inherited) {
882127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    DefaultArgument = DefArg;
883d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara    DefaultArgumentWasInherited = Inherited;
884d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  }
885d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara
886d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// \brief Removes the default argument of this template parameter.
887d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  void removeDefaultArgument() {
888d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara    DefaultArgument = TemplateArgumentLoc();
889d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara    DefaultArgumentWasInherited = false;
890127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  }
8917e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
892127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // Implement isa/cast/dyncast/etc.
89380cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
894127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static bool classof(const TemplateTemplateParmDecl *D) { return true; }
89580cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classofKind(Kind K) { return K == TemplateTemplateParm; }
8967e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor};
8977e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
8983e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// \brief Represents a class template specialization, which refers to
8993e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// a class template with a given set of template arguments.
9003e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor///
9013e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// Class template specializations represent both explicit
9023e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// specialization of class templates, as in the example below, and
9033e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// implicit instantiations of class templates.
9043e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor///
9053e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// \code
9063e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// template<typename T> class array;
9071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///
9081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// template<>
9093e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// class array<bool> { }; // class template specialization array<bool>
9103e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// \endcode
9111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpclass ClassTemplateSpecializationDecl
9123e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  : public CXXRecordDecl, public llvm::FoldingSetNode {
9131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
9141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// \brief Structure that stores information about a class template
91537d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// specialization that was instantiated from a class template partial
91637d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// specialization.
91737d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  struct SpecializedPartialSpecialization {
91837d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    /// \brief The class template partial specialization from which this
91937d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    /// class template specialization was instantiated.
92037d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    ClassTemplatePartialSpecializationDecl *PartialSpecialization;
9211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
92237d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    /// \brief The template argument list deduced for the class template
92337d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    /// partial specialization itself.
92437d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    TemplateArgumentList *TemplateArgs;
92537d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  };
9261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
9273e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  /// \brief The template that this specialization specializes
92837d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  llvm::PointerUnion<ClassTemplateDecl *, SpecializedPartialSpecialization *>
92937d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    SpecializedTemplate;
9303e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
931c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  /// \brief Further info for explicit template specialization/instantiation.
932c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  struct ExplicitSpecializationInfo {
933c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara    /// \brief The type-as-written.
934c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara    TypeSourceInfo *TypeAsWritten;
935c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara    /// \brief The location of the extern keyword.
936c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara    SourceLocation ExternLoc;
937c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara    /// \brief The location of the template keyword.
938c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara    SourceLocation TemplateKeywordLoc;
939c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara
940c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara    ExplicitSpecializationInfo()
941c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara      : TypeAsWritten(0), ExternLoc(), TemplateKeywordLoc() {}
942c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  };
943c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara
944c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  /// \brief Further info for explicit template specialization/instantiation.
9453cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall  /// Does not apply to implicit specializations.
946c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  ExplicitSpecializationInfo *ExplicitInfo;
9473cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall
9487e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor  /// \brief The template arguments used to describe this specialization.
9497e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor  TemplateArgumentList TemplateArgs;
950cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor
9519cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall  /// \brief The point where this template was instantiated (if any)
9529cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall  SourceLocation PointOfInstantiation;
9539cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall
954cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  /// \brief The kind of specialization this declaration refers to.
955cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  /// Really a value of type TemplateSpecializationKind.
956d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor  unsigned SpecializationKind : 3;
957cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor
958c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregorprotected:
95913c8577201e4fc0ddac5f09d05fd1778832137d1Douglas Gregor  ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
9607e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor                                  DeclContext *DC, SourceLocation L,
9613e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor                                  ClassTemplateDecl *SpecializedTemplate,
9628e9e9ef5348bce1a8f0741a5684fac3de9701c28Douglas Gregor                                  TemplateArgumentListBuilder &Builder,
9638e9e9ef5348bce1a8f0741a5684fac3de9701c28Douglas Gregor                                  ClassTemplateSpecializationDecl *PrevDecl);
9641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
9653e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregorpublic:
9663e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  static ClassTemplateSpecializationDecl *
96713c8577201e4fc0ddac5f09d05fd1778832137d1Douglas Gregor  Create(ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation L,
9683e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor         ClassTemplateDecl *SpecializedTemplate,
96991fdf6f576b91f023c3bebb0d3786aab555cb3c5Anders Carlsson         TemplateArgumentListBuilder &Builder,
970cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor         ClassTemplateSpecializationDecl *PrevDecl);
9713e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
97237d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  virtual void Destroy(ASTContext& C);
97337d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor
974136a6988960ac3aeb96f298da7a1a182db7217cdJohn McCall  virtual void getNameForDiagnostic(std::string &S,
975136a6988960ac3aeb96f298da7a1a182db7217cdJohn McCall                                    const PrintingPolicy &Policy,
976136a6988960ac3aeb96f298da7a1a182db7217cdJohn McCall                                    bool Qualified) const;
977136a6988960ac3aeb96f298da7a1a182db7217cdJohn McCall
9783e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  /// \brief Retrieve the template that this specialization specializes.
97937d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  ClassTemplateDecl *getSpecializedTemplate() const;
9803e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
9811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// \brief Retrieve the template arguments of the class template
98237d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// specialization.
9831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  const TemplateArgumentList &getTemplateArgs() const {
9847e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor    return TemplateArgs;
9853e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
9863e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
987cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  /// \brief Determine the kind of specialization that this
988cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  /// declaration represents.
989cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  TemplateSpecializationKind getSpecializationKind() const {
990cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor    return static_cast<TemplateSpecializationKind>(SpecializationKind);
991cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  }
992cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor
993cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  void setSpecializationKind(TemplateSpecializationKind TSK) {
994cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor    SpecializationKind = TSK;
995cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  }
996cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor
9979cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall  /// \brief Get the point of instantiation (if any), or null if none.
9989cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall  SourceLocation getPointOfInstantiation() const {
9999cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall    return PointOfInstantiation;
10009cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall  }
10019cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall
10029cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall  void setPointOfInstantiation(SourceLocation Loc) {
10039cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall    assert(Loc.isValid() && "point of instantiation must be valid!");
10049cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall    PointOfInstantiation = Loc;
10059cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall  }
10069cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall
100737d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// \brief If this class template specialization is an instantiation of
100837d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// a template (rather than an explicit specialization), return the
100937d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// class template or class template partial specialization from which it
101037d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// was instantiated.
10111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  llvm::PointerUnion<ClassTemplateDecl *,
101237d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor                     ClassTemplatePartialSpecializationDecl *>
101337d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  getInstantiatedFrom() const {
101437d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    if (getSpecializationKind() != TSK_ImplicitInstantiation &&
1015d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor        getSpecializationKind() != TSK_ExplicitInstantiationDefinition &&
1016d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor        getSpecializationKind() != TSK_ExplicitInstantiationDeclaration)
101737d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor      return (ClassTemplateDecl*)0;
10181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
10191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    if (SpecializedPartialSpecialization *PartialSpec
102037d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor          = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
102137d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor      return PartialSpec->PartialSpecialization;
10221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
102337d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    return const_cast<ClassTemplateDecl*>(
102437d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor                             SpecializedTemplate.get<ClassTemplateDecl*>());
102537d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  }
10261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
102737d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// \brief Retrieve the set of template arguments that should be used
102837d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// to instantiate members of the class template or class template partial
102937d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// specialization from which this class template specialization was
103037d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// instantiated.
103137d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  ///
103237d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// \returns For a class template specialization instantiated from the primary
103337d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// template, this function will return the same template arguments as
103437d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// getTemplateArgs(). For a class template specialization instantiated from
103537d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// a class template partial specialization, this function will return the
103637d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// deduced template arguments for the class template partial specialization
103737d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// itself.
103837d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  const TemplateArgumentList &getTemplateInstantiationArgs() const {
10391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    if (SpecializedPartialSpecialization *PartialSpec
104037d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor        = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
104137d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor      return *PartialSpec->TemplateArgs;
10421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
104337d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    return getTemplateArgs();
104437d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  }
10451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
104637d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// \brief Note that this class template specialization is actually an
104737d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// instantiation of the given class template partial specialization whose
104837d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// template arguments have been deduced.
104937d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  void setInstantiationOf(ClassTemplatePartialSpecializationDecl *PartialSpec,
105037d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor                          TemplateArgumentList *TemplateArgs) {
10511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    SpecializedPartialSpecialization *PS
105237d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor      = new (getASTContext()) SpecializedPartialSpecialization();
105337d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    PS->PartialSpecialization = PartialSpec;
105437d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    PS->TemplateArgs = TemplateArgs;
105537d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    SpecializedTemplate = PS;
105637d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  }
10571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1058fc705b84347e6fb4746a1a7e26949f64c2f2f358Douglas Gregor  /// \brief Sets the type of this specialization as it was written by
1059fc705b84347e6fb4746a1a7e26949f64c2f2f358Douglas Gregor  /// the user. This will be a class template specialization type.
10603cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall  void setTypeAsWritten(TypeSourceInfo *T) {
1061c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara    if (!ExplicitInfo) ExplicitInfo = new ExplicitSpecializationInfo;
1062c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara    ExplicitInfo->TypeAsWritten = T;
10633cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall  }
10643cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall  /// \brief Gets the type of this specialization as it was written by
10653cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall  /// the user, if it was so written.
10663cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall  TypeSourceInfo *getTypeAsWritten() const {
1067c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara    return ExplicitInfo ? ExplicitInfo->TypeAsWritten : 0;
1068c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  }
1069c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara
1070c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  /// \brief Gets the location of the extern keyword, if present.
1071c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  SourceLocation getExternLoc() const {
1072c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara    return ExplicitInfo ? ExplicitInfo->ExternLoc : SourceLocation();
1073c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  }
1074c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  /// \brief Sets the location of the extern keyword.
1075c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  void setExternLoc(SourceLocation Loc) {
1076c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara    if (!ExplicitInfo) ExplicitInfo = new ExplicitSpecializationInfo;
1077c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara    ExplicitInfo->ExternLoc = Loc;
1078c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  }
1079c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara
1080c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  /// \brief Sets the location of the template keyword.
1081c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  void setTemplateKeywordLoc(SourceLocation Loc) {
1082c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara    if (!ExplicitInfo) ExplicitInfo = new ExplicitSpecializationInfo;
1083c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara    ExplicitInfo->TemplateKeywordLoc = Loc;
1084c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  }
1085c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  /// \brief Gets the location of the template keyword, if present.
1086c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  SourceLocation getTemplateKeywordLoc() const {
1087c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara    return ExplicitInfo ? ExplicitInfo->TemplateKeywordLoc : SourceLocation();
1088fc705b84347e6fb4746a1a7e26949f64c2f2f358Douglas Gregor  }
1089fc705b84347e6fb4746a1a7e26949f64c2f2f358Douglas Gregor
1090c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  void Profile(llvm::FoldingSetNodeID &ID) const {
1091828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor    Profile(ID, TemplateArgs.getFlatArgumentList(), TemplateArgs.flat_size(),
1092828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor            getASTContext());
1093c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  }
1094c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
10951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  static void
10961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  Profile(llvm::FoldingSetNodeID &ID, const TemplateArgument *TemplateArgs,
1097828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor          unsigned NumTemplateArgs, ASTContext &Context) {
10980ceffb51b28b09db67404058c642dcb1f877f6e8Anders Carlsson    ID.AddInteger(NumTemplateArgs);
10993e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor    for (unsigned Arg = 0; Arg != NumTemplateArgs; ++Arg)
1100828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor      TemplateArgs[Arg].Profile(ID, Context);
11013e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
11023e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
110380cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
110480cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classofKind(Kind K) {
11059a55591af3e5506b95a9718e15380129fbfc5ebcSean Hunt    return K >= firstClassTemplateSpecialization &&
11069a55591af3e5506b95a9718e15380129fbfc5ebcSean Hunt           K <= lastClassTemplateSpecialization;
11073e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
11083e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
11093e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  static bool classof(const ClassTemplateSpecializationDecl *) {
11103e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor    return true;
11113e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
1112c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
1113c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  static bool classof(const ClassTemplatePartialSpecializationDecl *) {
1114c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor    return true;
1115c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  }
1116c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor};
1117c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
11181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpclass ClassTemplatePartialSpecializationDecl
11191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  : public ClassTemplateSpecializationDecl {
11201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// \brief The list of template parameters
1121c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  TemplateParameterList* TemplateParams;
1122c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
1123833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  /// \brief The source info for the template arguments as written.
11243cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall  /// FIXME: redundant with TypeAsWritten?
1125833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  TemplateArgumentLoc *ArgsAsWritten;
1126833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  unsigned NumArgsAsWritten;
1127833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall
1128dc60c1eb4acbde6edcec9760de92f9098593d915Douglas Gregor  /// \brief Sequence number indicating when this class template partial
1129dc60c1eb4acbde6edcec9760de92f9098593d915Douglas Gregor  /// specialization was added to the set of partial specializations for
1130dc60c1eb4acbde6edcec9760de92f9098593d915Douglas Gregor  /// its owning class template.
1131dc60c1eb4acbde6edcec9760de92f9098593d915Douglas Gregor  unsigned SequenceNumber;
1132dc60c1eb4acbde6edcec9760de92f9098593d915Douglas Gregor
1133ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \brief The class template partial specialization from which this
1134ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// class template partial specialization was instantiated.
1135ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ///
1136ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// The boolean value will be true to indicate that this class template
1137ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// partial specialization was specialized at this level.
1138ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  llvm::PointerIntPair<ClassTemplatePartialSpecializationDecl *, 1, bool>
1139ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor      InstantiatedFromMember;
1140ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor
114113c8577201e4fc0ddac5f09d05fd1778832137d1Douglas Gregor  ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK,
1142c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor                                         DeclContext *DC, SourceLocation L,
1143c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor                                         TemplateParameterList *Params,
1144c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor                                         ClassTemplateDecl *SpecializedTemplate,
11458e9e9ef5348bce1a8f0741a5684fac3de9701c28Douglas Gregor                                         TemplateArgumentListBuilder &Builder,
1146833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall                                         TemplateArgumentLoc *ArgInfos,
1147833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall                                         unsigned NumArgInfos,
1148dc60c1eb4acbde6edcec9760de92f9098593d915Douglas Gregor                               ClassTemplatePartialSpecializationDecl *PrevDecl,
1149dc60c1eb4acbde6edcec9760de92f9098593d915Douglas Gregor                                         unsigned SequenceNumber)
11501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    : ClassTemplateSpecializationDecl(Context,
11518e9e9ef5348bce1a8f0741a5684fac3de9701c28Douglas Gregor                                      ClassTemplatePartialSpecialization,
115213c8577201e4fc0ddac5f09d05fd1778832137d1Douglas Gregor                                      TK, DC, L, SpecializedTemplate, Builder,
11538e9e9ef5348bce1a8f0741a5684fac3de9701c28Douglas Gregor                                      PrevDecl),
1154833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall      TemplateParams(Params), ArgsAsWritten(ArgInfos),
1155dc60c1eb4acbde6edcec9760de92f9098593d915Douglas Gregor      NumArgsAsWritten(NumArgInfos), SequenceNumber(SequenceNumber),
1156dc60c1eb4acbde6edcec9760de92f9098593d915Douglas Gregor      InstantiatedFromMember(0, false) { }
1157c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
1158c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregorpublic:
1159c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  static ClassTemplatePartialSpecializationDecl *
116013c8577201e4fc0ddac5f09d05fd1778832137d1Douglas Gregor  Create(ASTContext &Context, TagKind TK,DeclContext *DC, SourceLocation L,
1161c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor         TemplateParameterList *Params,
1162c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor         ClassTemplateDecl *SpecializedTemplate,
116391fdf6f576b91f023c3bebb0d3786aab555cb3c5Anders Carlsson         TemplateArgumentListBuilder &Builder,
1164d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall         const TemplateArgumentListInfo &ArgInfos,
11653cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall         QualType CanonInjectedType,
1166dc60c1eb4acbde6edcec9760de92f9098593d915Douglas Gregor         ClassTemplatePartialSpecializationDecl *PrevDecl,
1167dc60c1eb4acbde6edcec9760de92f9098593d915Douglas Gregor         unsigned SequenceNumber);
1168c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
1169c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  /// Get the list of template parameters
1170c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  TemplateParameterList *getTemplateParameters() const {
1171c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor    return TemplateParams;
1172c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  }
1173c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
1174833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  /// Get the template arguments as written.
1175833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  TemplateArgumentLoc *getTemplateArgsAsWritten() const {
1176833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall    return ArgsAsWritten;
1177833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  }
1178833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall
1179833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  /// Get the number of template arguments as written.
1180833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  unsigned getNumTemplateArgsAsWritten() const {
1181833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall    return NumArgsAsWritten;
1182833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  }
1183833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall
1184dc60c1eb4acbde6edcec9760de92f9098593d915Douglas Gregor  /// \brief Get the sequence number for this class template partial
1185dc60c1eb4acbde6edcec9760de92f9098593d915Douglas Gregor  /// specialization.
1186dc60c1eb4acbde6edcec9760de92f9098593d915Douglas Gregor  unsigned getSequenceNumber() const { return SequenceNumber; }
1187dc60c1eb4acbde6edcec9760de92f9098593d915Douglas Gregor
1188ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \brief Retrieve the member class template partial specialization from
1189ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// which this particular class template partial specialization was
1190ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// instantiated.
1191ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ///
1192ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \code
1193ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// template<typename T>
1194ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// struct Outer {
1195ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ///   template<typename U> struct Inner;
1196ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ///   template<typename U> struct Inner<U*> { }; // #1
1197ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// };
1198ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ///
1199ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// Outer<float>::Inner<int*> ii;
1200ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \endcode
1201ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ///
1202ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// In this example, the instantiation of \c Outer<float>::Inner<int*> will
1203ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// end up instantiating the partial specialization
1204ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \c Outer<float>::Inner<U*>, which itself was instantiated from the class
1205ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// template partial specialization \c Outer<T>::Inner<U*>. Given
1206ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \c Outer<float>::Inner<U*>, this function would return
1207ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \c Outer<T>::Inner<U*>.
1208ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ClassTemplatePartialSpecializationDecl *getInstantiatedFromMember() {
1209ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor    ClassTemplatePartialSpecializationDecl *First
1210ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor      = cast<ClassTemplatePartialSpecializationDecl>(getFirstDeclaration());
1211ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor    return First->InstantiatedFromMember.getPointer();
1212ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  }
1213ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor
1214ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  void setInstantiatedFromMember(
1215ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor                          ClassTemplatePartialSpecializationDecl *PartialSpec) {
1216ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor    ClassTemplatePartialSpecializationDecl *First
1217ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor      = cast<ClassTemplatePartialSpecializationDecl>(getFirstDeclaration());
1218ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor    First->InstantiatedFromMember.setPointer(PartialSpec);
1219ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  }
1220ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor
1221ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \brief Determines whether this class template partial specialization
1222ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// template was a specialization of a member partial specialization.
1223ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ///
1224ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// In the following example, the member template partial specialization
1225ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \c X<int>::Inner<T*> is a member specialization.
1226ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ///
1227ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \code
1228ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// template<typename T>
1229ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// struct X {
1230ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ///   template<typename U> struct Inner;
1231ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ///   template<typename U> struct Inner<U*>;
1232ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// };
1233ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ///
1234ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// template<> template<typename T>
1235ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// struct X<int>::Inner<T*> { /* ... */ };
1236ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \endcode
1237ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  bool isMemberSpecialization() {
1238ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor    ClassTemplatePartialSpecializationDecl *First
1239ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor      = cast<ClassTemplatePartialSpecializationDecl>(getFirstDeclaration());
1240ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor    return First->InstantiatedFromMember.getInt();
1241ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  }
1242ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor
1243ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \brief Note that this member template is a specialization.
1244ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  void setMemberSpecialization() {
1245ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor    ClassTemplatePartialSpecializationDecl *First
1246ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor      = cast<ClassTemplatePartialSpecializationDecl>(getFirstDeclaration());
1247ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor    assert(First->InstantiatedFromMember.getPointer() &&
1248ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor           "Only member templates can be member template specializations");
1249ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor    return First->InstantiatedFromMember.setInt(true);
1250ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  }
125131f17ecbef57b5679c017c375db330546b7b5145John McCall
125231f17ecbef57b5679c017c375db330546b7b5145John McCall  /// Retrieves the injected specialization type for this partial
125331f17ecbef57b5679c017c375db330546b7b5145John McCall  /// specialization.  This is not the same as the type-decl-type for
125431f17ecbef57b5679c017c375db330546b7b5145John McCall  /// this partial specialization, which is an InjectedClassNameType.
125531f17ecbef57b5679c017c375db330546b7b5145John McCall  QualType getInjectedSpecializationType() const {
125631f17ecbef57b5679c017c375db330546b7b5145John McCall    assert(getTypeForDecl() && "partial specialization has no type set!");
125731f17ecbef57b5679c017c375db330546b7b5145John McCall    return cast<InjectedClassNameType>(getTypeForDecl())
125831f17ecbef57b5679c017c375db330546b7b5145John McCall             ->getInjectedSpecializationType();
125931f17ecbef57b5679c017c375db330546b7b5145John McCall  }
1260ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor
1261c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  // FIXME: Add Profile support!
1262c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
126380cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
126480cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classofKind(Kind K) {
126580cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall    return K == ClassTemplatePartialSpecialization;
1266c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  }
1267c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
1268c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  static bool classof(const ClassTemplatePartialSpecializationDecl *) {
1269c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor    return true;
1270c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  }
12713e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor};
12723e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
12733e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// Declaration of a class template.
12743e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregorclass ClassTemplateDecl : public TemplateDecl {
12750054531488928a424666ac11fcdc6bcc5112de52Douglas Gregor  static void DeallocateCommon(void *Ptr);
12760054531488928a424666ac11fcdc6bcc5112de52Douglas Gregor
12773e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregorprotected:
12785953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  /// \brief Data that is common to all of the declarations of a given
12795953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  /// class template.
12805953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  struct Common {
1281fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor    Common() : InstantiatedFromMember(0, 0) {}
1282e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall
12835953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor    /// \brief The class template specializations for this class
12845953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor    /// template, including explicit specializations and instantiations.
12855953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor    llvm::FoldingSet<ClassTemplateSpecializationDecl> Specializations;
12867da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor
1287c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor    /// \brief The class template partial specializations for this class
1288c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor    /// template.
12891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    llvm::FoldingSet<ClassTemplatePartialSpecializationDecl>
1290c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor      PartialSpecializations;
1291c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
12927da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor    /// \brief The injected-class-name type for this class template.
12937da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor    QualType InjectedClassNameType;
1294e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall
1295e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall    /// \brief The templated member class from which this was most
1296e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall    /// directly instantiated (or null).
1297fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor    ///
1298fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor    /// The boolean value indicates whether this member class template
1299fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor    /// was explicitly specialized.
1300fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor    llvm::PointerIntPair<ClassTemplateDecl *, 1, bool> InstantiatedFromMember;
13015953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  };
13025953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor
13035bf1bdc2fedb0c29b5fcdb4abc852aa85b4fe26aArgyrios Kyrtzidis  /// \brief A pointer to the previous declaration (if this is a redeclaration)
13045bf1bdc2fedb0c29b5fcdb4abc852aa85b4fe26aArgyrios Kyrtzidis  /// or to the data that is common to all declarations of this class template.
13055bf1bdc2fedb0c29b5fcdb4abc852aa85b4fe26aArgyrios Kyrtzidis  llvm::PointerUnion<Common*, ClassTemplateDecl*> CommonOrPrev;
13065953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor
13075bf1bdc2fedb0c29b5fcdb4abc852aa85b4fe26aArgyrios Kyrtzidis  /// \brief Retrieves the "common" pointer shared by all
13085bf1bdc2fedb0c29b5fcdb4abc852aa85b4fe26aArgyrios Kyrtzidis  /// (re-)declarations of the same class template. Calling this routine
13095bf1bdc2fedb0c29b5fcdb4abc852aa85b4fe26aArgyrios Kyrtzidis  /// may implicitly allocate memory for the common pointer.
13105bf1bdc2fedb0c29b5fcdb4abc852aa85b4fe26aArgyrios Kyrtzidis  Common *getCommonPtr();
13111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
13123e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  ClassTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
13138731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis                    TemplateParameterList *Params, NamedDecl *Decl)
13145953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor    : TemplateDecl(ClassTemplate, DC, L, Name, Params, Decl),
13155bf1bdc2fedb0c29b5fcdb4abc852aa85b4fe26aArgyrios Kyrtzidis      CommonOrPrev((Common*)0) { }
13163e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
13173e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregorpublic:
13183e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  /// Get the underlying class declarations of the template.
13193e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  CXXRecordDecl *getTemplatedDecl() const {
13203e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor    return static_cast<CXXRecordDecl *>(TemplatedDecl);
13213e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
13223e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
13235bf1bdc2fedb0c29b5fcdb4abc852aa85b4fe26aArgyrios Kyrtzidis  /// \brief Retrieve the previous declaration of this class template, or
13245bf1bdc2fedb0c29b5fcdb4abc852aa85b4fe26aArgyrios Kyrtzidis  /// NULL if no such declaration exists.
13255bf1bdc2fedb0c29b5fcdb4abc852aa85b4fe26aArgyrios Kyrtzidis  const ClassTemplateDecl *getPreviousDeclaration() const {
13265bf1bdc2fedb0c29b5fcdb4abc852aa85b4fe26aArgyrios Kyrtzidis    return CommonOrPrev.dyn_cast<ClassTemplateDecl*>();
13275bf1bdc2fedb0c29b5fcdb4abc852aa85b4fe26aArgyrios Kyrtzidis  }
13285bf1bdc2fedb0c29b5fcdb4abc852aa85b4fe26aArgyrios Kyrtzidis
13295bf1bdc2fedb0c29b5fcdb4abc852aa85b4fe26aArgyrios Kyrtzidis  /// \brief Retrieve the previous declaration of this function template, or
13305bf1bdc2fedb0c29b5fcdb4abc852aa85b4fe26aArgyrios Kyrtzidis  /// NULL if no such declaration exists.
13315bf1bdc2fedb0c29b5fcdb4abc852aa85b4fe26aArgyrios Kyrtzidis  ClassTemplateDecl *getPreviousDeclaration() {
13325bf1bdc2fedb0c29b5fcdb4abc852aa85b4fe26aArgyrios Kyrtzidis    return CommonOrPrev.dyn_cast<ClassTemplateDecl*>();
13337da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  }
13341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
13355bf1bdc2fedb0c29b5fcdb4abc852aa85b4fe26aArgyrios Kyrtzidis  /// \brief Set the previous declaration of this class template.
13365bf1bdc2fedb0c29b5fcdb4abc852aa85b4fe26aArgyrios Kyrtzidis  void setPreviousDeclaration(ClassTemplateDecl *Prev) {
13375bf1bdc2fedb0c29b5fcdb4abc852aa85b4fe26aArgyrios Kyrtzidis    if (Prev)
13385bf1bdc2fedb0c29b5fcdb4abc852aa85b4fe26aArgyrios Kyrtzidis      CommonOrPrev = Prev;
13395bf1bdc2fedb0c29b5fcdb4abc852aa85b4fe26aArgyrios Kyrtzidis  }
13408731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis
1341b57a4fe73b8227c0dba651818b8495dfca61e530Argyrios Kyrtzidis  virtual ClassTemplateDecl *getCanonicalDecl();
13427da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor
13435953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  /// Create a class template node.
13443e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  static ClassTemplateDecl *Create(ASTContext &C, DeclContext *DC,
13453e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor                                   SourceLocation L,
13463e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor                                   DeclarationName Name,
13473e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor                                   TemplateParameterList *Params,
13485953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor                                   NamedDecl *Decl,
13495953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor                                   ClassTemplateDecl *PrevDecl);
13503e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
13513e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  /// \brief Retrieve the set of specializations of this class template.
13523e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  llvm::FoldingSet<ClassTemplateSpecializationDecl> &getSpecializations() {
13535bf1bdc2fedb0c29b5fcdb4abc852aa85b4fe26aArgyrios Kyrtzidis    return getCommonPtr()->Specializations;
13543e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
13553e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
1356c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  /// \brief Retrieve the set of partial specializations of this class
1357c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  /// template.
1358c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  llvm::FoldingSet<ClassTemplatePartialSpecializationDecl> &
1359c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  getPartialSpecializations() {
13605bf1bdc2fedb0c29b5fcdb4abc852aa85b4fe26aArgyrios Kyrtzidis    return getCommonPtr()->PartialSpecializations;
1361c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  }
1362c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
1363dc60c1eb4acbde6edcec9760de92f9098593d915Douglas Gregor  /// \brief Retrieve the partial specializations as an ordered list.
1364dc60c1eb4acbde6edcec9760de92f9098593d915Douglas Gregor  void getPartialSpecializations(
1365dc60c1eb4acbde6edcec9760de92f9098593d915Douglas Gregor          llvm::SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS);
1366dc60c1eb4acbde6edcec9760de92f9098593d915Douglas Gregor
1367b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  /// \brief Find a class template partial specialization with the given
1368b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  /// type T.
1369b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  ///
1370b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  /// \brief A dependent type that names a specialization of this class
1371b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  /// template.
1372b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  ///
1373b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  /// \returns the class template partial specialization that exactly matches
1374b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  /// the type \p T, or NULL if no such partial specialization exists.
1375b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  ClassTemplatePartialSpecializationDecl *findPartialSpecialization(QualType T);
13761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
13773cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall  /// \brief Retrieve the template specialization type of the
13783cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall  /// injected-class-name for this class template.
13797da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  ///
13807da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// The injected-class-name for a class template \c X is \c
13817da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// X<template-args>, where \c template-args is formed from the
13827da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// template arguments that correspond to the template parameters of
13837da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// \c X. For example:
13847da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  ///
13857da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// \code
13867da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// template<typename T, int N>
13877da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// struct array {
13887da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  ///   typedef array this_type; // "array" is equivalent to "array<T, N>"
13897da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// };
13907da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// \endcode
13913cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall  QualType getInjectedClassNameSpecialization(ASTContext &Context);
13927da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor
1393e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// \brief Retrieve the member class template that this class template was
1394e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// derived from.
1395e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  ///
1396e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// This routine will return non-NULL for templated member classes of
1397e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// class templates.  For example, given:
1398e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  ///
1399e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// \code
1400e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// template <typename T>
1401e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// struct X {
1402e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  ///   template <typename U> struct A {};
1403e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// };
1404e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// \endcode
1405e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  ///
1406e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// X<int>::A<float> is a ClassTemplateSpecializationDecl (whose parent
1407e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// is X<int>, also a CTSD) for which getSpecializedTemplate() will
1408e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// return X<int>::A<U>, a TemplateClassDecl (whose parent is again
1409e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// X<int>) for which getInstantiatedFromMemberTemplate() will return
1410e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// X<T>::A<U>, a TemplateClassDecl (whose parent is X<T>, also a TCD).
1411e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  ///
1412e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// \returns null if this is not an instantiation of a member class template.
14135bf1bdc2fedb0c29b5fcdb4abc852aa85b4fe26aArgyrios Kyrtzidis  ClassTemplateDecl *getInstantiatedFromMemberTemplate() {
14145bf1bdc2fedb0c29b5fcdb4abc852aa85b4fe26aArgyrios Kyrtzidis    return getCommonPtr()->InstantiatedFromMember.getPointer();
1415e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  }
1416e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall
1417e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  void setInstantiatedFromMemberTemplate(ClassTemplateDecl *CTD) {
14185bf1bdc2fedb0c29b5fcdb4abc852aa85b4fe26aArgyrios Kyrtzidis    assert(!getCommonPtr()->InstantiatedFromMember.getPointer());
14195bf1bdc2fedb0c29b5fcdb4abc852aa85b4fe26aArgyrios Kyrtzidis    getCommonPtr()->InstantiatedFromMember.setPointer(CTD);
1420e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  }
1421e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall
1422fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  /// \brief Determines whether this template was a specialization of a
1423fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  /// member template.
1424fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  ///
1425fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  /// In the following example, the member template \c X<int>::Inner is a
1426fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  /// member specialization.
1427fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  ///
1428fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  /// \code
1429fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  /// template<typename T>
1430fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  /// struct X {
1431fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  ///   template<typename U> struct Inner;
1432fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  /// };
1433fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  ///
1434fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  /// template<> template<typename T>
1435fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  /// struct X<int>::Inner { /* ... */ };
1436fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  /// \endcode
1437fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  bool isMemberSpecialization() {
14385bf1bdc2fedb0c29b5fcdb4abc852aa85b4fe26aArgyrios Kyrtzidis    return getCommonPtr()->InstantiatedFromMember.getInt();
1439fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  }
1440fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor
1441fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  /// \brief Note that this member template is a specialization.
1442fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  void setMemberSpecialization() {
14435bf1bdc2fedb0c29b5fcdb4abc852aa85b4fe26aArgyrios Kyrtzidis    assert(getCommonPtr()->InstantiatedFromMember.getPointer() &&
1444fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor           "Only member templates can be member template specializations");
14455bf1bdc2fedb0c29b5fcdb4abc852aa85b4fe26aArgyrios Kyrtzidis    getCommonPtr()->InstantiatedFromMember.setInt(true);
1446fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  }
1447fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor
14483e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  // Implement isa/cast/dyncast support
144980cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
145080cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classof(const ClassTemplateDecl *D) { return true; }
145180cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classofKind(Kind K) { return K == ClassTemplate; }
14525953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor
14535953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  virtual void Destroy(ASTContext& C);
14543e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor};
14553e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
1456dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall/// Declaration of a friend template.  For example:
1457dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall///
1458dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall/// template <typename T> class A {
1459dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall///   friend class MyVector<T>; // not a friend template
1460dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall///   template <typename U> friend class B; // friend template
1461dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall///   template <typename U> friend class Foo<T>::Nested; // friend template
1462dd4a3b0065b9a7e7b00073df415a798886c090f3John McCallclass FriendTemplateDecl : public Decl {
1463dd4a3b0065b9a7e7b00073df415a798886c090f3John McCallpublic:
146432f2fb53d9d7c28c94d8569fd0fcf06cccee0c3dJohn McCall  typedef llvm::PointerUnion<NamedDecl*,TypeSourceInfo*> FriendUnion;
1465dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
1466dd4a3b0065b9a7e7b00073df415a798886c090f3John McCallprivate:
1467dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  // The number of template parameters;  always non-zero.
1468dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  unsigned NumParams;
1469dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
1470dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  // The parameter list.
1471dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  TemplateParameterList **Params;
1472dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
1473dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  // The declaration that's a friend of this class.
1474dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  FriendUnion Friend;
1475dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
1476dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  // Location of the 'friend' specifier.
1477dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  SourceLocation FriendLoc;
1478dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
1479dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
1480dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  FriendTemplateDecl(DeclContext *DC, SourceLocation Loc,
1481dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall                     unsigned NParams,
1482dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall                     TemplateParameterList **Params,
1483dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall                     FriendUnion Friend,
1484dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall                     SourceLocation FriendLoc)
1485dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall    : Decl(Decl::FriendTemplate, DC, Loc),
1486dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall      NumParams(NParams),
1487dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall      Params(Params),
1488dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall      Friend(Friend),
1489dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall      FriendLoc(FriendLoc)
1490dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  {}
1491dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
1492dd4a3b0065b9a7e7b00073df415a798886c090f3John McCallpublic:
1493dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  static FriendTemplateDecl *Create(ASTContext &Context,
1494dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall                                    DeclContext *DC, SourceLocation Loc,
1495dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall                                    unsigned NParams,
1496dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall                                    TemplateParameterList **Params,
1497dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall                                    FriendUnion Friend,
1498dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall                                    SourceLocation FriendLoc);
1499dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
1500dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  /// If this friend declaration names a templated type (or
1501dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  /// a dependent member type of a templated type), return that
1502dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  /// type;  otherwise return null.
150332f2fb53d9d7c28c94d8569fd0fcf06cccee0c3dJohn McCall  TypeSourceInfo *getFriendType() const {
150432f2fb53d9d7c28c94d8569fd0fcf06cccee0c3dJohn McCall    return Friend.dyn_cast<TypeSourceInfo*>();
1505dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  }
1506dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
1507dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  /// If this friend declaration names a templated function (or
1508dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  /// a member function of a templated type), return that type;
1509dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  /// otherwise return null.
1510dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  NamedDecl *getFriendDecl() const {
1511dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall    return Friend.dyn_cast<NamedDecl*>();
1512dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  }
1513dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
1514dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  /// Retrieves the location of the 'friend' keyword.
1515dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  SourceLocation getFriendLoc() const {
1516dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall    return FriendLoc;
1517dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  }
1518dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
1519dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  TemplateParameterList *getTemplateParameterList(unsigned i) const {
1520dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall    assert(i <= NumParams);
1521dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall    return Params[i];
1522dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  }
1523dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
1524dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  unsigned getNumTemplateParameters() const {
1525dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall    return NumParams;
1526dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  }
1527dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
1528dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  // Implement isa/cast/dyncast/etc.
152980cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
153080cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classofKind(Kind K) { return K == Decl::FriendTemplate; }
1531dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  static bool classof(const FriendTemplateDecl *D) { return true; }
1532dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall};
1533dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
1534e53060fa78ad7e98352049f72787bdb7543e2a48Douglas Gregor/// Implementation of inline functions that require the template declarations
15351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpinline AnyFunctionDecl::AnyFunctionDecl(FunctionTemplateDecl *FTD)
1536e53060fa78ad7e98352049f72787bdb7543e2a48Douglas Gregor  : Function(FTD) { }
1537e53060fa78ad7e98352049f72787bdb7543e2a48Douglas Gregor
1538aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor} /* end of namespace clang */
1539aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
1540aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor#endif
1541