DeclTemplate.h revision 8fed4b4bc93cce4d15bdb79f9e30cc25a93c8143
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;
269eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourneclass RedeclarableTemplateDecl;
27aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorclass FunctionTemplateDecl;
28aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorclass ClassTemplateDecl;
29c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregorclass ClassTemplatePartialSpecializationDecl;
30aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorclass TemplateTypeParmDecl;
31aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorclass NonTypeTemplateParmDecl;
32aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorclass TemplateTemplateParmDecl;
33aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
34f67875d5addf36b951ad37fb04509ab2b572c88aDouglas Gregor/// \brief Stores a template parameter of any kind.
35f67875d5addf36b951ad37fb04509ab2b572c88aDouglas Gregortypedef llvm::PointerUnion3<TemplateTypeParmDecl*, NonTypeTemplateParmDecl*,
36f67875d5addf36b951ad37fb04509ab2b572c88aDouglas Gregor                            TemplateTemplateParmDecl*> TemplateParameter;
37f67875d5addf36b951ad37fb04509ab2b572c88aDouglas Gregor
38aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor/// TemplateParameterList - Stores a list of template parameters for a
39aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor/// TemplateDecl and its derived classes.
40aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorclass TemplateParameterList {
41ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  /// The location of the 'template' keyword.
42ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  SourceLocation TemplateLoc;
43ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor
44ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  /// The locations of the '<' and '>' angle brackets.
45ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  SourceLocation LAngleLoc, RAngleLoc;
46ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor
47ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  /// The number of template parameters in this template
48aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  /// parameter list.
49aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  unsigned NumParams;
50aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
51ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  TemplateParameterList(SourceLocation TemplateLoc, SourceLocation LAngleLoc,
52bf4ea56cdc376cef5a12abf6bf18dc34805c2226Douglas Gregor                        NamedDecl **Params, unsigned NumParams,
53ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor                        SourceLocation RAngleLoc);
54aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
55aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorpublic:
561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  static TemplateParameterList *Create(ASTContext &C,
57ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor                                       SourceLocation TemplateLoc,
58ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor                                       SourceLocation LAngleLoc,
59bf4ea56cdc376cef5a12abf6bf18dc34805c2226Douglas Gregor                                       NamedDecl **Params,
60ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor                                       unsigned NumParams,
61ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor                                       SourceLocation RAngleLoc);
62aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
63aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  /// iterator - Iterates through the template parameters in this list.
64bf4ea56cdc376cef5a12abf6bf18dc34805c2226Douglas Gregor  typedef NamedDecl** iterator;
65aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
66aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  /// const_iterator - Iterates through the template parameters in this list.
67bf4ea56cdc376cef5a12abf6bf18dc34805c2226Douglas Gregor  typedef NamedDecl* const* const_iterator;
68aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
69bf4ea56cdc376cef5a12abf6bf18dc34805c2226Douglas Gregor  iterator begin() { return reinterpret_cast<NamedDecl **>(this + 1); }
70aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  const_iterator begin() const {
71bf4ea56cdc376cef5a12abf6bf18dc34805c2226Douglas Gregor    return reinterpret_cast<NamedDecl * const *>(this + 1);
72aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  }
73aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  iterator end() { return begin() + NumParams; }
74aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  const_iterator end() const { return begin() + NumParams; }
75aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
76aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  unsigned size() const { return NumParams; }
77ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor
78bf4ea56cdc376cef5a12abf6bf18dc34805c2226Douglas Gregor  NamedDecl* getParam(unsigned Idx) {
79f67875d5addf36b951ad37fb04509ab2b572c88aDouglas Gregor    assert(Idx < size() && "Template parameter index out-of-range");
80f67875d5addf36b951ad37fb04509ab2b572c88aDouglas Gregor    return begin()[Idx];
81f67875d5addf36b951ad37fb04509ab2b572c88aDouglas Gregor  }
82f67875d5addf36b951ad37fb04509ab2b572c88aDouglas Gregor
83bf4ea56cdc376cef5a12abf6bf18dc34805c2226Douglas Gregor  const NamedDecl* getParam(unsigned Idx) const {
8440808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor    assert(Idx < size() && "Template parameter index out-of-range");
8540808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor    return begin()[Idx];
8640808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor  }
8740808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor
8862cb18dd11472965e03374d40bc27d650bc331b6Douglas Gregor  /// \btief Returns the minimum number of arguments needed to form a
8962cb18dd11472965e03374d40bc27d650bc331b6Douglas Gregor  /// template specialization. This may be fewer than the number of
9062cb18dd11472965e03374d40bc27d650bc331b6Douglas Gregor  /// template parameters, if some of the parameters have default
910ceffb51b28b09db67404058c642dcb1f877f6e8Anders Carlsson  /// arguments or if there is a parameter pack.
9262cb18dd11472965e03374d40bc27d650bc331b6Douglas Gregor  unsigned getMinRequiredArguments() const;
9362cb18dd11472965e03374d40bc27d650bc331b6Douglas Gregor
94ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \brief Get the depth of this template parameter list in the set of
95ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// template parameter lists.
96ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ///
97ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// The first template parameter list in a declaration will have depth 0,
98ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// the second template parameter list will have depth 1, etc.
99ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  unsigned getDepth() const;
100ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor
101ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  SourceLocation getTemplateLoc() const { return TemplateLoc; }
102ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  SourceLocation getLAngleLoc() const { return LAngleLoc; }
103ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  SourceLocation getRAngleLoc() const { return RAngleLoc; }
10462cb18dd11472965e03374d40bc27d650bc331b6Douglas Gregor
10562cb18dd11472965e03374d40bc27d650bc331b6Douglas Gregor  SourceRange getSourceRange() const {
10662cb18dd11472965e03374d40bc27d650bc331b6Douglas Gregor    return SourceRange(TemplateLoc, RAngleLoc);
10762cb18dd11472965e03374d40bc27d650bc331b6Douglas Gregor  }
108aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor};
109aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
110127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// \brief A helper class for making template argument lists.
111127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorclass TemplateArgumentListBuilder {
112127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateArgument *StructuredArgs;
113127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned MaxStructuredArgs;
114127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned NumStructuredArgs;
1151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
11698d279ba8092186f606abaa8298f13a0816b9cf2Chris Lattner  llvm::SmallVector<TemplateArgument, 4> FlatArgs;
117127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned MaxFlatArgs;
118127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned NumFlatArgs;
1191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
120127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  bool AddingToPack;
121127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned PackBeginIndex;
1221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
123aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorpublic:
124127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateArgumentListBuilder(const TemplateParameterList *Parameters,
125127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                              unsigned NumTemplateArgs)
1261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  : StructuredArgs(0), MaxStructuredArgs(Parameters->size()),
1271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  NumStructuredArgs(0), FlatArgs(0),
128127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  MaxFlatArgs(std::max(MaxStructuredArgs, NumTemplateArgs)), NumFlatArgs(0),
129127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  AddingToPack(false), PackBeginIndex(0) { }
1301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
13198d279ba8092186f606abaa8298f13a0816b9cf2Chris Lattner  void Append(const TemplateArgument &Arg);
132127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  void BeginPack();
133127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  void EndPack();
1341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
13598d279ba8092186f606abaa8298f13a0816b9cf2Chris Lattner  unsigned flatSize() const { return FlatArgs.size(); }
13698d279ba8092186f606abaa8298f13a0816b9cf2Chris Lattner  const TemplateArgument *getFlatArguments() const { return FlatArgs.data(); }
1371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
138127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned structuredSize() const {
139127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    // If we don't have any structured args, just reuse the flat size.
140127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    if (!StructuredArgs)
141127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      return flatSize();
1421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
143127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return NumStructuredArgs;
144d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  }
145127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  const TemplateArgument *getStructuredArguments() const {
146127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    // If we don't have any structured args, just reuse the flat args.
147127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    if (!StructuredArgs)
148127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      return getFlatArguments();
1491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
150127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return StructuredArgs;
151aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  }
152aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor};
153aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
154127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// \brief A template argument list.
155127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor///
156127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// FIXME: In the future, this class will be extended to support
157127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// variadic templates and member templates, which will make some of
158127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// the function names below make more sense.
159127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorclass TemplateArgumentList {
160127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief The template argument list.
161127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  ///
162127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// The integer value will be non-zero to indicate that this
16356ef550c5eeea0714c635782776389df2a177584Chris Lattner  /// template argument list does own the pointer.
164127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  llvm::PointerIntPair<const TemplateArgument *, 1> FlatArguments;
1651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
166127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief The number of template arguments in this template
167127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// argument list.
168127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned NumFlatArguments;
1691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
170127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  llvm::PointerIntPair<const TemplateArgument *, 1> StructuredArguments;
171127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned NumStructuredArguments;
1721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
173885989109ade7cb4dc493e25da41456c64b3cf6aChris Lattner  TemplateArgumentList(const TemplateArgumentList &Other); // DO NOT IMPL
174885989109ade7cb4dc493e25da41456c64b3cf6aChris Lattner  void operator=(const TemplateArgumentList &Other); // DO NOT IMPL
175aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorpublic:
17656ef550c5eeea0714c635782776389df2a177584Chris Lattner  /// TemplateArgumentList - If this constructor is passed "true" for 'TakeArgs'
17756ef550c5eeea0714c635782776389df2a177584Chris Lattner  /// it copies them into a locally new[]'d array.  If passed "false", then it
17856ef550c5eeea0714c635782776389df2a177584Chris Lattner  /// just references the array passed in.  This is only safe if the builder
17956ef550c5eeea0714c635782776389df2a177584Chris Lattner  /// outlives it, but saves a copy.
180127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateArgumentList(ASTContext &Context,
181127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                       TemplateArgumentListBuilder &Builder,
182127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                       bool TakeArgs);
1831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
184d0913557c800c8a712fb554032a833619f23bc56Argyrios Kyrtzidis  /// TemplateArgumentList - It copies the template arguments into a locally
185d0913557c800c8a712fb554032a833619f23bc56Argyrios Kyrtzidis  /// new[]'d array.
186d0913557c800c8a712fb554032a833619f23bc56Argyrios Kyrtzidis  TemplateArgumentList(ASTContext &Context,
18794d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis                       const TemplateArgument *Args, unsigned NumArgs);
188d0913557c800c8a712fb554032a833619f23bc56Argyrios Kyrtzidis
189885989109ade7cb4dc493e25da41456c64b3cf6aChris Lattner  /// Produces a shallow copy of the given template argument list.  This
190885989109ade7cb4dc493e25da41456c64b3cf6aChris Lattner  /// assumes that the input argument list outlives it.  This takes the list as
191885989109ade7cb4dc493e25da41456c64b3cf6aChris Lattner  /// a pointer to avoid looking like a copy constructor, since this really
192885989109ade7cb4dc493e25da41456c64b3cf6aChris Lattner  /// really isn't safe to use that way.
193885989109ade7cb4dc493e25da41456c64b3cf6aChris Lattner  explicit TemplateArgumentList(const TemplateArgumentList *Other);
19494d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis
19594d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis  TemplateArgumentList() : NumFlatArguments(0), NumStructuredArguments(0) { }
19694d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis
19794d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis  /// \brief Copies the template arguments into a locally new[]'d array.
19894d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis  void init(ASTContext &Context,
19994d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis            const TemplateArgument *Args, unsigned NumArgs);
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  /// Get the list of template parameters
253127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateParameterList *getTemplateParameters() const {
254127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return TemplateParams;
255d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  }
256d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor
257127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// Get the underlying, templated declaration.
258127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  NamedDecl *getTemplatedDecl() const { return TemplatedDecl; }
259127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
260aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  // Implement isa/cast/dyncast/etc.
26180cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
262127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static bool classof(const TemplateDecl *D) { return true; }
2639eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  static bool classof(const RedeclarableTemplateDecl *D) { return true; }
264127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static bool classof(const FunctionTemplateDecl *D) { return true; }
265127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static bool classof(const ClassTemplateDecl *D) { return true; }
266aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  static bool classof(const TemplateTemplateParmDecl *D) { return true; }
26780cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classofKind(Kind K) {
2689a55591af3e5506b95a9718e15380129fbfc5ebcSean Hunt    return K >= firstTemplate && K <= lastTemplate;
26980cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  }
270aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
27180484d0de0dccee66d9f1760127c3e6e218987daDouglas Gregor  SourceRange getSourceRange() const {
27280484d0de0dccee66d9f1760127c3e6e218987daDouglas Gregor    return SourceRange(TemplateParams->getTemplateLoc(),
27380484d0de0dccee66d9f1760127c3e6e218987daDouglas Gregor                       TemplatedDecl->getSourceRange().getEnd());
27480484d0de0dccee66d9f1760127c3e6e218987daDouglas Gregor  }
27580484d0de0dccee66d9f1760127c3e6e218987daDouglas Gregor
276127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorprotected:
277127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  NamedDecl *TemplatedDecl;
278127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateParameterList* TemplateParams;
2798731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis
2808731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidispublic:
2818731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis  /// \brief Initialize the underlying templated declaration and
2828731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis  /// template parameters.
2838731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis  void init(NamedDecl *templatedDecl, TemplateParameterList* templateParams) {
2848731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis    assert(TemplatedDecl == 0 && "TemplatedDecl already set!");
2858731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis    assert(TemplateParams == 0 && "TemplateParams already set!");
2868731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis    TemplatedDecl = templatedDecl;
2878731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis    TemplateParams = templateParams;
2888731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis  }
289127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor};
2901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// \brief Provides information about a function template specialization,
292127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// which is a FunctionDecl that has been explicitly specialization or
293127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// instantiated from a function template.
294127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorclass FunctionTemplateSpecializationInfo : public llvm::FoldingSetNode {
295a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis  FunctionTemplateSpecializationInfo(FunctionDecl *FD,
296a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis                                     FunctionTemplateDecl *Template,
297a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis                                     TemplateSpecializationKind TSK,
298a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis                                     const TemplateArgumentList *TemplateArgs,
299a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis                          const TemplateArgumentListInfo *TemplateArgsAsWritten,
300a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis                                     SourceLocation POI)
301a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis  : Function(FD),
302a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis    Template(Template, TSK - 1),
303a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis    TemplateArguments(TemplateArgs),
304a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis    TemplateArgumentsAsWritten(TemplateArgsAsWritten),
305a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis    PointOfInstantiation(POI) { }
306a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis
307127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorpublic:
308a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis  static FunctionTemplateSpecializationInfo *
309a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis  Create(ASTContext &C, FunctionDecl *FD, FunctionTemplateDecl *Template,
310a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis         TemplateSpecializationKind TSK,
311a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis         const TemplateArgumentList *TemplateArgs,
312a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis         const TemplateArgumentListInfo *TemplateArgsAsWritten,
313a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis         SourceLocation POI) {
314a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis    return new (C) FunctionTemplateSpecializationInfo(FD, Template, TSK,
315a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis                                                      TemplateArgs,
316a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis                                                      TemplateArgsAsWritten,
317a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis                                                      POI);
318a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis  }
319a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis
3201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// \brief The function template specialization that this structure
321127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// describes.
322127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  FunctionDecl *Function;
3231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// \brief The function template from which this function template
325127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// specialization was generated.
3261fd2dd145d9bcdf0b8d60a88e1795b6ae83656f5Douglas Gregor  ///
327d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor  /// The two bits are contain the top 4 values of TemplateSpecializationKind.
328d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor  llvm::PointerIntPair<FunctionTemplateDecl *, 2> Template;
3291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
330127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief The template arguments used to produce the function template
331127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// specialization from the function template.
332127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  const TemplateArgumentList *TemplateArguments;
3331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
334e03db98d67111ebf7622d9086951aacc24406b66Abramo Bagnara  /// \brief The template arguments as written in the sources, if provided.
335e03db98d67111ebf7622d9086951aacc24406b66Abramo Bagnara  const TemplateArgumentListInfo *TemplateArgumentsAsWritten;
336e03db98d67111ebf7622d9086951aacc24406b66Abramo Bagnara
337b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  /// \brief The point at which this function template specialization was
338b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  /// first instantiated.
339b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  SourceLocation PointOfInstantiation;
340b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor
3411fd2dd145d9bcdf0b8d60a88e1795b6ae83656f5Douglas Gregor  /// \brief Retrieve the template from which this function was specialized.
3421fd2dd145d9bcdf0b8d60a88e1795b6ae83656f5Douglas Gregor  FunctionTemplateDecl *getTemplate() const { return Template.getPointer(); }
343d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor
344d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor  /// \brief Determine what kind of template specialization this is.
345d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor  TemplateSpecializationKind getTemplateSpecializationKind() const {
346d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor    return (TemplateSpecializationKind)(Template.getInt() + 1);
347d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor  }
348d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor
349d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor  /// \brief Set the template specialization kind.
350d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor  void setTemplateSpecializationKind(TemplateSpecializationKind TSK) {
3511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    assert(TSK != TSK_Undeclared &&
352d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor         "Cannot encode TSK_Undeclared for a function template specialization");
353d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor    Template.setInt(TSK - 1);
3541fd2dd145d9bcdf0b8d60a88e1795b6ae83656f5Douglas Gregor  }
3551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
356b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  /// \brief Retrieve the first point of instantiation of this function
357b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  /// template specialization.
358b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  ///
359b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  /// The point of instantiation may be an invalid source location if this
360b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  /// function has yet to be instantiated.
361b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  SourceLocation getPointOfInstantiation() const {
362b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor    return PointOfInstantiation;
363b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  }
364b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor
365b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  /// \brief Set the (first) point of instantiation of this function template
366b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  /// specialization.
367b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  void setPointOfInstantiation(SourceLocation POI) {
368b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor    PointOfInstantiation = POI;
369b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  }
370b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor
371127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  void Profile(llvm::FoldingSetNodeID &ID) {
3721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    Profile(ID, TemplateArguments->getFlatArgumentList(),
373828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor            TemplateArguments->flat_size(),
3741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            Function->getASTContext());
375127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  }
3761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  static void
3781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  Profile(llvm::FoldingSetNodeID &ID, const TemplateArgument *TemplateArgs,
379828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor          unsigned NumTemplateArgs, ASTContext &Context) {
380127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    ID.AddInteger(NumTemplateArgs);
381127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    for (unsigned Arg = 0; Arg != NumTemplateArgs; ++Arg)
382828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor      TemplateArgs[Arg].Profile(ID, Context);
3831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  }
384127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor};
3851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3862db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor/// \brief Provides information a specialization of a member of a class
3872db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor/// template, which may be a member function, static data member, or
3882db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor/// member class.
3892db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregorclass MemberSpecializationInfo {
39044e368b6a85c42d681148ccd5e0052418ff9751eDouglas Gregor  // The member declaration from which this member was instantiated, and the
39144e368b6a85c42d681148ccd5e0052418ff9751eDouglas Gregor  // manner in which the instantiation occurred (in the lower two bits).
39244e368b6a85c42d681148ccd5e0052418ff9751eDouglas Gregor  llvm::PointerIntPair<NamedDecl *, 2> MemberAndTSK;
3932db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor
394b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  // The point at which this member was first instantiated.
395b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  SourceLocation PointOfInstantiation;
396b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor
3972db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregorpublic:
3982db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor  explicit
3999421adc43891e272156fab640e5d5ee5054b779cArgyrios Kyrtzidis  MemberSpecializationInfo(NamedDecl *IF, TemplateSpecializationKind TSK,
4009421adc43891e272156fab640e5d5ee5054b779cArgyrios Kyrtzidis                           SourceLocation POI = SourceLocation())
4019421adc43891e272156fab640e5d5ee5054b779cArgyrios Kyrtzidis    : MemberAndTSK(IF, TSK - 1), PointOfInstantiation(POI) {
40244e368b6a85c42d681148ccd5e0052418ff9751eDouglas Gregor    assert(TSK != TSK_Undeclared &&
40344e368b6a85c42d681148ccd5e0052418ff9751eDouglas Gregor           "Cannot encode undeclared template specializations for members");
40444e368b6a85c42d681148ccd5e0052418ff9751eDouglas Gregor  }
4052db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor
4062db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor  /// \brief Retrieve the member declaration from which this member was
4072db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor  /// instantiated.
40844e368b6a85c42d681148ccd5e0052418ff9751eDouglas Gregor  NamedDecl *getInstantiatedFrom() const { return MemberAndTSK.getPointer(); }
4092db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor
4102db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor  /// \brief Determine what kind of template specialization this is.
4112db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor  TemplateSpecializationKind getTemplateSpecializationKind() const {
41244e368b6a85c42d681148ccd5e0052418ff9751eDouglas Gregor    return (TemplateSpecializationKind)(MemberAndTSK.getInt() + 1);
4132db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor  }
4142db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor
4152db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor  /// \brief Set the template specialization kind.
4162db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor  void setTemplateSpecializationKind(TemplateSpecializationKind TSK) {
41744e368b6a85c42d681148ccd5e0052418ff9751eDouglas Gregor    assert(TSK != TSK_Undeclared &&
41844e368b6a85c42d681148ccd5e0052418ff9751eDouglas Gregor           "Cannot encode undeclared template specializations for members");
41944e368b6a85c42d681148ccd5e0052418ff9751eDouglas Gregor    MemberAndTSK.setInt(TSK - 1);
4202db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor  }
421b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor
422b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  /// \brief Retrieve the first point of instantiation of this member.
423b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  /// If the point of instantiation is an invalid location, then this member
424b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  /// has not yet been instantiated.
425b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  SourceLocation getPointOfInstantiation() const {
426b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor    return PointOfInstantiation;
427b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  }
428b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor
429b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  /// \brief Set the first point of instantiation.
430b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  void setPointOfInstantiation(SourceLocation POI) {
431b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor    PointOfInstantiation = POI;
432b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  }
4332db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor};
434af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
435af2094e7cecadf36667deb61a83587ffdd979bd3John McCall/// \brief Provides information about a dependent function-template
436af2094e7cecadf36667deb61a83587ffdd979bd3John McCall/// specialization declaration.  Since explicit function template
437af2094e7cecadf36667deb61a83587ffdd979bd3John McCall/// specialization and instantiation declarations can only appear in
438af2094e7cecadf36667deb61a83587ffdd979bd3John McCall/// namespace scope, and you can only specialize a member of a
439af2094e7cecadf36667deb61a83587ffdd979bd3John McCall/// fully-specialized class, the only way to get one of these is in
440af2094e7cecadf36667deb61a83587ffdd979bd3John McCall/// a friend declaration like the following:
441af2094e7cecadf36667deb61a83587ffdd979bd3John McCall///
442af2094e7cecadf36667deb61a83587ffdd979bd3John McCall///   template <class T> void foo(T);
443af2094e7cecadf36667deb61a83587ffdd979bd3John McCall///   template <class T> class A {
444af2094e7cecadf36667deb61a83587ffdd979bd3John McCall///     friend void foo<>(T);
445af2094e7cecadf36667deb61a83587ffdd979bd3John McCall///   };
446af2094e7cecadf36667deb61a83587ffdd979bd3John McCallclass DependentFunctionTemplateSpecializationInfo {
447af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  union {
448af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    // Force sizeof to be a multiple of sizeof(void*) so that the
449af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    // trailing data is aligned.
450af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    void *Aligner;
451af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
452af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    struct {
453af2094e7cecadf36667deb61a83587ffdd979bd3John McCall      /// The number of potential template candidates.
454af2094e7cecadf36667deb61a83587ffdd979bd3John McCall      unsigned NumTemplates;
455af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
456af2094e7cecadf36667deb61a83587ffdd979bd3John McCall      /// The number of template arguments.
457af2094e7cecadf36667deb61a83587ffdd979bd3John McCall      unsigned NumArgs;
458af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    } d;
459af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  };
460af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
461af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  /// The locations of the left and right angle brackets.
462af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  SourceRange AngleLocs;
463af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
464af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  FunctionTemplateDecl * const *getTemplates() const {
465af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    return reinterpret_cast<FunctionTemplateDecl*const*>(this+1);
466af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  }
467af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
468af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  const TemplateArgumentLoc *getTemplateArgs() const {
469af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    return reinterpret_cast<const TemplateArgumentLoc*>(
47033cab704d9b3b5b0218d578a20593bdfb0b1eb23John McCall             &getTemplates()[getNumTemplates()]);
471af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  }
472af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
473af2094e7cecadf36667deb61a83587ffdd979bd3John McCallpublic:
474af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  DependentFunctionTemplateSpecializationInfo(
475af2094e7cecadf36667deb61a83587ffdd979bd3John McCall                                 const UnresolvedSetImpl &Templates,
476af2094e7cecadf36667deb61a83587ffdd979bd3John McCall                                 const TemplateArgumentListInfo &TemplateArgs);
477af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
478af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  /// \brief Returns the number of function templates that this might
479af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  /// be a specialization of.
480af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  unsigned getNumTemplates() const {
481af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    return d.NumTemplates;
482af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  }
483af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
484af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  /// \brief Returns the i'th template candidate.
485af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  FunctionTemplateDecl *getTemplate(unsigned I) const {
486af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    assert(I < getNumTemplates() && "template index out of range");
487af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    return getTemplates()[I];
488af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  }
489af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
490af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  /// \brief Returns the number of explicit template arguments that were given.
491af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  unsigned getNumTemplateArgs() const {
492af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    return d.NumArgs;
493af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  }
494af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
495af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  /// \brief Returns the nth template argument.
496af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  const TemplateArgumentLoc &getTemplateArg(unsigned I) const {
497af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    assert(I < getNumTemplateArgs() && "template arg index out of range");
498af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    return getTemplateArgs()[I];
499af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  }
500af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
501af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  SourceLocation getLAngleLoc() const {
502af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    return AngleLocs.getBegin();
503af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  }
504af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
505af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  SourceLocation getRAngleLoc() const {
506af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    return AngleLocs.getEnd();
507af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  }
508af2094e7cecadf36667deb61a83587ffdd979bd3John McCall};
5092db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor
5109eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne/// Declaration of a redeclarable template.
5119eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourneclass RedeclarableTemplateDecl : public TemplateDecl {
5121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5139eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  RedeclarableTemplateDecl *getPreviousDeclarationImpl() {
5149eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    return CommonOrPrev.dyn_cast<RedeclarableTemplateDecl*>();
5159eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
5169eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
5179eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  RedeclarableTemplateDecl *getCanonicalDeclImpl();
5189eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
5198a798a7f7d88dc9865fad7da648e5cef8580c65aPeter Collingbourne  void setPreviousDeclarationImpl(RedeclarableTemplateDecl *Prev);
5209eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
5219eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  RedeclarableTemplateDecl *getInstantiatedFromMemberTemplateImpl() {
5229eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    return getCommonPtr()->InstantiatedFromMember.getPointer();
5239eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
5249eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
5259eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  void setInstantiatedFromMemberTemplateImpl(RedeclarableTemplateDecl *TD) {
5269eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    assert(!getCommonPtr()->InstantiatedFromMember.getPointer());
5279eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    getCommonPtr()->InstantiatedFromMember.setPointer(TD);
5289eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
5291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5309eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourneprotected:
53144dd0b440efdb37ff4c6e49f243faa3b0580b120Peter Collingbourne  template <typename EntryType> struct SpecEntryTraits {
53244dd0b440efdb37ff4c6e49f243faa3b0580b120Peter Collingbourne    typedef EntryType DeclType;
53344dd0b440efdb37ff4c6e49f243faa3b0580b120Peter Collingbourne
53444dd0b440efdb37ff4c6e49f243faa3b0580b120Peter Collingbourne    static DeclType *getMostRecentDeclaration(EntryType *D) {
53544dd0b440efdb37ff4c6e49f243faa3b0580b120Peter Collingbourne      return D->getMostRecentDeclaration();
53644dd0b440efdb37ff4c6e49f243faa3b0580b120Peter Collingbourne    }
53744dd0b440efdb37ff4c6e49f243faa3b0580b120Peter Collingbourne  };
53844dd0b440efdb37ff4c6e49f243faa3b0580b120Peter Collingbourne
5399f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  template <typename EntryType,
5409f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne            typename _SETraits = SpecEntryTraits<EntryType>,
5419f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne            typename _DeclType = typename _SETraits::DeclType>
5429f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  class SpecIterator : public std::iterator<std::forward_iterator_tag,
5439f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne                                            _DeclType*, ptrdiff_t,
5449f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne                                            _DeclType*, _DeclType*> {
5459f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    typedef _SETraits SETraits;
5469f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    typedef _DeclType DeclType;
5479f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne
5489f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    typedef typename llvm::FoldingSet<EntryType>::iterator SetIteratorType;
5499f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne
5509f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    SetIteratorType SetIter;
5519f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne
5529f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  public:
5539f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    SpecIterator() : SetIter() {}
5549f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    SpecIterator(SetIteratorType SetIter) : SetIter(SetIter) {}
5559f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne
5569f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    DeclType *operator*() const {
5579f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne      return SETraits::getMostRecentDeclaration(&*SetIter);
5589f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    }
5599f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    DeclType *operator->() const { return **this; }
5609f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne
5619f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    SpecIterator &operator++() { ++SetIter; return *this; }
5629f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    SpecIterator operator++(int) {
5639f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne      SpecIterator tmp(*this);
5649f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne      ++(*this);
5659f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne      return tmp;
5669f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    }
5679f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne
5689f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    bool operator==(SpecIterator Other) const {
5699f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne      return SetIter == Other.SetIter;
5709f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    }
5719f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    bool operator!=(SpecIterator Other) const {
5729f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne      return SetIter != Other.SetIter;
5739f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    }
5749f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  };
5759f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne
5769f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  template <typename EntryType>
5779f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  SpecIterator<EntryType> makeSpecIterator(llvm::FoldingSet<EntryType> &Specs,
5789f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne                                           bool isEnd) {
5799f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    return SpecIterator<EntryType>(isEnd ? Specs.end() : Specs.begin());
5809f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  }
5819f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne
5824048590d5774fd4b08661b5cf59b6f90b62f283aPeter Collingbourne  template <class EntryType> typename SpecEntryTraits<EntryType>::DeclType*
5834048590d5774fd4b08661b5cf59b6f90b62f283aPeter Collingbourne  findSpecializationImpl(llvm::FoldingSet<EntryType> &Specs,
5844048590d5774fd4b08661b5cf59b6f90b62f283aPeter Collingbourne                         const TemplateArgument *Args, unsigned NumArgs,
5854048590d5774fd4b08661b5cf59b6f90b62f283aPeter Collingbourne                         void *&InsertPos);
5864048590d5774fd4b08661b5cf59b6f90b62f283aPeter Collingbourne
5879eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  struct CommonBase {
5889eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    CommonBase() : InstantiatedFromMember(0, false) { }
5899eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
5909eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    /// \brief The template from which this was most
591d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor    /// directly instantiated (or null).
592fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor    ///
5939eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    /// The boolean value indicates whether this template
594fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor    /// was explicitly specialized.
5959eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    llvm::PointerIntPair<RedeclarableTemplateDecl*, 1, bool>
5969eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne      InstantiatedFromMember;
5978a798a7f7d88dc9865fad7da648e5cef8580c65aPeter Collingbourne
5988a798a7f7d88dc9865fad7da648e5cef8580c65aPeter Collingbourne    /// \brief The latest declaration of this template.
5998a798a7f7d88dc9865fad7da648e5cef8580c65aPeter Collingbourne    RedeclarableTemplateDecl *Latest;
6003e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  };
6011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
602127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief A pointer to the previous declaration (if this is a redeclaration)
6039eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// or to the data that is common to all declarations of this template.
6049eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  llvm::PointerUnion<CommonBase*, RedeclarableTemplateDecl*> CommonOrPrev;
6051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
6069eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// \brief Retrieves the "common" pointer shared by all (re-)declarations of
6079eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// the same template. Calling this routine may implicitly allocate memory
6089eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// for the common pointer.
6099eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  CommonBase *getCommonPtr();
6101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
6116b5415196327fa8ef00f028ba175fafef1738ae1Argyrios Kyrtzidis  virtual CommonBase *newCommon(ASTContext &C) = 0;
6122c853e401ca406d417eb916e867226050e7be06bArgyrios Kyrtzidis
6139eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  // Construct a template decl with name, parameters, and templated element.
6149eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  RedeclarableTemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
6159eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne                           DeclarationName Name, TemplateParameterList *Params,
6169eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne                           NamedDecl *Decl)
6179eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    : TemplateDecl(DK, DC, L, Name, Params, Decl),
6189eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne      CommonOrPrev((CommonBase*)0) { }
6191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
6203e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregorpublic:
6219eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  template <class decl_type> friend class RedeclarableTemplate;
6229eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
6239eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  RedeclarableTemplateDecl *getCanonicalDecl() {
6249eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    return getCanonicalDeclImpl();
6253e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
6263e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
6279eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// \brief Retrieve the previous declaration of this template, or
6289eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// NULL if no such declaration exists.
6299eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  RedeclarableTemplateDecl *getPreviousDeclaration() {
6309eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    return getPreviousDeclarationImpl();
6319eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
6321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
6339eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// \brief Retrieve the previous declaration of this template, or
6349eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// NULL if no such declaration exists.
6359eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  const RedeclarableTemplateDecl *getPreviousDeclaration() const {
6369eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    return
6379eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne      const_cast<RedeclarableTemplateDecl*>(this)->getPreviousDeclaration();
6389eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
6399eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
640ba5ff8ccf3f2a4d8fa3e91b58733707fb1caed6bArgyrios Kyrtzidis  /// \brief Retrieve the first declaration of this template, or itself
641ba5ff8ccf3f2a4d8fa3e91b58733707fb1caed6bArgyrios Kyrtzidis  /// if this the first one.
642ba5ff8ccf3f2a4d8fa3e91b58733707fb1caed6bArgyrios Kyrtzidis  RedeclarableTemplateDecl *getFirstDeclaration() {
643ba5ff8ccf3f2a4d8fa3e91b58733707fb1caed6bArgyrios Kyrtzidis    return getCanonicalDecl();
644ba5ff8ccf3f2a4d8fa3e91b58733707fb1caed6bArgyrios Kyrtzidis  }
645ba5ff8ccf3f2a4d8fa3e91b58733707fb1caed6bArgyrios Kyrtzidis
646ba5ff8ccf3f2a4d8fa3e91b58733707fb1caed6bArgyrios Kyrtzidis  /// \brief Retrieve the first declaration of this template, or itself
647ba5ff8ccf3f2a4d8fa3e91b58733707fb1caed6bArgyrios Kyrtzidis  /// if this the first one.
648ba5ff8ccf3f2a4d8fa3e91b58733707fb1caed6bArgyrios Kyrtzidis  const RedeclarableTemplateDecl *getFirstDeclaration() const {
649ba5ff8ccf3f2a4d8fa3e91b58733707fb1caed6bArgyrios Kyrtzidis    return
650ba5ff8ccf3f2a4d8fa3e91b58733707fb1caed6bArgyrios Kyrtzidis      const_cast<RedeclarableTemplateDecl*>(this)->getFirstDeclaration();
651ba5ff8ccf3f2a4d8fa3e91b58733707fb1caed6bArgyrios Kyrtzidis  }
652ba5ff8ccf3f2a4d8fa3e91b58733707fb1caed6bArgyrios Kyrtzidis
653ba5ff8ccf3f2a4d8fa3e91b58733707fb1caed6bArgyrios Kyrtzidis  /// \brief Retrieve the most recent declaration of this template, or itself
654ba5ff8ccf3f2a4d8fa3e91b58733707fb1caed6bArgyrios Kyrtzidis  /// if this the most recent one.
655ba5ff8ccf3f2a4d8fa3e91b58733707fb1caed6bArgyrios Kyrtzidis  RedeclarableTemplateDecl *getMostRecentDeclaration() {
656ba5ff8ccf3f2a4d8fa3e91b58733707fb1caed6bArgyrios Kyrtzidis    return getCommonPtr()->Latest;
657ba5ff8ccf3f2a4d8fa3e91b58733707fb1caed6bArgyrios Kyrtzidis  }
658ba5ff8ccf3f2a4d8fa3e91b58733707fb1caed6bArgyrios Kyrtzidis
659ba5ff8ccf3f2a4d8fa3e91b58733707fb1caed6bArgyrios Kyrtzidis  /// \brief Retrieve the most recent declaration of this template, or itself
660ba5ff8ccf3f2a4d8fa3e91b58733707fb1caed6bArgyrios Kyrtzidis  /// if this the most recent one.
661ba5ff8ccf3f2a4d8fa3e91b58733707fb1caed6bArgyrios Kyrtzidis  const RedeclarableTemplateDecl *getMostRecentDeclaration() const {
662ba5ff8ccf3f2a4d8fa3e91b58733707fb1caed6bArgyrios Kyrtzidis    return
663ba5ff8ccf3f2a4d8fa3e91b58733707fb1caed6bArgyrios Kyrtzidis      const_cast<RedeclarableTemplateDecl*>(this)->getMostRecentDeclaration();
664ba5ff8ccf3f2a4d8fa3e91b58733707fb1caed6bArgyrios Kyrtzidis  }
665ba5ff8ccf3f2a4d8fa3e91b58733707fb1caed6bArgyrios Kyrtzidis
6669eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// \brief Determines whether this template was a specialization of a
6679eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// member template.
6689eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  ///
6699eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// In the following example, the function template \c X<int>::f and the
6709eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// member template \c X<int>::Inner are member specializations.
6719eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  ///
6729eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// \code
6739eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// template<typename T>
6749eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// struct X {
6759eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  ///   template<typename U> void f(T, U);
6769eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  ///   template<typename U> struct Inner;
6779eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// };
6789eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  ///
6799eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// template<> template<typename T>
6809eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// void X<int>::f(int, T);
6819eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// template<> template<typename T>
6829eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// struct X<int>::Inner { /* ... */ };
6839eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// \endcode
6849eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  bool isMemberSpecialization() {
6859eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    return getCommonPtr()->InstantiatedFromMember.getInt();
6869eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
6879eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
6889eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// \brief Note that this member template is a specialization.
6899eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  void setMemberSpecialization() {
6909eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    assert(getCommonPtr()->InstantiatedFromMember.getPointer() &&
6919eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne           "Only member templates can be member template specializations");
6929eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    getCommonPtr()->InstantiatedFromMember.setInt(true);
6939eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
6949eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
6959eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// \brief Retrieve the previous declaration of this template, or
6969eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// NULL if no such declaration exists.
6979eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  RedeclarableTemplateDecl *getInstantiatedFromMemberTemplate() {
6989eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    return getInstantiatedFromMemberTemplateImpl();
6999eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
7009eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
701f88718ea0ca0d64b7fd31d109f1d9ec769a9c45fPeter Collingbourne  virtual RedeclarableTemplateDecl *getNextRedeclaration();
702f88718ea0ca0d64b7fd31d109f1d9ec769a9c45fPeter Collingbourne
7039eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  // Implement isa/cast/dyncast/etc.
7049eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
7059eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  static bool classof(const RedeclarableTemplateDecl *D) { return true; }
7069eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  static bool classof(const FunctionTemplateDecl *D) { return true; }
7079eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  static bool classof(const ClassTemplateDecl *D) { return true; }
7089eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  static bool classofKind(Kind K) {
7099eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    return K >= firstRedeclarableTemplate && K <= lastRedeclarableTemplate;
7109eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
7119eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
712d527cc06d78fe5afa5f20105b51697637eb02c56Sebastian Redl  friend class ASTDeclReader;
7133397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl  friend class ASTDeclWriter;
7149eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne};
7159eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
7169eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbournetemplate <class decl_type>
7179eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourneclass RedeclarableTemplate {
7189eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  RedeclarableTemplateDecl *thisDecl() {
7199eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    return static_cast<decl_type*>(this);
7209eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
7219eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
7229eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbournepublic:
723127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the previous declaration of this function template, or
724127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// NULL if no such declaration exists.
7259eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  decl_type *getPreviousDeclaration() {
7269eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    return static_cast<decl_type*>(thisDecl()->getPreviousDeclarationImpl());
7273e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
7283e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
729127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the previous declaration of this function template, or
730127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// NULL if no such declaration exists.
7319eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  const decl_type *getPreviousDeclaration() const {
7329eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    return const_cast<RedeclarableTemplate*>(this)->getPreviousDeclaration();
7333e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
7341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
735127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Set the previous declaration of this function template.
7369eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  void setPreviousDeclaration(decl_type *Prev) {
7379eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    thisDecl()->setPreviousDeclarationImpl(Prev);
7389eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
7399eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
7409eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  decl_type *getCanonicalDecl() {
7419eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    return static_cast<decl_type*>(thisDecl()->getCanonicalDeclImpl());
742127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  }
7431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
7449eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  const decl_type *getCanonicalDecl() const {
7459eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    return const_cast<RedeclarableTemplate*>(this)->getCanonicalDecl();
7469eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
7471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
7489eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// \brief Retrieve the member template that this template was instantiated
7499eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// from.
750d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  ///
7519eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// This routine will return non-NULL for member templates of
752d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// class templates.  For example, given:
753d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  ///
754d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// \code
755d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// template <typename T>
756d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// struct X {
757d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  ///   template <typename U> void f();
7589eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  ///   template <typename U> struct A {};
759d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// };
760d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// \endcode
761d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  ///
7629eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// X<int>::f<float> is a CXXMethodDecl (whose parent is X<int>, a
7631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// ClassTemplateSpecializationDecl) for which getPrimaryTemplate() will
764d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// return X<int>::f, a FunctionTemplateDecl (whose parent is again
765d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// X<int>) for which getInstantiatedFromMemberTemplate() will return
7661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// X<T>::f, a FunctionTemplateDecl (whose parent is X<T>, a
767d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// ClassTemplateDecl).
768d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  ///
7699eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// X<int>::A<float> is a ClassTemplateSpecializationDecl (whose parent
7709eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// is X<int>, also a CTSD) for which getSpecializedTemplate() will
7719eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// return X<int>::A<U>, a ClassTemplateDecl (whose parent is again
7729eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// X<int>) for which getInstantiatedFromMemberTemplate() will return
7739eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// X<T>::A<U>, a ClassTemplateDecl (whose parent is X<T>, also a CTD).
7749eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  ///
7759eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// \returns NULL if this is not an instantiation of a member template.
7769eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  decl_type *getInstantiatedFromMemberTemplate() {
7779eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    return static_cast<decl_type*>(
7789eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne             thisDecl()->getInstantiatedFromMemberTemplateImpl());
779d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  }
7801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
7819eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  void setInstantiatedFromMemberTemplate(decl_type *TD) {
7829eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    thisDecl()->setInstantiatedFromMemberTemplateImpl(TD);
783d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  }
7849eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne};
7851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
78644dd0b440efdb37ff4c6e49f243faa3b0580b120Peter Collingbournetemplate <> struct RedeclarableTemplateDecl::
78744dd0b440efdb37ff4c6e49f243faa3b0580b120Peter CollingbourneSpecEntryTraits<FunctionTemplateSpecializationInfo> {
78844dd0b440efdb37ff4c6e49f243faa3b0580b120Peter Collingbourne  typedef FunctionDecl DeclType;
78944dd0b440efdb37ff4c6e49f243faa3b0580b120Peter Collingbourne
79044dd0b440efdb37ff4c6e49f243faa3b0580b120Peter Collingbourne  static DeclType *
79144dd0b440efdb37ff4c6e49f243faa3b0580b120Peter Collingbourne  getMostRecentDeclaration(FunctionTemplateSpecializationInfo *I) {
79244dd0b440efdb37ff4c6e49f243faa3b0580b120Peter Collingbourne    return I->Function->getMostRecentDeclaration();
79344dd0b440efdb37ff4c6e49f243faa3b0580b120Peter Collingbourne  }
79444dd0b440efdb37ff4c6e49f243faa3b0580b120Peter Collingbourne};
79544dd0b440efdb37ff4c6e49f243faa3b0580b120Peter Collingbourne
7969eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne/// Declaration of a template function.
7979eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourneclass FunctionTemplateDecl : public RedeclarableTemplateDecl,
7989eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne                             public RedeclarableTemplate<FunctionTemplateDecl> {
7999eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  static void DeallocateCommon(void *Ptr);
8009eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
8019eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourneprotected:
8029eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  typedef RedeclarableTemplate<FunctionTemplateDecl> redeclarable_base;
8039eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
8049eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// \brief Data that is common to all of the declarations of a given
8059eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// function template.
8069eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  struct Common : CommonBase {
8079eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    /// \brief The function template specializations for this function
8089eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    /// template, including explicit specializations and instantiations.
8099eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    llvm::FoldingSet<FunctionTemplateSpecializationInfo> Specializations;
8109eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  };
8119eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
8129eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  FunctionTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
8139eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne                       TemplateParameterList *Params, NamedDecl *Decl)
8149eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    : RedeclarableTemplateDecl(FunctionTemplate, DC, L, Name, Params, Decl) { }
8159eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
8166b5415196327fa8ef00f028ba175fafef1738ae1Argyrios Kyrtzidis  CommonBase *newCommon(ASTContext &C);
8179eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
8189eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  Common *getCommonPtr() {
8199eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
820fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  }
8219eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
8226b5415196327fa8ef00f028ba175fafef1738ae1Argyrios Kyrtzidis  friend class FunctionDecl;
8239eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
8249eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// \brief Retrieve the set of function template specializations of this
8259eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// function template.
8269eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  llvm::FoldingSet<FunctionTemplateSpecializationInfo> &getSpecializations() {
8279eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    return getCommonPtr()->Specializations;
828fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  }
829fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor
8309eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbournepublic:
8319eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// Get the underlying function declaration of the template.
8329eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  FunctionDecl *getTemplatedDecl() const {
8339eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    return static_cast<FunctionDecl*>(TemplatedDecl);
8349eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
8359eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
83613fda8afe2ddd06c12bfb93a054e6b0d6d0d99f1John McCall  /// Returns whether this template declaration defines the primary
83713fda8afe2ddd06c12bfb93a054e6b0d6d0d99f1John McCall  /// pattern.
83813fda8afe2ddd06c12bfb93a054e6b0d6d0d99f1John McCall  bool isThisDeclarationADefinition() const {
83913fda8afe2ddd06c12bfb93a054e6b0d6d0d99f1John McCall    return getTemplatedDecl()->isThisDeclarationADefinition();
84013fda8afe2ddd06c12bfb93a054e6b0d6d0d99f1John McCall  }
84113fda8afe2ddd06c12bfb93a054e6b0d6d0d99f1John McCall
8429eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// \brief Return the specialization with the provided arguments if it exists,
8439eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// otherwise return the insertion point.
8449eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  FunctionDecl *findSpecialization(const TemplateArgument *Args,
8459eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne                                   unsigned NumArgs, void *&InsertPos);
8469eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
8479eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  FunctionTemplateDecl *getCanonicalDecl() {
8489eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    return redeclarable_base::getCanonicalDecl();
8499eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
8509eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  const FunctionTemplateDecl *getCanonicalDecl() const {
8519eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    return redeclarable_base::getCanonicalDecl();
8529eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
8539eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
8549eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// \brief Retrieve the previous declaration of this function template, or
8559eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// NULL if no such declaration exists.
8569eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  FunctionTemplateDecl *getPreviousDeclaration() {
8579eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    return redeclarable_base::getPreviousDeclaration();
8589eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
8599eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
8609eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// \brief Retrieve the previous declaration of this function template, or
8619eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// NULL if no such declaration exists.
8629eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  const FunctionTemplateDecl *getPreviousDeclaration() const {
8639eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    return redeclarable_base::getPreviousDeclaration();
8649eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
8659eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
8669eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  FunctionTemplateDecl *getInstantiatedFromMemberTemplate() {
8679eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    return redeclarable_base::getInstantiatedFromMemberTemplate();
8689eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
8699eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
8709f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  typedef SpecIterator<FunctionTemplateSpecializationInfo> spec_iterator;
8719f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne
8729f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  spec_iterator spec_begin() {
8739f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    return makeSpecIterator(getSpecializations(), false);
8749f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  }
8759f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne
8769f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  spec_iterator spec_end() {
8779f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    return makeSpecIterator(getSpecializations(), true);
8789f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  }
8799f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne
880127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// Create a template function node.
881127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static FunctionTemplateDecl *Create(ASTContext &C, DeclContext *DC,
882127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                      SourceLocation L,
883127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                      DeclarationName Name,
884127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                      TemplateParameterList *Params,
885127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                      NamedDecl *Decl);
8863e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
887127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // Implement isa/cast/dyncast support
88880cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
88980cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classof(const FunctionTemplateDecl *D) { return true; }
89080cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classofKind(Kind K) { return K == FunctionTemplate; }
891c8f9af2943699ff623ca08f2e5ed4d72e0351189Argyrios Kyrtzidis
892d527cc06d78fe5afa5f20105b51697637eb02c56Sebastian Redl  friend class ASTDeclReader;
8933397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl  friend class ASTDeclWriter;
894127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor};
895d01b1da213aeb71fd40ff7fb78a194613cc1ece7Anders Carlsson
896127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor//===----------------------------------------------------------------------===//
897127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor// Kinds of Template Parameters
898127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor//===----------------------------------------------------------------------===//
89940808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor
900127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// The TemplateParmPosition class defines the position of a template parameter
901127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// within a template parameter list. Because template parameter can be listed
902127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// sequentially for out-of-line template members, each template parameter is
903127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// given a Depth - the nesting of template parameter scopes - and a Position -
904127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// the occurrence within the parameter list.
905127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// This class is inheritedly privately by different kinds of template
906127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// parameters and is not part of the Decl hierarchy. Just a facility.
9071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpclass TemplateParmPosition {
908127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorprotected:
909127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // FIXME: This should probably never be called, but it's here as
910127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateParmPosition()
911127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    : Depth(0), Position(0)
912127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  { /* assert(0 && "Cannot create positionless template parameter"); */ }
9133e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
914127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateParmPosition(unsigned D, unsigned P)
915127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    : Depth(D), Position(P)
916127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  { }
9173e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
918127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // FIXME: These probably don't need to be ints. int:5 for depth, int:8 for
919127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // position? Maybe?
920127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned Depth;
921127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned Position;
9223e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
923127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorpublic:
924127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// Get the nesting depth of the template parameter.
925127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned getDepth() const { return Depth; }
926b24e199fbd17af780ab000c5862d191e4daffc0fArgyrios Kyrtzidis  void setDepth(unsigned D) { Depth = D; }
9273e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
928127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// Get the position of the template parameter within its parameter list.
929127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned getPosition() const { return Position; }
930b24e199fbd17af780ab000c5862d191e4daffc0fArgyrios Kyrtzidis  void setPosition(unsigned P) { Position = P; }
9311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
932127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// Get the index of the template parameter within its parameter list.
933127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned getIndex() const { return Position; }
934127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor};
9353e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
936127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// TemplateTypeParmDecl - Declaration of a template type parameter,
937127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// e.g., "T" in
938127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// @code
939127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// template<typename T> class vector;
940127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// @endcode
941127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorclass TemplateTypeParmDecl : public TypeDecl {
942127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Whether this template type parameter was declaration with
943127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// the 'typename' keyword. If false, it was declared with the
944127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// 'class' keyword.
945127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  bool Typename : 1;
9463e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
947127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Whether this template type parameter inherited its
948127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// default argument.
949127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  bool InheritedDefault : 1;
9503e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
951efed5c832de630715dd42211dd3b2aab5dd97a1bDouglas Gregor  /// \brief Whether this is a parameter pack.
952efed5c832de630715dd42211dd3b2aab5dd97a1bDouglas Gregor  bool ParameterPack : 1;
953efed5c832de630715dd42211dd3b2aab5dd97a1bDouglas Gregor
954127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief The default template argument, if any.
955a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall  TypeSourceInfo *DefaultArgument;
956127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
9571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  TemplateTypeParmDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
958efed5c832de630715dd42211dd3b2aab5dd97a1bDouglas Gregor                       bool Typename, QualType Type, bool ParameterPack)
959127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    : TypeDecl(TemplateTypeParm, DC, L, Id), Typename(Typename),
960efed5c832de630715dd42211dd3b2aab5dd97a1bDouglas Gregor      InheritedDefault(false), ParameterPack(ParameterPack), DefaultArgument() {
961efed5c832de630715dd42211dd3b2aab5dd97a1bDouglas Gregor    TypeForDecl = Type.getTypePtr();
962efed5c832de630715dd42211dd3b2aab5dd97a1bDouglas Gregor  }
9633e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
964127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorpublic:
965127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static TemplateTypeParmDecl *Create(ASTContext &C, DeclContext *DC,
966127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                      SourceLocation L, unsigned D, unsigned P,
967127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                      IdentifierInfo *Id, bool Typename,
968127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                      bool ParameterPack);
969b8b03e6df1cc89e701a809c6a47c41f31b7a9e50Argyrios Kyrtzidis  static TemplateTypeParmDecl *Create(ASTContext &C, EmptyShell Empty);
970c971f8694661776ecdec2ccc33fbe0333eeaf191Douglas Gregor
971127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Whether this template type parameter was declared with
972127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// the 'typename' keyword. If not, it was declared with the 'class'
973127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// keyword.
974127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  bool wasDeclaredWithTypename() const { return Typename; }
975c971f8694661776ecdec2ccc33fbe0333eeaf191Douglas Gregor
976127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Determine whether this template parameter has a default
977127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// argument.
978833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  bool hasDefaultArgument() const { return DefaultArgument != 0; }
979199d99192fbcca9f043596c40ead4afab4999dbaDouglas Gregor
980127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the default argument, if any.
981833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  QualType getDefaultArgument() const { return DefaultArgument->getType(); }
98240808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor
983833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  /// \brief Retrieves the default argument's source information, if any.
984a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall  TypeSourceInfo *getDefaultArgumentInfo() const { return DefaultArgument; }
985833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall
986833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  /// \brief Retrieves the location of the default argument declaration.
987833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  SourceLocation getDefaultArgumentLoc() const;
98840808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor
989127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Determines whether the default argument was inherited
990127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// from a previous declaration of this template.
991127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  bool defaultArgumentWasInherited() const { return InheritedDefault; }
992f670c8cfa58b4c224eb8fb566130dc47844dd3deDouglas Gregor
993127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Set the default argument for this template parameter, and
994127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// whether that default argument was inherited from another
995127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// declaration.
996a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall  void setDefaultArgument(TypeSourceInfo *DefArg, bool Inherited) {
997127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    DefaultArgument = DefArg;
998127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    InheritedDefault = Inherited;
999f670c8cfa58b4c224eb8fb566130dc47844dd3deDouglas Gregor  }
100040808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor
1001833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  /// \brief Removes the default argument of this template parameter.
1002833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  void removeDefaultArgument() {
1003833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall    DefaultArgument = 0;
1004833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall    InheritedDefault = false;
1005833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  }
10068731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis
10078731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis  /// \brief Set whether this template type parameter was declared with
10088731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis  /// the 'typename' or 'class' keyword.
10098731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis  void setDeclaredWithTypename(bool withTypename) { Typename = withTypename; }
10108731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis
10118731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis  /// \brief Set whether this is a parameter pack.
10128731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis  void setParameterPack(bool isParamPack) { ParameterPack = isParamPack; }
1013833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall
1014ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \brief Retrieve the depth of the template parameter.
1015ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  unsigned getDepth() const;
1016ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor
1017ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \brief Retrieve the index of the template parameter.
1018ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  unsigned getIndex() const;
1019ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor
1020127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Returns whether this is a parameter pack.
1021efed5c832de630715dd42211dd3b2aab5dd97a1bDouglas Gregor  bool isParameterPack() const { return ParameterPack; }
1022fb25052736439d72a557cddd41dfb927bcb3d3e5Anders Carlsson
1023127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // Implement isa/cast/dyncast/etc.
102480cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1025127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static bool classof(const TemplateTypeParmDecl *D) { return true; }
102680cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classofKind(Kind K) { return K == TemplateTypeParm; }
10273e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor};
10283e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
1029127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// NonTypeTemplateParmDecl - Declares a non-type template parameter,
1030127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// e.g., "Size" in
1031127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// @code
1032127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// template<int Size> class array { };
1033127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// @endcode
1034127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorclass NonTypeTemplateParmDecl
1035127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  : public VarDecl, protected TemplateParmPosition {
1036d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// \brief The default template argument, if any, and whether or not
1037d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// it was inherited.
1038d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  llvm::PointerIntPair<Expr*, 1, bool> DefaultArgumentAndInherited;
1039127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
1040127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  NonTypeTemplateParmDecl(DeclContext *DC, SourceLocation L, unsigned D,
1041127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                          unsigned P, IdentifierInfo *Id, QualType T,
1042a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall                          TypeSourceInfo *TInfo)
1043d931b086984257de68868a64a235c2b4b34003fbJohn McCall    : VarDecl(NonTypeTemplateParm, DC, L, Id, T, TInfo, SC_None, SC_None),
1044d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara      TemplateParmPosition(D, P), DefaultArgumentAndInherited(0, false)
1045127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  { }
1046127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
10471c5976e5e933c0d74f7e04e8f907a93f5edbfec1Anders Carlssonpublic:
1048127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static NonTypeTemplateParmDecl *
1049127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  Create(ASTContext &C, DeclContext *DC, SourceLocation L, unsigned D,
1050a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall         unsigned P, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo);
10519ba41645892da0000fe8a7832b80208f44dafedaAnders Carlsson
1052127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  using TemplateParmPosition::getDepth;
1053b24e199fbd17af780ab000c5862d191e4daffc0fArgyrios Kyrtzidis  using TemplateParmPosition::setDepth;
1054127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  using TemplateParmPosition::getPosition;
1055b24e199fbd17af780ab000c5862d191e4daffc0fArgyrios Kyrtzidis  using TemplateParmPosition::setPosition;
1056127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  using TemplateParmPosition::getIndex;
10571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1058127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Determine whether this template parameter has a default
1059127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// argument.
1060d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  bool hasDefaultArgument() const {
1061d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara    return DefaultArgumentAndInherited.getPointer() != 0;
1062d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  }
1063fb25052736439d72a557cddd41dfb927bcb3d3e5Anders Carlsson
1064127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the default argument, if any.
1065d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  Expr *getDefaultArgument() const {
1066d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara    return DefaultArgumentAndInherited.getPointer();
1067d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  }
1068127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
1069127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the location of the default argument, if any.
1070127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  SourceLocation getDefaultArgumentLoc() const;
1071127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
1072d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// \brief Determines whether the default argument was inherited
1073d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// from a previous declaration of this template.
1074d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  bool defaultArgumentWasInherited() const {
1075d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara    return DefaultArgumentAndInherited.getInt();
1076d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  }
1077d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara
1078d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// \brief Set the default argument for this template parameter, and
1079d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// whether that default argument was inherited from another
1080d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// declaration.
1081d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  void setDefaultArgument(Expr *DefArg, bool Inherited) {
1082d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara    DefaultArgumentAndInherited.setPointer(DefArg);
1083d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara    DefaultArgumentAndInherited.setInt(Inherited);
1084d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  }
1085d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara
1086d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// \brief Removes the default argument of this template parameter.
1087d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  void removeDefaultArgument() {
1088d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara    DefaultArgumentAndInherited.setPointer(0);
1089d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara    DefaultArgumentAndInherited.setInt(false);
10903b36b66a00b7d5bab71b486a54694f0ae397bddbAnders Carlsson  }
1091127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
1092127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // Implement isa/cast/dyncast/etc.
109380cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1094127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static bool classof(const NonTypeTemplateParmDecl *D) { return true; }
109580cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classofKind(Kind K) { return K == NonTypeTemplateParm; }
10961c5976e5e933c0d74f7e04e8f907a93f5edbfec1Anders Carlsson};
10971c5976e5e933c0d74f7e04e8f907a93f5edbfec1Anders Carlsson
1098127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// TemplateTemplateParmDecl - Declares a template template parameter,
1099127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// e.g., "T" in
1100127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// @code
1101127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// template <template <typename> class T> class container { };
1102127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// @endcode
1103127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// A template template parameter is a TemplateDecl because it defines the
1104127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// name of a template and the template parameters allowable for substitution.
1105127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorclass TemplateTemplateParmDecl
1106127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  : public TemplateDecl, protected TemplateParmPosition {
11077e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
1108d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// DefaultArgument - The default template argument, if any.
1109788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor  TemplateArgumentLoc DefaultArgument;
1110d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// Whether or not the default argument was inherited.
1111d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  bool DefaultArgumentWasInherited;
11127e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
1113127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L,
1114127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                           unsigned D, unsigned P,
1115127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                           IdentifierInfo *Id, TemplateParameterList *Params)
1116127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
1117d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara      TemplateParmPosition(D, P), DefaultArgument(),
1118d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara      DefaultArgumentWasInherited(false)
1119127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    { }
11207e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
1121127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorpublic:
1122127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static TemplateTemplateParmDecl *Create(ASTContext &C, DeclContext *DC,
1123127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                          SourceLocation L, unsigned D,
1124127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                          unsigned P, IdentifierInfo *Id,
1125127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                          TemplateParameterList *Params);
11267e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
1127127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  using TemplateParmPosition::getDepth;
1128127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  using TemplateParmPosition::getPosition;
1129127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  using TemplateParmPosition::getIndex;
11301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1131127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Determine whether this template parameter has a default
1132127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// argument.
1133d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  bool hasDefaultArgument() const {
1134d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara    return !DefaultArgument.getArgument().isNull();
1135788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor  }
11367e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
1137127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the default argument, if any.
1138d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  const TemplateArgumentLoc &getDefaultArgument() const {
1139d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara    return DefaultArgument;
1140d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  }
1141d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara
1142d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// \brief Retrieve the location of the default argument, if any.
1143d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  SourceLocation getDefaultArgumentLoc() const;
1144d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara
1145d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// \brief Determines whether the default argument was inherited
1146d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// from a previous declaration of this template.
1147d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  bool defaultArgumentWasInherited() const {
1148d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara    return DefaultArgumentWasInherited;
1149788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor  }
11507e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
1151d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// \brief Set the default argument for this template parameter, and
1152d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// whether that default argument was inherited from another
1153d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// declaration.
1154d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  void setDefaultArgument(const TemplateArgumentLoc &DefArg, bool Inherited) {
1155127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    DefaultArgument = DefArg;
1156d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara    DefaultArgumentWasInherited = Inherited;
1157d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  }
1158d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara
1159d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// \brief Removes the default argument of this template parameter.
1160d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  void removeDefaultArgument() {
1161d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara    DefaultArgument = TemplateArgumentLoc();
1162d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara    DefaultArgumentWasInherited = false;
1163127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  }
11647e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
1165fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor  SourceRange getSourceRange() const {
1166fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor    SourceLocation End = getLocation();
1167fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor    if (hasDefaultArgument() && !defaultArgumentWasInherited())
1168fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor      End = getDefaultArgument().getSourceRange().getEnd();
1169fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor    return SourceRange(getTemplateParameters()->getTemplateLoc(), End);
1170fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor  }
1171fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor
1172127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // Implement isa/cast/dyncast/etc.
117380cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1174127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static bool classof(const TemplateTemplateParmDecl *D) { return true; }
117580cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classofKind(Kind K) { return K == TemplateTemplateParm; }
1176bfcc92c3476ada55ceeea49e43e6d2e083252830Argyrios Kyrtzidis
1177d527cc06d78fe5afa5f20105b51697637eb02c56Sebastian Redl  friend class ASTDeclReader;
11783397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl  friend class ASTDeclWriter;
11797e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor};
11807e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
11813e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// \brief Represents a class template specialization, which refers to
11823e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// a class template with a given set of template arguments.
11833e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor///
11843e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// Class template specializations represent both explicit
11853e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// specialization of class templates, as in the example below, and
11863e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// implicit instantiations of class templates.
11873e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor///
11883e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// \code
11893e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// template<typename T> class array;
11901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///
11911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// template<>
11923e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// class array<bool> { }; // class template specialization array<bool>
11933e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// \endcode
11941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpclass ClassTemplateSpecializationDecl
11953e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  : public CXXRecordDecl, public llvm::FoldingSetNode {
11961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
11971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// \brief Structure that stores information about a class template
119837d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// specialization that was instantiated from a class template partial
119937d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// specialization.
120037d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  struct SpecializedPartialSpecialization {
120137d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    /// \brief The class template partial specialization from which this
120237d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    /// class template specialization was instantiated.
120337d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    ClassTemplatePartialSpecializationDecl *PartialSpecialization;
12041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
120537d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    /// \brief The template argument list deduced for the class template
120637d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    /// partial specialization itself.
120737d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    TemplateArgumentList *TemplateArgs;
120837d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  };
12091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
12103e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  /// \brief The template that this specialization specializes
121137d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  llvm::PointerUnion<ClassTemplateDecl *, SpecializedPartialSpecialization *>
121237d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    SpecializedTemplate;
12133e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
1214c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  /// \brief Further info for explicit template specialization/instantiation.
1215c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  struct ExplicitSpecializationInfo {
1216c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara    /// \brief The type-as-written.
1217c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara    TypeSourceInfo *TypeAsWritten;
1218c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara    /// \brief The location of the extern keyword.
1219c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara    SourceLocation ExternLoc;
1220c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara    /// \brief The location of the template keyword.
1221c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara    SourceLocation TemplateKeywordLoc;
1222c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara
1223c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara    ExplicitSpecializationInfo()
1224c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara      : TypeAsWritten(0), ExternLoc(), TemplateKeywordLoc() {}
1225c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  };
1226c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara
1227c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  /// \brief Further info for explicit template specialization/instantiation.
12283cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall  /// Does not apply to implicit specializations.
1229c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  ExplicitSpecializationInfo *ExplicitInfo;
12303cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall
12317e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor  /// \brief The template arguments used to describe this specialization.
12327e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor  TemplateArgumentList TemplateArgs;
1233cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor
12349cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall  /// \brief The point where this template was instantiated (if any)
12359cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall  SourceLocation PointOfInstantiation;
12369cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall
1237cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  /// \brief The kind of specialization this declaration refers to.
1238cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  /// Really a value of type TemplateSpecializationKind.
1239d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor  unsigned SpecializationKind : 3;
1240cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor
1241c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregorprotected:
124213c8577201e4fc0ddac5f09d05fd1778832137d1Douglas Gregor  ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
12437e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor                                  DeclContext *DC, SourceLocation L,
12443e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor                                  ClassTemplateDecl *SpecializedTemplate,
12458e9e9ef5348bce1a8f0741a5684fac3de9701c28Douglas Gregor                                  TemplateArgumentListBuilder &Builder,
12468e9e9ef5348bce1a8f0741a5684fac3de9701c28Douglas Gregor                                  ClassTemplateSpecializationDecl *PrevDecl);
12471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
124894d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis  explicit ClassTemplateSpecializationDecl(Kind DK);
124994d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis
12503e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregorpublic:
12513e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  static ClassTemplateSpecializationDecl *
125213c8577201e4fc0ddac5f09d05fd1778832137d1Douglas Gregor  Create(ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation L,
12533e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor         ClassTemplateDecl *SpecializedTemplate,
125491fdf6f576b91f023c3bebb0d3786aab555cb3c5Anders Carlsson         TemplateArgumentListBuilder &Builder,
1255cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor         ClassTemplateSpecializationDecl *PrevDecl);
1256b8b03e6df1cc89e701a809c6a47c41f31b7a9e50Argyrios Kyrtzidis  static ClassTemplateSpecializationDecl *
1257b8b03e6df1cc89e701a809c6a47c41f31b7a9e50Argyrios Kyrtzidis  Create(ASTContext &Context, EmptyShell Empty);
125894d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis
1259136a6988960ac3aeb96f298da7a1a182db7217cdJohn McCall  virtual void getNameForDiagnostic(std::string &S,
1260136a6988960ac3aeb96f298da7a1a182db7217cdJohn McCall                                    const PrintingPolicy &Policy,
1261136a6988960ac3aeb96f298da7a1a182db7217cdJohn McCall                                    bool Qualified) const;
1262136a6988960ac3aeb96f298da7a1a182db7217cdJohn McCall
1263cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  ClassTemplateSpecializationDecl *getMostRecentDeclaration() {
1264cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis    CXXRecordDecl *Recent
1265cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis        = cast<CXXRecordDecl>(CXXRecordDecl::getMostRecentDeclaration());
1266cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis    if (!isa<ClassTemplateSpecializationDecl>(Recent)) {
1267cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis      // FIXME: Does injected class name need to be in the redeclarations chain?
1268cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis      assert(Recent->isInjectedClassName() && Recent->getPreviousDeclaration());
1269cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis      Recent = Recent->getPreviousDeclaration();
1270cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis    }
1271cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis    return cast<ClassTemplateSpecializationDecl>(Recent);
1272cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  }
1273cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis
12743e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  /// \brief Retrieve the template that this specialization specializes.
127537d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  ClassTemplateDecl *getSpecializedTemplate() const;
12763e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
12771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// \brief Retrieve the template arguments of the class template
127837d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// specialization.
12791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  const TemplateArgumentList &getTemplateArgs() const {
12807e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor    return TemplateArgs;
12813e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
12823e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
1283cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  /// \brief Determine the kind of specialization that this
1284cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  /// declaration represents.
1285cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  TemplateSpecializationKind getSpecializationKind() const {
1286cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor    return static_cast<TemplateSpecializationKind>(SpecializationKind);
1287cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  }
1288cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor
1289cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  void setSpecializationKind(TemplateSpecializationKind TSK) {
1290cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor    SpecializationKind = TSK;
1291cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  }
1292cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor
12939cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall  /// \brief Get the point of instantiation (if any), or null if none.
12949cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall  SourceLocation getPointOfInstantiation() const {
12959cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall    return PointOfInstantiation;
12969cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall  }
12979cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall
12989cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall  void setPointOfInstantiation(SourceLocation Loc) {
12999cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall    assert(Loc.isValid() && "point of instantiation must be valid!");
13009cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall    PointOfInstantiation = Loc;
13019cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall  }
13029cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall
130337d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// \brief If this class template specialization is an instantiation of
130437d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// a template (rather than an explicit specialization), return the
130537d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// class template or class template partial specialization from which it
130637d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// was instantiated.
13071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  llvm::PointerUnion<ClassTemplateDecl *,
130837d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor                     ClassTemplatePartialSpecializationDecl *>
130937d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  getInstantiatedFrom() const {
131037d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    if (getSpecializationKind() != TSK_ImplicitInstantiation &&
1311d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor        getSpecializationKind() != TSK_ExplicitInstantiationDefinition &&
1312d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor        getSpecializationKind() != TSK_ExplicitInstantiationDeclaration)
1313e0329acf5c9437e2086a2fb2bf7a95ae2ac96505Douglas Gregor      return llvm::PointerUnion<ClassTemplateDecl *,
1314e0329acf5c9437e2086a2fb2bf7a95ae2ac96505Douglas Gregor                                ClassTemplatePartialSpecializationDecl *>();
13151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
13161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    if (SpecializedPartialSpecialization *PartialSpec
131737d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor          = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
131837d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor      return PartialSpec->PartialSpecialization;
13191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
132037d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    return const_cast<ClassTemplateDecl*>(
132137d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor                             SpecializedTemplate.get<ClassTemplateDecl*>());
132237d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  }
13231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
132494d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis  /// \brief Retrieve the class template or class template partial
132594d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis  /// specialization which was specialized by this.
132694d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis  llvm::PointerUnion<ClassTemplateDecl *,
132794d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis                     ClassTemplatePartialSpecializationDecl *>
132894d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis  getSpecializedTemplateOrPartial() const {
132994d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis    if (SpecializedPartialSpecialization *PartialSpec
133094d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis          = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
133194d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis      return PartialSpec->PartialSpecialization;
133294d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis
133394d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis    return const_cast<ClassTemplateDecl*>(
133494d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis                             SpecializedTemplate.get<ClassTemplateDecl*>());
133594d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis  }
133694d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis
133737d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// \brief Retrieve the set of template arguments that should be used
133837d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// to instantiate members of the class template or class template partial
133937d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// specialization from which this class template specialization was
134037d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// instantiated.
134137d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  ///
134237d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// \returns For a class template specialization instantiated from the primary
134337d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// template, this function will return the same template arguments as
134437d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// getTemplateArgs(). For a class template specialization instantiated from
134537d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// a class template partial specialization, this function will return the
134637d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// deduced template arguments for the class template partial specialization
134737d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// itself.
134837d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  const TemplateArgumentList &getTemplateInstantiationArgs() const {
13491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    if (SpecializedPartialSpecialization *PartialSpec
135037d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor        = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
135137d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor      return *PartialSpec->TemplateArgs;
13521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
135337d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    return getTemplateArgs();
135437d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  }
13551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
135637d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// \brief Note that this class template specialization is actually an
135737d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// instantiation of the given class template partial specialization whose
135837d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// template arguments have been deduced.
135937d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  void setInstantiationOf(ClassTemplatePartialSpecializationDecl *PartialSpec,
136037d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor                          TemplateArgumentList *TemplateArgs) {
136194d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis    assert(!SpecializedTemplate.is<SpecializedPartialSpecialization*>() &&
136294d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis           "Already set to a class template partial specialization!");
13631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    SpecializedPartialSpecialization *PS
136437d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor      = new (getASTContext()) SpecializedPartialSpecialization();
136537d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    PS->PartialSpecialization = PartialSpec;
136637d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    PS->TemplateArgs = TemplateArgs;
136737d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    SpecializedTemplate = PS;
136837d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  }
13691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
137094d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis  /// \brief Note that this class template specialization is an instantiation
137194d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis  /// of the given class template.
137294d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis  void setInstantiationOf(ClassTemplateDecl *TemplDecl) {
137394d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis    assert(!SpecializedTemplate.is<SpecializedPartialSpecialization*>() &&
137494d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis           "Previously set to a class template partial specialization!");
137594d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis    SpecializedTemplate = TemplDecl;
137694d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis  }
137794d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis
1378fc705b84347e6fb4746a1a7e26949f64c2f2f358Douglas Gregor  /// \brief Sets the type of this specialization as it was written by
1379fc705b84347e6fb4746a1a7e26949f64c2f2f358Douglas Gregor  /// the user. This will be a class template specialization type.
13803cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall  void setTypeAsWritten(TypeSourceInfo *T) {
1381db1423008b6185fc570558cff77d92f94e55b386Ted Kremenek    if (!ExplicitInfo)
1382db1423008b6185fc570558cff77d92f94e55b386Ted Kremenek      ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
1383c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara    ExplicitInfo->TypeAsWritten = T;
13843cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall  }
13853cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall  /// \brief Gets the type of this specialization as it was written by
13863cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall  /// the user, if it was so written.
13873cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall  TypeSourceInfo *getTypeAsWritten() const {
1388c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara    return ExplicitInfo ? ExplicitInfo->TypeAsWritten : 0;
1389c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  }
1390c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara
1391c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  /// \brief Gets the location of the extern keyword, if present.
1392c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  SourceLocation getExternLoc() const {
1393c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara    return ExplicitInfo ? ExplicitInfo->ExternLoc : SourceLocation();
1394c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  }
1395c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  /// \brief Sets the location of the extern keyword.
1396c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  void setExternLoc(SourceLocation Loc) {
1397db1423008b6185fc570558cff77d92f94e55b386Ted Kremenek    if (!ExplicitInfo)
1398db1423008b6185fc570558cff77d92f94e55b386Ted Kremenek      ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
1399c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara    ExplicitInfo->ExternLoc = Loc;
1400c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  }
1401c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara
1402c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  /// \brief Sets the location of the template keyword.
1403c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  void setTemplateKeywordLoc(SourceLocation Loc) {
1404db1423008b6185fc570558cff77d92f94e55b386Ted Kremenek    if (!ExplicitInfo)
1405db1423008b6185fc570558cff77d92f94e55b386Ted Kremenek      ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
1406c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara    ExplicitInfo->TemplateKeywordLoc = Loc;
1407c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  }
1408c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  /// \brief Gets the location of the template keyword, if present.
1409c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  SourceLocation getTemplateKeywordLoc() const {
1410c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara    return ExplicitInfo ? ExplicitInfo->TemplateKeywordLoc : SourceLocation();
1411fc705b84347e6fb4746a1a7e26949f64c2f2f358Douglas Gregor  }
1412fc705b84347e6fb4746a1a7e26949f64c2f2f358Douglas Gregor
14131693e154bef16ca060b5e3786d8528ddc11f5637Douglas Gregor  SourceLocation getInnerLocStart() const { return getTemplateKeywordLoc(); }
14141693e154bef16ca060b5e3786d8528ddc11f5637Douglas Gregor
1415c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  void Profile(llvm::FoldingSetNodeID &ID) const {
1416828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor    Profile(ID, TemplateArgs.getFlatArgumentList(), TemplateArgs.flat_size(),
1417828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor            getASTContext());
1418c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  }
1419c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
14201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  static void
14211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  Profile(llvm::FoldingSetNodeID &ID, const TemplateArgument *TemplateArgs,
1422828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor          unsigned NumTemplateArgs, ASTContext &Context) {
14230ceffb51b28b09db67404058c642dcb1f877f6e8Anders Carlsson    ID.AddInteger(NumTemplateArgs);
14243e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor    for (unsigned Arg = 0; Arg != NumTemplateArgs; ++Arg)
1425828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor      TemplateArgs[Arg].Profile(ID, Context);
14263e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
14273e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
142880cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
142980cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classofKind(Kind K) {
14309a55591af3e5506b95a9718e15380129fbfc5ebcSean Hunt    return K >= firstClassTemplateSpecialization &&
14319a55591af3e5506b95a9718e15380129fbfc5ebcSean Hunt           K <= lastClassTemplateSpecialization;
14323e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
14333e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
14343e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  static bool classof(const ClassTemplateSpecializationDecl *) {
14353e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor    return true;
14363e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
1437c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
1438c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  static bool classof(const ClassTemplatePartialSpecializationDecl *) {
1439c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor    return true;
1440c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  }
1441586c7156d51039290f100c80d2d8bd263c99addcArgyrios Kyrtzidis
1442586c7156d51039290f100c80d2d8bd263c99addcArgyrios Kyrtzidis  friend class ASTDeclReader;
1443586c7156d51039290f100c80d2d8bd263c99addcArgyrios Kyrtzidis  friend class ASTDeclWriter;
1444c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor};
1445c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
14461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpclass ClassTemplatePartialSpecializationDecl
14471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  : public ClassTemplateSpecializationDecl {
14481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// \brief The list of template parameters
1449c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  TemplateParameterList* TemplateParams;
1450c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
1451833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  /// \brief The source info for the template arguments as written.
14523cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall  /// FIXME: redundant with TypeAsWritten?
1453833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  TemplateArgumentLoc *ArgsAsWritten;
1454833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  unsigned NumArgsAsWritten;
1455833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall
1456dc60c1eb4acbde6edcec9760de92f9098593d915Douglas Gregor  /// \brief Sequence number indicating when this class template partial
1457dc60c1eb4acbde6edcec9760de92f9098593d915Douglas Gregor  /// specialization was added to the set of partial specializations for
1458dc60c1eb4acbde6edcec9760de92f9098593d915Douglas Gregor  /// its owning class template.
1459dc60c1eb4acbde6edcec9760de92f9098593d915Douglas Gregor  unsigned SequenceNumber;
1460dc60c1eb4acbde6edcec9760de92f9098593d915Douglas Gregor
1461ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \brief The class template partial specialization from which this
1462ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// class template partial specialization was instantiated.
1463ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ///
1464ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// The boolean value will be true to indicate that this class template
1465ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// partial specialization was specialized at this level.
1466ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  llvm::PointerIntPair<ClassTemplatePartialSpecializationDecl *, 1, bool>
1467ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor      InstantiatedFromMember;
1468ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor
146913c8577201e4fc0ddac5f09d05fd1778832137d1Douglas Gregor  ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK,
1470c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor                                         DeclContext *DC, SourceLocation L,
1471c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor                                         TemplateParameterList *Params,
1472c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor                                         ClassTemplateDecl *SpecializedTemplate,
14738e9e9ef5348bce1a8f0741a5684fac3de9701c28Douglas Gregor                                         TemplateArgumentListBuilder &Builder,
1474833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall                                         TemplateArgumentLoc *ArgInfos,
1475833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall                                         unsigned NumArgInfos,
1476dc60c1eb4acbde6edcec9760de92f9098593d915Douglas Gregor                               ClassTemplatePartialSpecializationDecl *PrevDecl,
1477dc60c1eb4acbde6edcec9760de92f9098593d915Douglas Gregor                                         unsigned SequenceNumber)
14781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    : ClassTemplateSpecializationDecl(Context,
14798e9e9ef5348bce1a8f0741a5684fac3de9701c28Douglas Gregor                                      ClassTemplatePartialSpecialization,
148013c8577201e4fc0ddac5f09d05fd1778832137d1Douglas Gregor                                      TK, DC, L, SpecializedTemplate, Builder,
14818e9e9ef5348bce1a8f0741a5684fac3de9701c28Douglas Gregor                                      PrevDecl),
1482833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall      TemplateParams(Params), ArgsAsWritten(ArgInfos),
1483dc60c1eb4acbde6edcec9760de92f9098593d915Douglas Gregor      NumArgsAsWritten(NumArgInfos), SequenceNumber(SequenceNumber),
1484dc60c1eb4acbde6edcec9760de92f9098593d915Douglas Gregor      InstantiatedFromMember(0, false) { }
148594d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis
148694d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis  ClassTemplatePartialSpecializationDecl()
148794d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis    : ClassTemplateSpecializationDecl(ClassTemplatePartialSpecialization),
148894d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis      TemplateParams(0), ArgsAsWritten(0),
148994d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis      NumArgsAsWritten(0), SequenceNumber(0),
149094d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis      InstantiatedFromMember(0, false) { }
1491c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
1492c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregorpublic:
1493c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  static ClassTemplatePartialSpecializationDecl *
149413c8577201e4fc0ddac5f09d05fd1778832137d1Douglas Gregor  Create(ASTContext &Context, TagKind TK,DeclContext *DC, SourceLocation L,
1495c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor         TemplateParameterList *Params,
1496c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor         ClassTemplateDecl *SpecializedTemplate,
149791fdf6f576b91f023c3bebb0d3786aab555cb3c5Anders Carlsson         TemplateArgumentListBuilder &Builder,
1498d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall         const TemplateArgumentListInfo &ArgInfos,
14993cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall         QualType CanonInjectedType,
1500dc60c1eb4acbde6edcec9760de92f9098593d915Douglas Gregor         ClassTemplatePartialSpecializationDecl *PrevDecl,
1501dc60c1eb4acbde6edcec9760de92f9098593d915Douglas Gregor         unsigned SequenceNumber);
1502c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
150394d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis  static ClassTemplatePartialSpecializationDecl *
1504b8b03e6df1cc89e701a809c6a47c41f31b7a9e50Argyrios Kyrtzidis  Create(ASTContext &Context, EmptyShell Empty);
150594d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis
1506cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  ClassTemplatePartialSpecializationDecl *getMostRecentDeclaration() {
1507cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis    return cast<ClassTemplatePartialSpecializationDecl>(
1508cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis                   ClassTemplateSpecializationDecl::getMostRecentDeclaration());
1509cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  }
1510cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis
1511c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  /// Get the list of template parameters
1512c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  TemplateParameterList *getTemplateParameters() const {
1513c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor    return TemplateParams;
1514c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  }
1515c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
1516833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  /// Get the template arguments as written.
1517833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  TemplateArgumentLoc *getTemplateArgsAsWritten() const {
1518833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall    return ArgsAsWritten;
1519833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  }
1520833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall
1521833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  /// Get the number of template arguments as written.
1522833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  unsigned getNumTemplateArgsAsWritten() const {
1523833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall    return NumArgsAsWritten;
1524833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  }
1525833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall
1526dc60c1eb4acbde6edcec9760de92f9098593d915Douglas Gregor  /// \brief Get the sequence number for this class template partial
1527dc60c1eb4acbde6edcec9760de92f9098593d915Douglas Gregor  /// specialization.
1528dc60c1eb4acbde6edcec9760de92f9098593d915Douglas Gregor  unsigned getSequenceNumber() const { return SequenceNumber; }
15298fed4b4bc93cce4d15bdb79f9e30cc25a93c8143Argyrios Kyrtzidis
1530ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \brief Retrieve the member class template partial specialization from
1531ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// which this particular class template partial specialization was
1532ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// instantiated.
1533ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ///
1534ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \code
1535ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// template<typename T>
1536ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// struct Outer {
1537ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ///   template<typename U> struct Inner;
1538ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ///   template<typename U> struct Inner<U*> { }; // #1
1539ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// };
1540ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ///
1541ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// Outer<float>::Inner<int*> ii;
1542ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \endcode
1543ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ///
1544ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// In this example, the instantiation of \c Outer<float>::Inner<int*> will
1545ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// end up instantiating the partial specialization
1546ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \c Outer<float>::Inner<U*>, which itself was instantiated from the class
1547ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// template partial specialization \c Outer<T>::Inner<U*>. Given
1548ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \c Outer<float>::Inner<U*>, this function would return
1549ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \c Outer<T>::Inner<U*>.
1550ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ClassTemplatePartialSpecializationDecl *getInstantiatedFromMember() {
1551ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor    ClassTemplatePartialSpecializationDecl *First
1552ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor      = cast<ClassTemplatePartialSpecializationDecl>(getFirstDeclaration());
1553ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor    return First->InstantiatedFromMember.getPointer();
1554ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  }
1555ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor
1556ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  void setInstantiatedFromMember(
1557ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor                          ClassTemplatePartialSpecializationDecl *PartialSpec) {
1558ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor    ClassTemplatePartialSpecializationDecl *First
1559ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor      = cast<ClassTemplatePartialSpecializationDecl>(getFirstDeclaration());
1560ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor    First->InstantiatedFromMember.setPointer(PartialSpec);
1561ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  }
1562ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor
1563ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \brief Determines whether this class template partial specialization
1564ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// template was a specialization of a member partial specialization.
1565ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ///
1566ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// In the following example, the member template partial specialization
1567ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \c X<int>::Inner<T*> is a member specialization.
1568ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ///
1569ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \code
1570ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// template<typename T>
1571ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// struct X {
1572ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ///   template<typename U> struct Inner;
1573ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ///   template<typename U> struct Inner<U*>;
1574ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// };
1575ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ///
1576ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// template<> template<typename T>
1577ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// struct X<int>::Inner<T*> { /* ... */ };
1578ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \endcode
1579ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  bool isMemberSpecialization() {
1580ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor    ClassTemplatePartialSpecializationDecl *First
1581ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor      = cast<ClassTemplatePartialSpecializationDecl>(getFirstDeclaration());
1582ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor    return First->InstantiatedFromMember.getInt();
1583ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  }
1584ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor
1585ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \brief Note that this member template is a specialization.
1586ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  void setMemberSpecialization() {
1587ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor    ClassTemplatePartialSpecializationDecl *First
1588ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor      = cast<ClassTemplatePartialSpecializationDecl>(getFirstDeclaration());
1589ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor    assert(First->InstantiatedFromMember.getPointer() &&
1590ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor           "Only member templates can be member template specializations");
1591ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor    return First->InstantiatedFromMember.setInt(true);
1592ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  }
159331f17ecbef57b5679c017c375db330546b7b5145John McCall
159431f17ecbef57b5679c017c375db330546b7b5145John McCall  /// Retrieves the injected specialization type for this partial
159531f17ecbef57b5679c017c375db330546b7b5145John McCall  /// specialization.  This is not the same as the type-decl-type for
159631f17ecbef57b5679c017c375db330546b7b5145John McCall  /// this partial specialization, which is an InjectedClassNameType.
159731f17ecbef57b5679c017c375db330546b7b5145John McCall  QualType getInjectedSpecializationType() const {
159831f17ecbef57b5679c017c375db330546b7b5145John McCall    assert(getTypeForDecl() && "partial specialization has no type set!");
159931f17ecbef57b5679c017c375db330546b7b5145John McCall    return cast<InjectedClassNameType>(getTypeForDecl())
160031f17ecbef57b5679c017c375db330546b7b5145John McCall             ->getInjectedSpecializationType();
160131f17ecbef57b5679c017c375db330546b7b5145John McCall  }
1602ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor
1603c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  // FIXME: Add Profile support!
1604c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
160580cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
160680cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classofKind(Kind K) {
160780cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall    return K == ClassTemplatePartialSpecialization;
1608c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  }
1609c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
1610c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  static bool classof(const ClassTemplatePartialSpecializationDecl *) {
1611c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor    return true;
1612c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  }
16138fed4b4bc93cce4d15bdb79f9e30cc25a93c8143Argyrios Kyrtzidis
16148fed4b4bc93cce4d15bdb79f9e30cc25a93c8143Argyrios Kyrtzidis  friend class ASTDeclReader;
16158fed4b4bc93cce4d15bdb79f9e30cc25a93c8143Argyrios Kyrtzidis  friend class ASTDeclWriter;
16163e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor};
16173e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
16183e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// Declaration of a class template.
16199eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourneclass ClassTemplateDecl : public RedeclarableTemplateDecl,
16209eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne                          public RedeclarableTemplate<ClassTemplateDecl> {
16210054531488928a424666ac11fcdc6bcc5112de52Douglas Gregor  static void DeallocateCommon(void *Ptr);
16220054531488928a424666ac11fcdc6bcc5112de52Douglas Gregor
16233e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregorprotected:
16249eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  typedef RedeclarableTemplate<ClassTemplateDecl> redeclarable_base;
16259eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
16265953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  /// \brief Data that is common to all of the declarations of a given
16275953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  /// class template.
16289eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  struct Common : CommonBase {
16295953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor    /// \brief The class template specializations for this class
16305953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor    /// template, including explicit specializations and instantiations.
16315953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor    llvm::FoldingSet<ClassTemplateSpecializationDecl> Specializations;
16327da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor
1633c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor    /// \brief The class template partial specializations for this class
1634c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor    /// template.
16351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    llvm::FoldingSet<ClassTemplatePartialSpecializationDecl>
1636c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor      PartialSpecializations;
1637c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
16387da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor    /// \brief The injected-class-name type for this class template.
16397da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor    QualType InjectedClassNameType;
16405953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  };
16415953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor
1642cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// \brief Retrieve the set of specializations of this class template.
1643cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  llvm::FoldingSet<ClassTemplateSpecializationDecl> &getSpecializations() {
1644cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis    return getCommonPtr()->Specializations;
1645cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  }
1646cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis
1647cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// \brief Retrieve the set of partial specializations of this class
1648cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// template.
1649cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  llvm::FoldingSet<ClassTemplatePartialSpecializationDecl> &
1650cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  getPartialSpecializations() {
1651cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis    return getCommonPtr()->PartialSpecializations;
1652cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  }
1653cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis
16543e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  ClassTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
16558731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis                    TemplateParameterList *Params, NamedDecl *Decl)
16569eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    : RedeclarableTemplateDecl(ClassTemplate, DC, L, Name, Params, Decl) { }
16579eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
16586b5415196327fa8ef00f028ba175fafef1738ae1Argyrios Kyrtzidis  CommonBase *newCommon(ASTContext &C);
16599eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
16609eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  Common *getCommonPtr() {
16619eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
16629eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
16633e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
16643e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregorpublic:
16653e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  /// Get the underlying class declarations of the template.
16663e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  CXXRecordDecl *getTemplatedDecl() const {
16673e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor    return static_cast<CXXRecordDecl *>(TemplatedDecl);
16683e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
16693e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
167013fda8afe2ddd06c12bfb93a054e6b0d6d0d99f1John McCall  /// Returns whether this template declaration defines the primary
167113fda8afe2ddd06c12bfb93a054e6b0d6d0d99f1John McCall  /// class pattern.
167213fda8afe2ddd06c12bfb93a054e6b0d6d0d99f1John McCall  bool isThisDeclarationADefinition() const {
167313fda8afe2ddd06c12bfb93a054e6b0d6d0d99f1John McCall    return getTemplatedDecl()->isThisDeclarationADefinition();
167413fda8afe2ddd06c12bfb93a054e6b0d6d0d99f1John McCall  }
167513fda8afe2ddd06c12bfb93a054e6b0d6d0d99f1John McCall
16765953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  /// Create a class template node.
16773e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  static ClassTemplateDecl *Create(ASTContext &C, DeclContext *DC,
16783e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor                                   SourceLocation L,
16793e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor                                   DeclarationName Name,
16803e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor                                   TemplateParameterList *Params,
16815953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor                                   NamedDecl *Decl,
16825953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor                                   ClassTemplateDecl *PrevDecl);
16833e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
1684cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// \brief Return the specialization with the provided arguments if it exists,
1685cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// otherwise return the insertion point.
1686cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  ClassTemplateSpecializationDecl *
1687cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  findSpecialization(const TemplateArgument *Args, unsigned NumArgs,
1688cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis                     void *&InsertPos);
1689cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis
1690cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// \brief Insert the specified specialization knowing that it is not already
1691cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// in. InsertPos must be obtained from findSpecialization.
1692cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  void AddSpecialization(ClassTemplateSpecializationDecl *D, void *InsertPos) {
1693cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis    getSpecializations().InsertNode(D, InsertPos);
16943e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
16953e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
16969eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  ClassTemplateDecl *getCanonicalDecl() {
16979eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    return redeclarable_base::getCanonicalDecl();
16989eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
16999eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  const ClassTemplateDecl *getCanonicalDecl() const {
17009eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    return redeclarable_base::getCanonicalDecl();
17019eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
17029eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
17039eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// \brief Retrieve the previous declaration of this class template, or
17049eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// NULL if no such declaration exists.
17059eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  ClassTemplateDecl *getPreviousDeclaration() {
17069eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    return redeclarable_base::getPreviousDeclaration();
17079eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
17089eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
17099eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// \brief Retrieve the previous declaration of this class template, or
17109eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// NULL if no such declaration exists.
17119eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  const ClassTemplateDecl *getPreviousDeclaration() const {
17129eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    return redeclarable_base::getPreviousDeclaration();
17139eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
17149eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
17159eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  ClassTemplateDecl *getInstantiatedFromMemberTemplate() {
17169eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    return redeclarable_base::getInstantiatedFromMemberTemplate();
17179eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
17189eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
1719cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// \brief Return the partial specialization with the provided arguments if it
1720cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// exists, otherwise return the insertion point.
1721cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  ClassTemplatePartialSpecializationDecl *
1722cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  findPartialSpecialization(const TemplateArgument *Args, unsigned NumArgs,
1723cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis                            void *&InsertPos);
1724cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis
1725cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// \brief Insert the specified partial specialization knowing that it is not
1726cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// already in. InsertPos must be obtained from findPartialSpecialization.
1727cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  void AddPartialSpecialization(ClassTemplatePartialSpecializationDecl *D,
1728cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis                                void *InsertPos) {
1729cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis    getPartialSpecializations().InsertNode(D, InsertPos);
1730cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  }
1731cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis
1732cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// \brief Return the next partial specialization sequence number.
1733cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  unsigned getNextPartialSpecSequenceNumber() {
1734cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis    return getPartialSpecializations().size();
1735c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  }
1736c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
1737dc60c1eb4acbde6edcec9760de92f9098593d915Douglas Gregor  /// \brief Retrieve the partial specializations as an ordered list.
1738dc60c1eb4acbde6edcec9760de92f9098593d915Douglas Gregor  void getPartialSpecializations(
1739dc60c1eb4acbde6edcec9760de92f9098593d915Douglas Gregor          llvm::SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS);
1740dc60c1eb4acbde6edcec9760de92f9098593d915Douglas Gregor
1741b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  /// \brief Find a class template partial specialization with the given
1742b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  /// type T.
1743b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  ///
1744cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// \param T a dependent type that names a specialization of this class
1745b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  /// template.
1746b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  ///
1747b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  /// \returns the class template partial specialization that exactly matches
1748b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  /// the type \p T, or NULL if no such partial specialization exists.
1749b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  ClassTemplatePartialSpecializationDecl *findPartialSpecialization(QualType T);
1750cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis
1751cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// \brief Find a class template partial specialization which was instantiated
1752cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// from the given member partial specialization.
1753cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  ///
1754cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// \param D a member class template partial specialization.
1755cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  ///
1756cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// \returns the class template partial specialization which was instantiated
1757cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// from the given member partial specialization, or NULL if no such partial
1758cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// specialization exists.
1759cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  ClassTemplatePartialSpecializationDecl *
1760cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  findPartialSpecInstantiatedFromMember(
1761cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis                                     ClassTemplatePartialSpecializationDecl *D);
17621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
17633cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall  /// \brief Retrieve the template specialization type of the
17643cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall  /// injected-class-name for this class template.
17657da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  ///
17667da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// The injected-class-name for a class template \c X is \c
17677da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// X<template-args>, where \c template-args is formed from the
17687da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// template arguments that correspond to the template parameters of
17697da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// \c X. For example:
17707da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  ///
17717da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// \code
17727da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// template<typename T, int N>
17737da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// struct array {
17747da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  ///   typedef array this_type; // "array" is equivalent to "array<T, N>"
17757da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// };
17767da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// \endcode
177724bae92f08ae098cc50a602d8cf1273b423e14daDouglas Gregor  QualType getInjectedClassNameSpecialization();
17787da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor
17799f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  typedef SpecIterator<ClassTemplateSpecializationDecl> spec_iterator;
17809f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne
17819f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  spec_iterator spec_begin() {
17829f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    return makeSpecIterator(getSpecializations(), false);
17839f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  }
17849f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne
17859f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  spec_iterator spec_end() {
17869f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    return makeSpecIterator(getSpecializations(), true);
17879f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  }
17889f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne
17899f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  typedef SpecIterator<ClassTemplatePartialSpecializationDecl>
17909f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne          partial_spec_iterator;
17919f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne
17929f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  partial_spec_iterator partial_spec_begin() {
17939f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    return makeSpecIterator(getPartialSpecializations(), false);
17949f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  }
17959f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne
17969f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  partial_spec_iterator partial_spec_end() {
17979f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    return makeSpecIterator(getPartialSpecializations(), true);
17989f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  }
17999f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne
18003e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  // Implement isa/cast/dyncast support
180180cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
180280cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classof(const ClassTemplateDecl *D) { return true; }
180380cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classofKind(Kind K) { return K == ClassTemplate; }
18045953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor
1805d527cc06d78fe5afa5f20105b51697637eb02c56Sebastian Redl  friend class ASTDeclReader;
18063397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl  friend class ASTDeclWriter;
18073e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor};
18083e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
1809dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall/// Declaration of a friend template.  For example:
1810dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall///
1811dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall/// template <typename T> class A {
1812dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall///   friend class MyVector<T>; // not a friend template
1813c6a518a7271bbd6d0f606ba5c1b1b9c668bbdcb0Craig Silverstein///   template <typename U> friend class B; // not a friend template
1814dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall///   template <typename U> friend class Foo<T>::Nested; // friend template
1815c6a518a7271bbd6d0f606ba5c1b1b9c668bbdcb0Craig Silverstein/// };
1816c6a518a7271bbd6d0f606ba5c1b1b9c668bbdcb0Craig Silverstein/// NOTE: This class is not currently in use.  All of the above
1817c6a518a7271bbd6d0f606ba5c1b1b9c668bbdcb0Craig Silverstein/// will yield a FriendDecl, not a FriendTemplateDecl.
1818dd4a3b0065b9a7e7b00073df415a798886c090f3John McCallclass FriendTemplateDecl : public Decl {
1819dd4a3b0065b9a7e7b00073df415a798886c090f3John McCallpublic:
182032f2fb53d9d7c28c94d8569fd0fcf06cccee0c3dJohn McCall  typedef llvm::PointerUnion<NamedDecl*,TypeSourceInfo*> FriendUnion;
1821dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
1822dd4a3b0065b9a7e7b00073df415a798886c090f3John McCallprivate:
1823dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  // The number of template parameters;  always non-zero.
1824dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  unsigned NumParams;
1825dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
1826dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  // The parameter list.
1827dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  TemplateParameterList **Params;
1828dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
1829dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  // The declaration that's a friend of this class.
1830dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  FriendUnion Friend;
1831dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
1832dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  // Location of the 'friend' specifier.
1833dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  SourceLocation FriendLoc;
1834dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
1835dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
1836dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  FriendTemplateDecl(DeclContext *DC, SourceLocation Loc,
1837dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall                     unsigned NParams,
1838dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall                     TemplateParameterList **Params,
1839dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall                     FriendUnion Friend,
1840dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall                     SourceLocation FriendLoc)
1841dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall    : Decl(Decl::FriendTemplate, DC, Loc),
1842dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall      NumParams(NParams),
1843dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall      Params(Params),
1844dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall      Friend(Friend),
1845dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall      FriendLoc(FriendLoc)
1846dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  {}
1847dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
1848554e6aa2da082575514607c3639c246c04b3232aArgyrios Kyrtzidis  FriendTemplateDecl(EmptyShell Empty)
1849554e6aa2da082575514607c3639c246c04b3232aArgyrios Kyrtzidis    : Decl(Decl::FriendTemplate, Empty),
1850554e6aa2da082575514607c3639c246c04b3232aArgyrios Kyrtzidis      NumParams(0),
1851554e6aa2da082575514607c3639c246c04b3232aArgyrios Kyrtzidis      Params(0)
1852554e6aa2da082575514607c3639c246c04b3232aArgyrios Kyrtzidis  {}
1853554e6aa2da082575514607c3639c246c04b3232aArgyrios Kyrtzidis
1854dd4a3b0065b9a7e7b00073df415a798886c090f3John McCallpublic:
1855dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  static FriendTemplateDecl *Create(ASTContext &Context,
1856dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall                                    DeclContext *DC, SourceLocation Loc,
1857dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall                                    unsigned NParams,
1858dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall                                    TemplateParameterList **Params,
1859dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall                                    FriendUnion Friend,
1860dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall                                    SourceLocation FriendLoc);
1861dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
1862554e6aa2da082575514607c3639c246c04b3232aArgyrios Kyrtzidis  static FriendTemplateDecl *Create(ASTContext &Context, EmptyShell Empty);
1863554e6aa2da082575514607c3639c246c04b3232aArgyrios Kyrtzidis
1864dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  /// If this friend declaration names a templated type (or
1865dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  /// a dependent member type of a templated type), return that
1866dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  /// type;  otherwise return null.
186732f2fb53d9d7c28c94d8569fd0fcf06cccee0c3dJohn McCall  TypeSourceInfo *getFriendType() const {
186832f2fb53d9d7c28c94d8569fd0fcf06cccee0c3dJohn McCall    return Friend.dyn_cast<TypeSourceInfo*>();
1869dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  }
1870dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
1871dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  /// If this friend declaration names a templated function (or
1872dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  /// a member function of a templated type), return that type;
1873dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  /// otherwise return null.
1874dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  NamedDecl *getFriendDecl() const {
1875dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall    return Friend.dyn_cast<NamedDecl*>();
1876dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  }
1877dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
1878dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  /// Retrieves the location of the 'friend' keyword.
1879dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  SourceLocation getFriendLoc() const {
1880dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall    return FriendLoc;
1881dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  }
1882dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
1883dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  TemplateParameterList *getTemplateParameterList(unsigned i) const {
1884dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall    assert(i <= NumParams);
1885dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall    return Params[i];
1886dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  }
1887dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
1888dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  unsigned getNumTemplateParameters() const {
1889dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall    return NumParams;
1890dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  }
1891dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
1892dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  // Implement isa/cast/dyncast/etc.
189380cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
189480cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classofKind(Kind K) { return K == Decl::FriendTemplate; }
1895dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  static bool classof(const FriendTemplateDecl *D) { return true; }
1896554e6aa2da082575514607c3639c246c04b3232aArgyrios Kyrtzidis
1897d527cc06d78fe5afa5f20105b51697637eb02c56Sebastian Redl  friend class ASTDeclReader;
1898dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall};
1899dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
1900e53060fa78ad7e98352049f72787bdb7543e2a48Douglas Gregor/// Implementation of inline functions that require the template declarations
19011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpinline AnyFunctionDecl::AnyFunctionDecl(FunctionTemplateDecl *FTD)
1902e53060fa78ad7e98352049f72787bdb7543e2a48Douglas Gregor  : Function(FTD) { }
1903e53060fa78ad7e98352049f72787bdb7543e2a48Douglas Gregor
1904aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor} /* end of namespace clang */
1905aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
1906aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor#endif
1907